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