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