1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <dm.h> 8 #include <key.h> 9 #include <common.h> 10 #include <dm.h> 11 12 static inline uint64_t arch_counter_get_cntpct(void) 13 { 14 uint64_t cval = 0; 15 16 isb(); 17 #ifdef CONFIG_ARM64 18 asm volatile("mrs %0, cntpct_el0" : "=r" (cval)); 19 #else 20 asm volatile ("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); 21 #endif 22 return cval; 23 } 24 25 uint64_t key_get_timer(uint64_t base) 26 { 27 uint64_t cntpct; 28 29 cntpct = arch_counter_get_cntpct() / 24000UL; 30 return (cntpct > base) ? (cntpct - base) : 0; 31 } 32 33 static int key_state_valid(int state) 34 { 35 return (state >= KEY_PRESS_NONE && state < KEY_NOT_EXIST); 36 } 37 38 static int key_read(struct udevice *dev, int code) 39 { 40 const struct dm_key_ops *ops = dev_get_driver_ops(dev); 41 42 if (!ops || !ops->read) 43 return -ENOSYS; 44 45 return ops->read(dev, code); 46 } 47 48 int platform_key_read(int code) 49 { 50 struct udevice *dev; 51 int report = KEY_NOT_EXIST; 52 53 for (uclass_first_device(UCLASS_KEY, &dev); 54 dev; 55 uclass_next_device(&dev)) { 56 debug("key dev.name = %s, code = %d\n", dev->name, code); 57 report = key_read(dev, code); 58 if (key_state_valid(report)) { 59 debug("key dev.name = %s, state=%d\n", dev->name, report); 60 break; 61 } 62 } 63 64 return report; 65 } 66 67 UCLASS_DRIVER(key) = { 68 .id = UCLASS_KEY, 69 .name = "key", 70 }; 71