From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
u-boot/drivers/input/spl_adc_key.c | 141 ++++++++++++++++++++++++++++++++++------------
1 files changed, 103 insertions(+), 38 deletions(-)
diff --git a/u-boot/drivers/input/spl_adc_key.c b/u-boot/drivers/input/spl_adc_key.c
index 60e0394..8aceaef 100644
--- a/u-boot/drivers/input/spl_adc_key.c
+++ b/u-boot/drivers/input/spl_adc_key.c
@@ -6,28 +6,46 @@
#include <common.h>
#include <adc.h>
+#include <div64.h>
#include <fdtdec.h>
+#include <dm/uclass.h>
DECLARE_GLOBAL_DATA_PTR;
+
+static int adc_raw_to_mV(struct udevice *dev, unsigned int raw, int *mV)
+{
+ unsigned int data_mask;
+ int ret, vref = 1800000;
+ u64 raw64 = raw;
+
+ ret = adc_data_mask(dev, &data_mask);
+ if (ret)
+ return ret;
+
+ raw64 *= vref;
+ do_div(raw64, data_mask);
+ *mV = raw64;
+
+ return 0;
+}
int key_read(int code)
{
const void *fdt_blob = gd->fdt_blob;
+ struct udevice *dev;
int adc_node, offset;
- int cd, channel, adc;
- int ret, vref, mv;
+ int t, down_threshold = -1, up_threshold;
+ int ret, num = 0, volt_margin = 150000; /* will be div 2 */
+ int mV, cd, voltage = -1;
int min, max;
- int margin;
- int range;
- uint val;
- u32 chn[2];
-#ifdef CONFIG_SARADC_ROCKCHIP_V2
- range = 4096; /* 12-bit adc */
- margin = 120;
-#else
- range = 1024; /* 10-bit adc */
- margin = 30;
-#endif
+ u32 chn[2], adc;
+
+ ret = uclass_get_device_by_name(UCLASS_ADC, "saradc", &dev);
+ if (ret) {
+ debug("No saradc device, ret=%d\n", ret);
+ return 0;
+ }
+
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);
@@ -41,40 +59,87 @@
return 0;
}
- vref = fdtdec_get_int(fdt_blob, adc_node,
- "keyup-threshold-microvolt", -1);
- if (vref < 0) {
+ up_threshold = fdtdec_get_int(fdt_blob, adc_node,
+ "keyup-threshold-microvolt", -ENODATA);
+ if (up_threshold < 0) {
debug("Can't read 'keyup-threshold-microvolt'\n");
return 0;
}
- channel = chn[1];
+ /* find the expected key-code */
+ 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", -ENODATA);
+ if (cd < 0) {
+ debug("Can't read 'linux,code', ret=%d\n", cd);
+ return 0;
+ }
+
+ if (cd == code) {
+ voltage = fdtdec_get_int(fdt_blob, offset,
+ "press-threshold-microvolt", -ENODATA);
+ if (voltage < 0) {
+ debug("Can't read 'press-threshold-microvolt'\n");
+ return 0;
+ }
+ break;
+ }
+ }
+
+ if (voltage < 0)
+ return 0;
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 / range);
- 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);
+ t = fdtdec_get_int(fdt_blob, offset,
+ "press-threshold-microvolt", -ENODATA);
+ if (t < 0) {
+ debug("Can't read 'press-threshold-microvolt'\n");
+ return 0;
}
+
+ if (t > voltage && t < up_threshold)
+ up_threshold = t;
+ else if (t < voltage && t > down_threshold)
+ down_threshold = t;
+ num++;
}
- return 0;
+ /* although one node only, it doesn't mean only one key on hardware */
+ if (num == 1) {
+ down_threshold = voltage - volt_margin;
+ up_threshold = voltage + volt_margin;
+ }
+
+ /*
+ * Define the voltage range such that the button is only pressed
+ * when the voltage is closest to its own press-threshold-microvolt
+ */
+ if (down_threshold < 0)
+ min = 0;
+ else
+ min = down_threshold + (voltage - down_threshold) / 2;
+
+ max = voltage + (up_threshold - voltage) / 2;
+
+ /* now, read key status */
+ ret = adc_channel_single_shot("saradc", chn[1], &adc);
+ if (ret) {
+ debug("Failed to read adc%d, ret=%d\n", chn[1], ret);
+ return 0;
+ }
+
+ ret = adc_raw_to_mV(dev, adc, &mV);
+ if (ret) {
+ debug("Failed to convert adc to mV, ret=%d\n", ret);
+ return 0;
+ }
+
+ debug("key[%d] <%d, %d, %d>: adc=%d -> mV=%d\n",
+ code, min, voltage, max, adc, mV);
+
+ return (mV <= max && mV >= min);
}
+
--
Gitblit v1.6.2