1010#include <zephyr/drivers/gpio.h>
1111#include <zephyr/input/input.h>
1212#include <zephyr/logging/log.h>
13+ #include <zephyr/math/ilog2.h>
1314LOG_MODULE_REGISTER (cap12xx , CONFIG_INPUT_LOG_LEVEL );
1415
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
1721
1822#define REG_INPUT_STATUS 0x03
1923
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+
2030#define REG_INTERRUPT_ENABLE 0x27
2131#define INTERRUPT_ENABLE 0xFF
2232#define INTERRUPT_DISABLE 0x00
@@ -25,13 +35,24 @@ LOG_MODULE_REGISTER(cap12xx, CONFIG_INPUT_LOG_LEVEL);
2535#define REPEAT_ENABLE 0xFF
2636#define REPEAT_DISABLE 0x00
2737
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+
2845struct cap12xx_config {
2946 struct i2c_dt_spec i2c ;
3047 const uint8_t input_channels ;
3148 const uint16_t * input_codes ;
3249 struct gpio_dt_spec * int_gpio ;
3350 bool repeat ;
3451 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 ;
3556};
3657
3758struct cap12xx_data {
@@ -45,11 +66,11 @@ struct cap12xx_data {
4566static int cap12xx_clear_interrupt (const struct i2c_dt_spec * i2c )
4667{
4768 uint8_t ctrl ;
48- int r ;
69+ int ret ;
4970
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 ;
5374 }
5475
5576 ctrl = ctrl & ~CONTROL_INT ;
@@ -63,25 +84,65 @@ static int cap12xx_enable_interrupt(const struct i2c_dt_spec *i2c, bool enable)
6384 return i2c_reg_write_byte_dt (i2c , REG_INTERRUPT_ENABLE , intr );
6485}
6586
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+
66127static int cap12xx_process (const struct device * dev )
67128{
68129 const struct cap12xx_config * config = dev -> config ;
69130 struct cap12xx_data * data = dev -> data ;
70- int r ;
131+ int ret ;
71132 uint8_t input_state ;
72133
73134 /*
74135 * Clear INT bit to clear SENSOR INPUT STATUS bits.
75136 * Note that this is also required in polling mode.
76137 */
77- r = cap12xx_clear_interrupt (& config -> i2c );
138+ ret = cap12xx_clear_interrupt (& config -> i2c );
78139
79- if (r < 0 ) {
80- return r ;
140+ if (ret < 0 ) {
141+ return ret ;
81142 }
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 ;
85146 }
86147
87148 if (config -> int_gpio == NULL ) {
@@ -129,7 +190,8 @@ static int cap12xx_init(const struct device *dev)
129190{
130191 const struct cap12xx_config * config = dev -> config ;
131192 struct cap12xx_data * data = dev -> data ;
132- int r ;
193+ uint8_t guarded_channels = 0 ;
194+ int ret ;
133195
134196 if (!device_is_ready (config -> i2c .bus )) {
135197 LOG_ERR ("I2C controller device not ready" );
@@ -140,13 +202,43 @@ static int cap12xx_init(const struct device *dev)
140202
141203 k_work_init (& data -> work , cap12xx_work_handler );
142204
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+ }
143235 if (config -> int_gpio == NULL ) {
144236 LOG_DBG ("cap12xx driver in polling mode" );
145237 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 ) {
148240 LOG_ERR ("Could not configure interrupt" );
149- return r ;
241+ return ret ;
150242 }
151243 k_timer_start (& data -> poll_timer , K_MSEC (config -> poll_interval_ms ),
152244 K_MSEC (config -> poll_interval_ms ));
@@ -158,49 +250,50 @@ static int cap12xx_init(const struct device *dev)
158250 return - ENODEV ;
159251 }
160252
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 ) {
163255 LOG_ERR ("Could not configure interrupt GPIO pin" );
164- return r ;
256+ return ret ;
165257 }
166258
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 ) {
169261 LOG_ERR ("Could not configure interrupt GPIO interrupt" );
170- return r ;
262+ return ret ;
171263 }
172264
173265 gpio_init_callback (& data -> int_gpio_cb , cap12xx_isr_handler ,
174266 BIT (config -> int_gpio -> pin ));
175267
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 ) {
178270 LOG_ERR ("Could not set gpio callback" );
179- return r ;
271+ return ret ;
180272 }
181273
182- r = cap12xx_clear_interrupt (& config -> i2c );
183- if (r < 0 ) {
274+ ret = cap12xx_clear_interrupt (& config -> i2c );
275+ if (ret < 0 ) {
184276 LOG_ERR ("Could not clear interrupt" );
185- return r ;
277+ return ret ;
186278 }
187- r = cap12xx_enable_interrupt (& config -> i2c , true);
188- if (r < 0 ) {
279+ ret = cap12xx_enable_interrupt (& config -> i2c , true);
280+ if (ret < 0 ) {
189281 LOG_ERR ("Could not configure interrupt" );
190- return r ;
282+ return ret ;
191283 }
192284 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 ) {
195287 LOG_ERR ("Could not disable repeated interrupts" );
196- return r ;
288+ return ret ;
197289 }
198290 LOG_DBG ("cap12xx enabled repeated interrupts" );
199291 } 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 ) {
202295 LOG_ERR ("Could not enable repeated interrupts" );
203- return r ;
296+ return ret ;
204297 }
205298 LOG_DBG ("cap12xx disabled repeated interrupts" );
206299 }
@@ -214,14 +307,22 @@ static int cap12xx_init(const struct device *dev)
214307 static struct gpio_dt_spec cap12xx_int_gpio_##index = \
215308 GPIO_DT_SPEC_INST_GET(index, int_gpios);)) \
216309 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); \
217314 static const struct cap12xx_config cap12xx_config_##index = { \
218315 .i2c = I2C_DT_SPEC_INST_GET(index), \
219316 .input_channels = DT_INST_PROP_LEN(index, input_codes), \
220317 .input_codes = cap12xx_input_codes_##index, \
221318 IF_ENABLED(DT_INST_NODE_HAS_PROP(index, int_gpios), ( \
222319 .int_gpio = &cap12xx_int_gpio_##index,)) \
223320 .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}; \
225326 static struct cap12xx_data cap12xx_data_##index; \
226327 DEVICE_DT_INST_DEFINE(index, cap12xx_init, NULL, &cap12xx_data_##index, \
227328 &cap12xx_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \
0 commit comments