xref: /rk3399_rockchip-uboot/drivers/input/key-uclass.c (revision eb104afcdaefa3ee1320f8c5dae924e7aba1c6fe)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <adc.h>
9 #include <dm.h>
10 #include <irq-generic.h>
11 #include <key.h>
12 #include <dm/lists.h>
13 #include <dm/uclass-internal.h>
14 
15 #define KEY_WARN(fmt, args...)	printf("Key Warn: "fmt, ##args)
16 #define KEY_ERR(fmt, args...)	printf("Key Error: "fmt, ##args)
17 #define KEY_DBG(fmt, args...)	 debug("Key Debug: "fmt, ##args)
18 
19 static inline uint64_t arch_counter_get_cntpct(void)
20 {
21 	uint64_t cval = 0;
22 
23 	isb();
24 #ifdef CONFIG_ARM64
25 	asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
26 #else
27 	asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
28 #endif
29 	return cval;
30 }
31 
32 uint64_t key_timer(uint64_t base)
33 {
34 	uint64_t cntpct;
35 
36 	cntpct = arch_counter_get_cntpct() / 24000UL;
37 	return (cntpct > base) ? (cntpct - base) : 0;
38 }
39 
40 #ifdef CONFIG_ADC
41 static int key_adc_event(struct dm_key_uclass_platdata *uc_key, int adcval)
42 {
43 	return (adcval <= uc_key->max && adcval >= uc_key->min) ?
44 		KEY_PRESS_DOWN : KEY_PRESS_NONE;
45 }
46 #endif
47 
48 static int key_gpio_event(struct dm_key_uclass_platdata *uc_key)
49 {
50 	if (!dm_gpio_is_valid(&uc_key->gpio)) {
51 		KEY_ERR("'%s' Invalid gpio\n", uc_key->name);
52 		return KEY_PRESS_NONE;
53 	}
54 
55 	return dm_gpio_get_value(&uc_key->gpio) ?
56 	       KEY_PRESS_DOWN : KEY_PRESS_NONE;
57 }
58 
59 static int key_gpio_interrupt_event(struct dm_key_uclass_platdata *uc_key)
60 {
61 	int event;
62 
63 	debug("%s: %s: up=%llu, down=%llu, delta=%llu\n",
64 	      __func__, uc_key->name, uc_key->rise_ms, uc_key->fall_ms,
65 	      uc_key->rise_ms - uc_key->fall_ms);
66 
67 	/* Possible this is machine power-on long pressed, so ignore this */
68 	if (uc_key->fall_ms == 0 && uc_key->rise_ms != 0) {
69 		event = KEY_PRESS_NONE;
70 		goto out;
71 	}
72 
73 	if ((uc_key->rise_ms > uc_key->fall_ms) &&
74 	    (uc_key->rise_ms - uc_key->fall_ms) >= KEY_LONG_DOWN_MS) {
75 		uc_key->rise_ms = 0;
76 		uc_key->fall_ms = 0;
77 		event = KEY_PRESS_LONG_DOWN;
78 		KEY_DBG("%s key long pressed..\n", uc_key->name);
79 	} else if (uc_key->fall_ms &&
80 		   key_timer(uc_key->fall_ms) >= KEY_LONG_DOWN_MS) {
81 		uc_key->rise_ms = 0;
82 		uc_key->fall_ms = 0;
83 		event = KEY_PRESS_LONG_DOWN;
84 		KEY_DBG("%s key long pressed(hold)..\n", uc_key->name);
85 	} else if ((uc_key->rise_ms > uc_key->fall_ms) &&
86 		   (uc_key->rise_ms - uc_key->fall_ms) < KEY_LONG_DOWN_MS) {
87 		uc_key->rise_ms = 0;
88 		uc_key->fall_ms = 0;
89 		event = KEY_PRESS_DOWN;
90 		KEY_DBG("%s key short pressed..\n", uc_key->name);
91 	/* Possible in charge animation, we enable irq after fuel gauge updated */
92 	} else if (uc_key->rise_ms && uc_key->fall_ms &&
93 		   (uc_key->rise_ms == uc_key->fall_ms)) {
94 		uc_key->rise_ms = 0;
95 		uc_key->fall_ms = 0;
96 		event = KEY_PRESS_DOWN;
97 		KEY_DBG("%s key short pressed..\n", uc_key->name);
98 	} else {
99 		event = KEY_PRESS_NONE;
100 	}
101 
102 out:
103 	return event;
104 }
105 
106 int key_is_pressed(int event)
107 {
108 	return (event == KEY_PRESS_DOWN || event == KEY_PRESS_LONG_DOWN);
109 }
110 
111 static int key_core_read(struct dm_key_uclass_platdata *uc_key)
112 {
113 	if (uc_key->type == ADC_KEY) {
114 #ifdef CONFIG_ADC
115 		unsigned int adcval;
116 
117 		if (adc_channel_single_shot("saradc",
118 					    uc_key->channel, &adcval)) {
119 			KEY_ERR("%s failed to read saradc\n", uc_key->name);
120 			return KEY_NOT_EXIST;
121 		}
122 
123 		return key_adc_event(uc_key, adcval);
124 #else
125 		return KEY_NOT_EXIST;
126 #endif
127 	}
128 
129 	return (uc_key->code == KEY_POWER) ?
130 		key_gpio_interrupt_event(uc_key) :
131 		key_gpio_event(uc_key);
132 }
133 
134 int key_read(int code)
135 {
136 	struct dm_key_uclass_platdata *uc_key;
137 	struct udevice *dev;
138 	struct uclass *uc;
139 	bool allow_pre_reloc = false;
140 	int ret, event = KEY_NOT_EXIST;
141 
142 	ret = uclass_get(UCLASS_KEY, &uc);
143 	if (ret)
144 		return ret;
145 
146 try_again:
147 	for (uclass_first_device(UCLASS_KEY, &dev);
148 	     dev;
149 	     uclass_next_device(&dev)) {
150 		uc_key = dev_get_uclass_platdata(dev);
151 
152 		if (!allow_pre_reloc && uc_key->pre_reloc)
153 			continue;
154 
155 		if (uc_key->code != code)
156 			continue;
157 
158 		event = key_core_read(uc_key);
159 		if (key_is_pressed(event))
160 			return event;
161 	}
162 
163 	/* If not find valid key node from kernel, try from u-boot */
164 	if (event == KEY_NOT_EXIST && !allow_pre_reloc) {
165 		allow_pre_reloc = true;
166 		goto try_again;
167 	}
168 
169 	return event;
170 }
171 
172 int key_exist(int code)
173 {
174 	struct dm_key_uclass_platdata *uc_key;
175 	struct udevice *dev;
176 
177 	for (uclass_find_first_device(UCLASS_KEY, &dev);
178 	     dev;
179 	     uclass_find_next_device(&dev)) {
180 		uc_key = dev_get_uclass_platdata(dev);
181 
182 		if (uc_key->code == code)
183 			return 1;
184 	}
185 
186 	return 0;
187 }
188 
189 #if CONFIG_IS_ENABLED(IRQ)
190 #if defined(CONFIG_PWRKEY_DNL_TRIGGER_NUM) && \
191 		(CONFIG_PWRKEY_DNL_TRIGGER_NUM > 0)
192 static void power_key_download(struct dm_key_uclass_platdata *uc_key)
193 {
194 	int trig_cnt = CONFIG_PWRKEY_DNL_TRIGGER_NUM;
195 	static u64 old_rise_ms;
196 
197 	if (uc_key->code == KEY_POWER && old_rise_ms != uc_key->rise_ms) {
198 		old_rise_ms = uc_key->rise_ms;
199 		uc_key->trig_cnt++;
200 		if (uc_key->trig_cnt >= trig_cnt) {
201 			printf("\nEnter download mode by pwrkey\n");
202 			irq_handler_disable(uc_key->irq);
203 			run_command("download", 0);
204 		}
205 	}
206 }
207 
208 int pwrkey_download_init(void)
209 {
210 	return (KEY_NOT_EXIST == key_read(KEY_POWER));
211 }
212 #endif
213 
214 static void gpio_irq_handler(int irq, void *data)
215 {
216 	struct udevice *dev = data;
217 	struct dm_key_uclass_platdata *uc_key = dev_get_uclass_platdata(dev);
218 
219 	if (uc_key->irq != irq)
220 		return;
221 
222 	if (uc_key->irq_thread) {
223 		uc_key->irq_thread(irq, data);
224 	} else {
225 		if (irq_get_gpio_level(irq)) {
226 			uc_key->rise_ms = key_timer(0);
227 			KEY_DBG("%s: key dn: %llu ms\n",
228 				uc_key->name, uc_key->fall_ms);
229 		} else {
230 			uc_key->fall_ms = key_timer(0);
231 			KEY_DBG("%s: key up: %llu ms\n",
232 				uc_key->name, uc_key->rise_ms);
233 		}
234 
235 		/* Must delay */
236 		mdelay(10);
237 		irq_revert_irq_type(irq);
238 	}
239 
240 	/* Hook event: enter download mode by pwrkey */
241 #if defined(CONFIG_PWRKEY_DNL_TRIGGER_NUM) && \
242 		(CONFIG_PWRKEY_DNL_TRIGGER_NUM > 0)
243 	power_key_download(uc_key);
244 #endif
245 }
246 #endif
247 
248 int key_bind_children(struct udevice *dev, const char *drv_name)
249 {
250 	const char *name;
251 	ofnode node;
252 	int ret;
253 
254 	dev_for_each_subnode(node, dev) {
255 		/*
256 		 * If this node has "compatible" property, this is not
257 		 * a amp subnode, but a normal device. skip.
258 		 */
259 		ofnode_get_property(node, "compatible", &ret);
260 		if (ret >= 0)
261 			continue;
262 
263 		if (ret != -FDT_ERR_NOTFOUND)
264 			return ret;
265 
266 		name = ofnode_get_name(node);
267 		if (!name)
268 			return -EINVAL;
269 		ret = device_bind_driver_to_node(dev, drv_name, name,
270 						 node, NULL);
271 		if (ret)
272 			return ret;
273 	}
274 
275 	return 0;
276 }
277 
278 static int key_post_probe(struct udevice *dev)
279 {
280 	struct dm_key_uclass_platdata *uc_key;
281 	int ret;
282 #ifdef CONFIG_SARADC_ROCKCHIP_V2
283 	int margin = 120;
284 #else
285 	int margin = 30;
286 #endif
287 	uc_key = dev_get_uclass_platdata(dev);
288 	if (!uc_key)
289 		return -ENXIO;
290 
291 	/* True from U-Boot key node */
292 	uc_key->pre_reloc = dev_read_bool(dev, "u-boot,dm-pre-reloc") ||
293 			    dev_read_bool(dev, "u-boot,dm-spl");
294 
295 	if (uc_key->type == ADC_KEY) {
296 		uc_key->max = uc_key->adcval + margin;
297 		uc_key->min = uc_key->adcval > margin ?
298 					uc_key->adcval - margin : 0;
299 	} else {
300 		if (uc_key->code == KEY_POWER) {
301 #if CONFIG_IS_ENABLED(IRQ)
302 			int irq;
303 
304 			if (uc_key->skip_irq_init)
305 				return 0;
306 
307 			irq = phandle_gpio_to_irq(uc_key->gpios[0],
308 						  uc_key->gpios[1]);
309 			if (irq < 0) {
310 				KEY_ERR("%s: failed to request irq, ret=%d\n",
311 					uc_key->name, irq);
312 				return irq;
313 			}
314 
315 			if (uc_key->code != KEY_POWER && uc_key->irq_thread) {
316 				KEY_WARN("%s: only power key can request irq thread\n",
317 					 uc_key->name);
318 				return -EINVAL;
319 			}
320 
321 			uc_key->irq = irq;
322 			irq_install_handler(irq, gpio_irq_handler, dev);
323 			irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
324 			irq_handler_enable(irq);
325 #else
326 			KEY_WARN("%s: no IRQ framework available\n", uc_key->name);
327 #endif
328 		} else {
329 			ret = gpio_request_by_name(dev, "gpios", 0,
330 						   &uc_key->gpio, GPIOD_IS_IN);
331 			if (ret) {
332 				KEY_ERR("%s: failed to request gpio, ret=%d\n",
333 					uc_key->name, ret);
334 				return ret;
335 			}
336 		}
337 	}
338 
339 #ifdef DEBUG
340 	printf("[%s] (%s, %s, %s):\n", uc_key->name,
341 	       uc_key->type == ADC_KEY ? "ADC" : "GPIO",
342 	       uc_key->pre_reloc ? "U-Boot" : "Kernel",
343 	       dev->parent->name);
344 
345 	if (uc_key->type == ADC_KEY) {
346 		printf("    adcval: %d (%d, %d)\n", uc_key->adcval,
347 		       uc_key->min, uc_key->max);
348 		printf("   channel: %d\n\n", uc_key->channel);
349 	} else {
350 		const char *gpio_name =
351 		     ofnode_get_name(ofnode_get_by_phandle(uc_key->gpios[0]));
352 
353 		printf("       irq: %d\n", uc_key->irq);
354 		printf("   gpio[0]: %s\n", gpio_name);
355 		printf("   gpio[1]: %d\n\n", uc_key->gpios[1]);
356 	}
357 #endif
358 
359 	return 0;
360 }
361 
362 UCLASS_DRIVER(key) = {
363 	.id		= UCLASS_KEY,
364 	.name		= "key",
365 	.post_probe	= key_post_probe,
366 	.per_device_platdata_auto_alloc_size =
367 			sizeof(struct dm_key_uclass_platdata),
368 };
369