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