10
10
#include <zephyr/drivers/gpio.h>
11
11
#include <zephyr/input/input.h>
12
12
#include <zephyr/logging/log.h>
13
+ #include <zephyr/math/ilog2.h>
13
14
LOG_MODULE_REGISTER (cap12xx , CONFIG_INPUT_LOG_LEVEL );
14
15
15
- #define REG_MAIN_CONTROL 0x00
16
- #define CONTROL_INT 0x01
16
+ #define REG_MAIN_CONTROL 0x00
17
+ #define MAIN_CONTROL_GAIN_MASK GENMASK(7, 6)
18
+ #define MAIN_CONTROL_GAIN_SHIFT 6
19
+
20
+ #define CONTROL_INT 0x01
17
21
18
22
#define REG_INPUT_STATUS 0x03
19
23
24
+ #define REG_SENSITIVITY_CONTROL 0x1F
25
+ #define DELTA_SENSE_BITS 3
26
+ #define DELTA_SENSE_SHIFT 4
27
+ #define DELTA_SENSE_MASK GENMASK(6, 4)
28
+ #define DELTA_SENSE_MAX GENMASK(DELTA_SENSE_BITS - 1, 0)
29
+
20
30
#define REG_INTERRUPT_ENABLE 0x27
21
31
#define INTERRUPT_ENABLE 0xFF
22
32
#define INTERRUPT_DISABLE 0x00
@@ -25,13 +35,24 @@ LOG_MODULE_REGISTER(cap12xx, CONFIG_INPUT_LOG_LEVEL);
25
35
#define REPEAT_ENABLE 0xFF
26
36
#define REPEAT_DISABLE 0x00
27
37
38
+ #define REG_SIGNAL_GUARD_ENABLE 0x29
39
+
40
+ #define REG_CALIB_SENSITIVITY_CONFIG1 0x80
41
+ #define REG_CALIB_SENSITIVITY_CONFIG2 0x81
42
+ #define CALSENS_BITS 2
43
+ #define NUM_CALSENS_PER_REG 4
44
+
28
45
struct cap12xx_config {
29
46
struct i2c_dt_spec i2c ;
30
47
const uint8_t input_channels ;
31
48
const uint16_t * input_codes ;
32
49
struct gpio_dt_spec * int_gpio ;
33
50
bool repeat ;
34
51
const uint16_t poll_interval_ms ;
52
+ const uint8_t sensor_gain ;
53
+ const uint8_t sensitivity_delta_sense ;
54
+ const uint8_t * signal_guard ;
55
+ const uint8_t * calib_sensitivity ;
35
56
};
36
57
37
58
struct cap12xx_data {
@@ -45,11 +66,11 @@ struct cap12xx_data {
45
66
static int cap12xx_clear_interrupt (const struct i2c_dt_spec * i2c )
46
67
{
47
68
uint8_t ctrl ;
48
- int r ;
69
+ int ret ;
49
70
50
- r = i2c_reg_read_byte_dt (i2c , REG_MAIN_CONTROL , & ctrl );
51
- if (r < 0 ) {
52
- return r ;
71
+ ret = i2c_reg_read_byte_dt (i2c , REG_MAIN_CONTROL , & ctrl );
72
+ if (ret < 0 ) {
73
+ return ret ;
53
74
}
54
75
55
76
ctrl = ctrl & ~CONTROL_INT ;
@@ -63,25 +84,65 @@ static int cap12xx_enable_interrupt(const struct i2c_dt_spec *i2c, bool enable)
63
84
return i2c_reg_write_byte_dt (i2c , REG_INTERRUPT_ENABLE , intr );
64
85
}
65
86
87
+ static int cap12xx_set_sensor_gain (const struct i2c_dt_spec * i2c , uint8_t gain )
88
+ {
89
+ uint8_t regval = gain << MAIN_CONTROL_GAIN_SHIFT ;
90
+
91
+ return i2c_reg_update_byte_dt (i2c , REG_MAIN_CONTROL , MAIN_CONTROL_GAIN_MASK , regval );
92
+ }
93
+
94
+ static int cap12xx_set_sensitivity (const struct i2c_dt_spec * i2c , uint8_t sensitivity )
95
+ {
96
+ uint8_t regval = sensitivity << DELTA_SENSE_SHIFT ;
97
+
98
+ return i2c_reg_update_byte_dt (i2c , REG_SENSITIVITY_CONTROL , DELTA_SENSE_MASK , regval );
99
+ }
100
+
101
+ static int cap12xx_set_calsens (const struct i2c_dt_spec * i2c , const uint8_t * calsens ,
102
+ uint8_t channels )
103
+ {
104
+ int ret ;
105
+ uint8_t regval ;
106
+
107
+ for (uint8_t i = 0 ; i < channels ; i += NUM_CALSENS_PER_REG ) {
108
+ regval = 0 ;
109
+ for (uint8_t j = 0 ; j < NUM_CALSENS_PER_REG && i + j < channels ; j ++ ) {
110
+ /* Convert the enumerated sensitivity to the corresponding register value */
111
+ regval |= (ilog2 (calsens [i + j ]) << (CALSENS_BITS * j ));
112
+ }
113
+ if (i == 0 ) {
114
+ ret = i2c_reg_write_byte_dt (i2c , REG_CALIB_SENSITIVITY_CONFIG1 , regval );
115
+ } else {
116
+ ret = i2c_reg_write_byte_dt (i2c , REG_CALIB_SENSITIVITY_CONFIG2 , regval );
117
+ }
118
+
119
+ if (ret ) {
120
+ return ret ;
121
+ }
122
+ }
123
+
124
+ return 0 ;
125
+ }
126
+
66
127
static int cap12xx_process (const struct device * dev )
67
128
{
68
129
const struct cap12xx_config * config = dev -> config ;
69
130
struct cap12xx_data * data = dev -> data ;
70
- int r ;
131
+ int ret ;
71
132
uint8_t input_state ;
72
133
73
134
/*
74
135
* Clear INT bit to clear SENSOR INPUT STATUS bits.
75
136
* Note that this is also required in polling mode.
76
137
*/
77
- r = cap12xx_clear_interrupt (& config -> i2c );
138
+ ret = cap12xx_clear_interrupt (& config -> i2c );
78
139
79
- if (r < 0 ) {
80
- return r ;
140
+ if (ret < 0 ) {
141
+ return ret ;
81
142
}
82
- r = i2c_reg_read_byte_dt (& config -> i2c , REG_INPUT_STATUS , & input_state );
83
- if (r < 0 ) {
84
- return r ;
143
+ ret = i2c_reg_read_byte_dt (& config -> i2c , REG_INPUT_STATUS , & input_state );
144
+ if (ret < 0 ) {
145
+ return ret ;
85
146
}
86
147
87
148
if (config -> int_gpio == NULL ) {
@@ -129,7 +190,8 @@ static int cap12xx_init(const struct device *dev)
129
190
{
130
191
const struct cap12xx_config * config = dev -> config ;
131
192
struct cap12xx_data * data = dev -> data ;
132
- int r ;
193
+ uint8_t guarded_channels = 0 ;
194
+ int ret ;
133
195
134
196
if (!device_is_ready (config -> i2c .bus )) {
135
197
LOG_ERR ("I2C controller device not ready" );
@@ -140,13 +202,43 @@ static int cap12xx_init(const struct device *dev)
140
202
141
203
k_work_init (& data -> work , cap12xx_work_handler );
142
204
205
+ for (uint8_t i = 0 ; i < config -> input_channels ; i ++ ) {
206
+ if (config -> signal_guard [i ]) {
207
+ guarded_channels |= BIT (i );
208
+ }
209
+ }
210
+ ret = i2c_reg_write_byte_dt (& config -> i2c , REG_SIGNAL_GUARD_ENABLE , guarded_channels );
211
+ if (ret < 0 ) {
212
+ LOG_ERR ("Could not set guarded channels" );
213
+ return ret ;
214
+ }
215
+ ret = cap12xx_set_calsens (& config -> i2c , config -> calib_sensitivity , config -> input_channels );
216
+ if (ret < 0 ) {
217
+ LOG_ERR ("Could not set calibration sensitivities" );
218
+ return ret ;
219
+ }
220
+ /* Convert the enumerated gain to the corresponding register value */
221
+ ret = cap12xx_set_sensor_gain (& config -> i2c , ilog2 (config -> sensor_gain ));
222
+ if (ret < 0 ) {
223
+ LOG_ERR ("Could not set analog gain" );
224
+ return ret ;
225
+ }
226
+ /* Convert the enumerated sensitivity to the corresponding register value,
227
+ * which is in reverse order
228
+ */
229
+ ret = cap12xx_set_sensitivity (& config -> i2c ,
230
+ DELTA_SENSE_MAX - ilog2 (config -> sensitivity_delta_sense ));
231
+ if (ret < 0 ) {
232
+ LOG_ERR ("Could not set sensitivity" );
233
+ return ret ;
234
+ }
143
235
if (config -> int_gpio == NULL ) {
144
236
LOG_DBG ("cap12xx driver in polling mode" );
145
237
k_timer_init (& data -> poll_timer , cap12xx_timer_handler , NULL );
146
- r = cap12xx_enable_interrupt (& config -> i2c , true);
147
- if (r < 0 ) {
238
+ ret = cap12xx_enable_interrupt (& config -> i2c , true);
239
+ if (ret < 0 ) {
148
240
LOG_ERR ("Could not configure interrupt" );
149
- return r ;
241
+ return ret ;
150
242
}
151
243
k_timer_start (& data -> poll_timer , K_MSEC (config -> poll_interval_ms ),
152
244
K_MSEC (config -> poll_interval_ms ));
@@ -158,49 +250,50 @@ static int cap12xx_init(const struct device *dev)
158
250
return - ENODEV ;
159
251
}
160
252
161
- r = gpio_pin_configure_dt (config -> int_gpio , GPIO_INPUT );
162
- if (r < 0 ) {
253
+ ret = gpio_pin_configure_dt (config -> int_gpio , GPIO_INPUT );
254
+ if (ret < 0 ) {
163
255
LOG_ERR ("Could not configure interrupt GPIO pin" );
164
- return r ;
256
+ return ret ;
165
257
}
166
258
167
- r = gpio_pin_interrupt_configure_dt (config -> int_gpio , GPIO_INT_EDGE_TO_ACTIVE );
168
- if (r < 0 ) {
259
+ ret = gpio_pin_interrupt_configure_dt (config -> int_gpio , GPIO_INT_EDGE_TO_ACTIVE );
260
+ if (ret < 0 ) {
169
261
LOG_ERR ("Could not configure interrupt GPIO interrupt" );
170
- return r ;
262
+ return ret ;
171
263
}
172
264
173
265
gpio_init_callback (& data -> int_gpio_cb , cap12xx_isr_handler ,
174
266
BIT (config -> int_gpio -> pin ));
175
267
176
- r = gpio_add_callback_dt (config -> int_gpio , & data -> int_gpio_cb );
177
- if (r < 0 ) {
268
+ ret = gpio_add_callback_dt (config -> int_gpio , & data -> int_gpio_cb );
269
+ if (ret < 0 ) {
178
270
LOG_ERR ("Could not set gpio callback" );
179
- return r ;
271
+ return ret ;
180
272
}
181
273
182
- r = cap12xx_clear_interrupt (& config -> i2c );
183
- if (r < 0 ) {
274
+ ret = cap12xx_clear_interrupt (& config -> i2c );
275
+ if (ret < 0 ) {
184
276
LOG_ERR ("Could not clear interrupt" );
185
- return r ;
277
+ return ret ;
186
278
}
187
- r = cap12xx_enable_interrupt (& config -> i2c , true);
188
- if (r < 0 ) {
279
+ ret = cap12xx_enable_interrupt (& config -> i2c , true);
280
+ if (ret < 0 ) {
189
281
LOG_ERR ("Could not configure interrupt" );
190
- return r ;
282
+ return ret ;
191
283
}
192
284
if (config -> repeat ) {
193
- r = i2c_reg_write_byte_dt (& config -> i2c , REG_REPEAT_ENABLE , REPEAT_ENABLE );
194
- if (r < 0 ) {
285
+ ret = i2c_reg_write_byte_dt (& config -> i2c , REG_REPEAT_ENABLE , REPEAT_ENABLE );
286
+ if (ret < 0 ) {
195
287
LOG_ERR ("Could not disable repeated interrupts" );
196
- return r ;
288
+ return ret ;
197
289
}
198
290
LOG_DBG ("cap12xx enabled repeated interrupts" );
199
291
} else {
200
- r = i2c_reg_write_byte_dt (& config -> i2c , REG_REPEAT_ENABLE , REPEAT_DISABLE );
201
- if (r < 0 ) {
292
+ ret = i2c_reg_write_byte_dt (& config -> i2c , REG_REPEAT_ENABLE ,
293
+ REPEAT_DISABLE );
294
+ if (ret < 0 ) {
202
295
LOG_ERR ("Could not enable repeated interrupts" );
203
- return r ;
296
+ return ret ;
204
297
}
205
298
LOG_DBG ("cap12xx disabled repeated interrupts" );
206
299
}
@@ -214,14 +307,22 @@ static int cap12xx_init(const struct device *dev)
214
307
static struct gpio_dt_spec cap12xx_int_gpio_##index = \
215
308
GPIO_DT_SPEC_INST_GET(index, int_gpios);)) \
216
309
static const uint16_t cap12xx_input_codes_##index[] = DT_INST_PROP(index, input_codes); \
310
+ static const uint8_t cap12xx_signal_guard_##index[] = \
311
+ DT_INST_PROP(index, signal_guard); \
312
+ static const uint8_t cap12xx_calib_sensitivity_##index[] = \
313
+ DT_INST_PROP(index, calib_sensitivity); \
217
314
static const struct cap12xx_config cap12xx_config_##index = { \
218
315
.i2c = I2C_DT_SPEC_INST_GET(index), \
219
316
.input_channels = DT_INST_PROP_LEN(index, input_codes), \
220
317
.input_codes = cap12xx_input_codes_##index, \
221
318
IF_ENABLED(DT_INST_NODE_HAS_PROP(index, int_gpios), ( \
222
319
.int_gpio = &cap12xx_int_gpio_##index,)) \
223
320
.repeat = DT_INST_PROP(index, repeat), \
224
- .poll_interval_ms = DT_INST_PROP_OR(index, poll_interval_ms, 10)}; \
321
+ .poll_interval_ms = DT_INST_PROP(index, poll_interval_ms), \
322
+ .sensor_gain = DT_INST_PROP(index, sensor_gain), \
323
+ .sensitivity_delta_sense = DT_INST_PROP(index, sensitivity_delta_sense), \
324
+ .signal_guard = cap12xx_signal_guard_##index, \
325
+ .calib_sensitivity = cap12xx_calib_sensitivity_##index}; \
225
326
static struct cap12xx_data cap12xx_data_##index; \
226
327
DEVICE_DT_INST_DEFINE(index, cap12xx_init, NULL, &cap12xx_data_##index, \
227
328
&cap12xx_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \
0 commit comments