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