input: add spl adc key driver

Providing a mininum adc key driver for SPL, which does not
depend on key uclass, but ADC uclass is still required.

Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Change-Id: I80f861780acd9c47d345b95762a4dd39d19ea6fc
This commit is contained in:
Joseph Chen 2020-04-17 10:50:10 +08:00 committed by Jianhong Chen
parent 3509e794f3
commit abedddcfae
3 changed files with 82 additions and 0 deletions

View File

@ -105,6 +105,12 @@ config ADC_KEY
help
This adds a driver for the adc keys support.
config SPL_ADC_KEY
bool "Enable SPL adc keys support without DM"
depends on SPL_INPUT
help
This adds a driver for the SPL adc keys support
config GPIO_KEY
bool "Enable gpio keys support"
depends on DM_KEY

View File

@ -28,4 +28,7 @@ ifdef CONFIG_PS2KBD
obj-y += keyboard.o pc_keyb.o
obj-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o
endif
else
obj-$(CONFIG_SPL_ADC_KEY) += spl_adc_key.o
endif

View File

@ -0,0 +1,73 @@
/*
* (C) Copyright 2020 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <adc.h>
#include <fdtdec.h>
DECLARE_GLOBAL_DATA_PTR;
int key_read(int code)
{
const void *fdt_blob = gd->fdt_blob;
int adc_node, offset;
int cd, channel, adc;
int ret, vref, mv;
int min, max;
int margin = 30;
uint val;
u32 chn[2];
adc_node = fdt_node_offset_by_compatible(fdt_blob, 0, "adc-keys");
if (adc_node < 0) {
debug("No 'adc-keys' node, ret=%d\n", adc_node);
return 0;
}
ret = fdtdec_get_int_array(fdt_blob, adc_node, "io-channels",
chn, ARRAY_SIZE(chn));
if (ret) {
debug("Can't read 'io-channels', ret=%d\n", ret);
return 0;
}
vref = fdtdec_get_int(fdt_blob, adc_node,
"keyup-threshold-microvolt", -1);
if (vref < 0) {
debug("Can't read 'keyup-threshold-microvolt'\n");
return 0;
}
channel = chn[1];
for (offset = fdt_first_subnode(fdt_blob, adc_node);
offset >= 0;
offset = fdt_next_subnode(fdt_blob, offset)) {
cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -1);
if (cd == code) {
mv = fdtdec_get_int(fdt_blob, offset,
"press-threshold-microvolt", -1);
if (mv < 0) {
debug("Can't read 'press-threshold-microvolt'\n");
return 0;
}
adc = mv / (vref / 1024); /* 10-bit adc */
max = adc + margin;
min = adc > margin ? adc - margin : 0;
ret = adc_channel_single_shot("saradc", channel, &val);
if (ret) {
debug("Failed to read adc%d, ret=%d\n",
channel, ret);
return 0;
}
return (val >= min && val <= max);
}
}
return 0;
}