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