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
arch_counter_get_cntpct(void)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
key_timer(uint64_t base)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
adc_raw_to_mV(struct udevice * dev,unsigned int raw,int * mV)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
key_adc_event(struct udevice * dev,struct dm_key_uclass_platdata * uc_key,int adcval)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
key_gpio_event(struct dm_key_uclass_platdata * uc_key)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
key_gpio_interrupt_event(struct dm_key_uclass_platdata * uc_key)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
key_is_pressed(int event)138 int key_is_pressed(int event)
139 {
140 return (event == KEY_PRESS_DOWN || event == KEY_PRESS_LONG_DOWN);
141 }
142
key_core_read(struct dm_key_uclass_platdata * uc_key)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
key_read(int code)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
key_exist(int code)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)
power_key_download(struct dm_key_uclass_platdata * uc_key)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
pwrkey_download_init(void)256 int pwrkey_download_init(void)
257 {
258 return (KEY_NOT_EXIST == key_read(KEY_POWER));
259 }
260 #endif
261
gpio_irq_handler(int irq,void * data)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
key_bind_children(struct udevice * dev,const char * drv_name)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
key_post_probe(struct udevice * dev)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