2017-09-18 11:41:54 +00:00
|
|
|
/*
|
|
|
|
|
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <dm.h>
|
|
|
|
|
#include <key.h>
|
2018-01-30 07:34:49 +00:00
|
|
|
#include <common.h>
|
|
|
|
|
#include <dm.h>
|
2017-09-18 11:41:54 +00:00
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
static inline uint64_t arch_counter_get_cntpct(void)
|
2017-09-18 11:41:54 +00:00
|
|
|
{
|
2018-01-30 07:34:49 +00:00
|
|
|
uint64_t cval = 0;
|
2017-09-18 11:41:54 +00:00
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
isb();
|
|
|
|
|
#ifdef CONFIG_ARM64
|
|
|
|
|
asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
|
|
|
|
|
#else
|
|
|
|
|
asm volatile ("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
|
|
|
|
|
#endif
|
|
|
|
|
return cval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t key_get_timer(uint64_t base)
|
|
|
|
|
{
|
|
|
|
|
uint64_t cntpct;
|
|
|
|
|
|
|
|
|
|
cntpct = arch_counter_get_cntpct() / 24000UL;
|
|
|
|
|
return (cntpct > base) ? (cntpct - base) : 0;
|
|
|
|
|
}
|
2017-09-18 11:41:54 +00:00
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
static int key_state_valid(int state)
|
|
|
|
|
{
|
|
|
|
|
return (state >= KEY_PRESS_NONE && state < KEY_NOT_EXIST);
|
2017-09-18 11:41:54 +00:00
|
|
|
}
|
|
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
static int key_read(struct udevice *dev, int code)
|
2017-10-27 09:42:18 +00:00
|
|
|
{
|
|
|
|
|
const struct dm_key_ops *ops = dev_get_driver_ops(dev);
|
|
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
if (!ops || !ops->read)
|
2017-10-27 09:42:18 +00:00
|
|
|
return -ENOSYS;
|
|
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
return ops->read(dev, code);
|
2017-10-27 09:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
int platform_key_read(int code)
|
2017-10-27 09:42:18 +00:00
|
|
|
{
|
2018-01-30 07:34:49 +00:00
|
|
|
struct udevice *dev;
|
|
|
|
|
int report = KEY_NOT_EXIST;
|
2017-10-27 09:42:18 +00:00
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
for (uclass_first_device(UCLASS_KEY, &dev);
|
|
|
|
|
dev;
|
|
|
|
|
uclass_next_device(&dev)) {
|
|
|
|
|
debug("key dev.name = %s, code = %d\n", dev->name, code);
|
|
|
|
|
report = key_read(dev, code);
|
|
|
|
|
if (key_state_valid(report)) {
|
|
|
|
|
debug("key dev.name = %s, state=%d\n", dev->name, report);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-27 09:42:18 +00:00
|
|
|
|
2018-01-30 07:34:49 +00:00
|
|
|
return report;
|
2017-10-27 09:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
2017-09-18 11:41:54 +00:00
|
|
|
UCLASS_DRIVER(key) = {
|
|
|
|
|
.id = UCLASS_KEY,
|
|
|
|
|
.name = "key",
|
|
|
|
|
};
|