hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
u-boot/drivers/input/spl_adc_key.c
....@@ -6,28 +6,46 @@
66
77 #include <common.h>
88 #include <adc.h>
9
+#include <div64.h>
910 #include <fdtdec.h>
11
+#include <dm/uclass.h>
1012
1113 DECLARE_GLOBAL_DATA_PTR;
14
+
15
+static int adc_raw_to_mV(struct udevice *dev, unsigned int raw, int *mV)
16
+{
17
+ unsigned int data_mask;
18
+ int ret, vref = 1800000;
19
+ u64 raw64 = raw;
20
+
21
+ ret = adc_data_mask(dev, &data_mask);
22
+ if (ret)
23
+ return ret;
24
+
25
+ raw64 *= vref;
26
+ do_div(raw64, data_mask);
27
+ *mV = raw64;
28
+
29
+ return 0;
30
+}
1231
1332 int key_read(int code)
1433 {
1534 const void *fdt_blob = gd->fdt_blob;
35
+ struct udevice *dev;
1636 int adc_node, offset;
17
- int cd, channel, adc;
18
- int ret, vref, mv;
37
+ int t, down_threshold = -1, up_threshold;
38
+ int ret, num = 0, volt_margin = 150000; /* will be div 2 */
39
+ int mV, cd, voltage = -1;
1940 int min, max;
20
- int margin;
21
- int range;
22
- uint val;
23
- u32 chn[2];
24
-#ifdef CONFIG_SARADC_ROCKCHIP_V2
25
- range = 4096; /* 12-bit adc */
26
- margin = 120;
27
-#else
28
- range = 1024; /* 10-bit adc */
29
- margin = 30;
30
-#endif
41
+ u32 chn[2], adc;
42
+
43
+ ret = uclass_get_device_by_name(UCLASS_ADC, "saradc", &dev);
44
+ if (ret) {
45
+ debug("No saradc device, ret=%d\n", ret);
46
+ return 0;
47
+ }
48
+
3149 adc_node = fdt_node_offset_by_compatible(fdt_blob, 0, "adc-keys");
3250 if (adc_node < 0) {
3351 debug("No 'adc-keys' node, ret=%d\n", adc_node);
....@@ -41,40 +59,87 @@
4159 return 0;
4260 }
4361
44
- vref = fdtdec_get_int(fdt_blob, adc_node,
45
- "keyup-threshold-microvolt", -1);
46
- if (vref < 0) {
62
+ up_threshold = fdtdec_get_int(fdt_blob, adc_node,
63
+ "keyup-threshold-microvolt", -ENODATA);
64
+ if (up_threshold < 0) {
4765 debug("Can't read 'keyup-threshold-microvolt'\n");
4866 return 0;
4967 }
5068
51
- channel = chn[1];
69
+ /* find the expected key-code */
70
+ for (offset = fdt_first_subnode(fdt_blob, adc_node);
71
+ offset >= 0;
72
+ offset = fdt_next_subnode(fdt_blob, offset)) {
73
+ cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -ENODATA);
74
+ if (cd < 0) {
75
+ debug("Can't read 'linux,code', ret=%d\n", cd);
76
+ return 0;
77
+ }
78
+
79
+ if (cd == code) {
80
+ voltage = fdtdec_get_int(fdt_blob, offset,
81
+ "press-threshold-microvolt", -ENODATA);
82
+ if (voltage < 0) {
83
+ debug("Can't read 'press-threshold-microvolt'\n");
84
+ return 0;
85
+ }
86
+ break;
87
+ }
88
+ }
89
+
90
+ if (voltage < 0)
91
+ return 0;
5292
5393 for (offset = fdt_first_subnode(fdt_blob, adc_node);
5494 offset >= 0;
5595 offset = fdt_next_subnode(fdt_blob, offset)) {
56
- cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -1);
57
- if (cd == code) {
58
- mv = fdtdec_get_int(fdt_blob, offset,
59
- "press-threshold-microvolt", -1);
60
- if (mv < 0) {
61
- debug("Can't read 'press-threshold-microvolt'\n");
62
- return 0;
63
- }
64
-
65
- adc = mv / (vref / range);
66
- max = adc + margin;
67
- min = adc > margin ? adc - margin : 0;
68
- ret = adc_channel_single_shot("saradc", channel, &val);
69
- if (ret) {
70
- debug("Failed to read adc%d, ret=%d\n",
71
- channel, ret);
72
- return 0;
73
- }
74
-
75
- return (val >= min && val <= max);
96
+ t = fdtdec_get_int(fdt_blob, offset,
97
+ "press-threshold-microvolt", -ENODATA);
98
+ if (t < 0) {
99
+ debug("Can't read 'press-threshold-microvolt'\n");
100
+ return 0;
76101 }
102
+
103
+ if (t > voltage && t < up_threshold)
104
+ up_threshold = t;
105
+ else if (t < voltage && t > down_threshold)
106
+ down_threshold = t;
107
+ num++;
77108 }
78109
79
- return 0;
110
+ /* although one node only, it doesn't mean only one key on hardware */
111
+ if (num == 1) {
112
+ down_threshold = voltage - volt_margin;
113
+ up_threshold = voltage + volt_margin;
114
+ }
115
+
116
+ /*
117
+ * Define the voltage range such that the button is only pressed
118
+ * when the voltage is closest to its own press-threshold-microvolt
119
+ */
120
+ if (down_threshold < 0)
121
+ min = 0;
122
+ else
123
+ min = down_threshold + (voltage - down_threshold) / 2;
124
+
125
+ max = voltage + (up_threshold - voltage) / 2;
126
+
127
+ /* now, read key status */
128
+ ret = adc_channel_single_shot("saradc", chn[1], &adc);
129
+ if (ret) {
130
+ debug("Failed to read adc%d, ret=%d\n", chn[1], ret);
131
+ return 0;
132
+ }
133
+
134
+ ret = adc_raw_to_mV(dev, adc, &mV);
135
+ if (ret) {
136
+ debug("Failed to convert adc to mV, ret=%d\n", ret);
137
+ return 0;
138
+ }
139
+
140
+ debug("key[%d] <%d, %d, %d>: adc=%d -> mV=%d\n",
141
+ code, min, voltage, max, adc, mV);
142
+
143
+ return (mV <= max && mV >= min);
80144 }
145
+