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