1 /*
2 * Copyright (c) 2023 Caspar Friedrich <c.s.w.friedrich@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8
9 #include <zephyr/devicetree.h>
10 #include <zephyr/drivers/adc.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/sys/byteorder.h>
15
16 #define ADC_CONTEXT_USES_KERNEL_TIMER
17
18 /*
19 * This requires to be included _after_ `#define ADC_CONTEXT_USES_KERNEL_TIMER`
20 */
21 #include "adc_context.h"
22
23 LOG_MODULE_REGISTER(tla2021, CONFIG_ADC_LOG_LEVEL);
24
25 #define ACQ_THREAD_PRIORITY CONFIG_ADC_TLA202X_ACQUISITION_THREAD_PRIORITY
26 #define ACQ_THREAD_STACK_SIZE CONFIG_ADC_TLA202X_ACQUISITION_THREAD_STACK_SIZE
27
28 #define MAX_CHANNELS 4
29 #define ADC_RESOLUTION 12
30
31 #define WAKEUP_TIME_US 25
32 #define CONVERSION_TIME_US 625 /* DR is 1600 SPS */
33
34 /*
35 * Conversion Data Register (RP = 00h) [reset = 0000h]
36 */
37 #define REG_DATA 0x00
38 #define REG_DATA_pos 4
39
40 /*
41 * Configuration Register (RP = 01h) [reset = 8583h]
42 */
43 #define REG_CONFIG 0x01
44 #define REG_CONFIG_DEFAULT 0x8583
45 #define REG_CONFIG_DR_pos 5
46 #define REG_CONFIG_MODE_pos 8
47 #define REG_CONFIG_PGA_pos 9 /* TLA2024 Only */
48 #define REG_CONFIG_PGA_msk GENMASK(11, 9) /* TLA2022 and TLA2024 Only */
49 #define REG_CONFIG_MUX_pos 12 /* TLA2024 Only */
50 #define REG_CONFIG_MUX_msk GENMASK(14, 12) /* TLA2024 Only */
51 #define REG_CONFIG_OS_pos 15
52 #define REG_CONFIG_OS_msk (BIT_MASK(1) << REG_CONFIG_OS_pos)
53
54 enum {
55 MUX_DIFF_0_1 = 0,
56 MUX_DIFF_0_3 = 1,
57 MUX_DIFF_1_3 = 2,
58 MUX_DIFF_2_3 = 3,
59 MUX_SINGLE_0 = 4,
60 MUX_SINGLE_1 = 5,
61 MUX_SINGLE_2 = 6,
62 MUX_SINGLE_3 = 7,
63 };
64
65 enum {
66 /* Gain 1/3 */
67 PGA_6144 = 0,
68 /* Gain 1/2 */
69 PGA_4096 = 1,
70 /* Gain 1 (Default) */
71 PGA_2048 = 2,
72 /* Gain 2 */
73 PGA_1024 = 3,
74 /* Gain 4 */
75 PGA_512 = 4,
76 /* Gain 8 */
77 PGA_256 = 5
78 };
79
80 typedef int16_t tla202x_reg_data_t;
81 typedef uint16_t tla202x_reg_config_t;
82
83 struct tla202x_config {
84 const struct i2c_dt_spec bus;
85 bool has_pga;
86 uint8_t channel_count;
87 };
88
89 struct tla202x_data {
90 const struct device *dev;
91 struct adc_context ctx;
92 #ifdef CONFIG_ADC_ASYNC
93 struct k_sem acq_lock;
94 #endif
95 tla202x_reg_data_t *buffer;
96 tla202x_reg_data_t *repeat_buffer;
97 uint8_t channels;
98
99 /*
100 * Shadow register
101 */
102 tla202x_reg_config_t reg_config[MAX_CHANNELS];
103 };
104
tla202x_read_register(const struct device * dev,uint8_t reg,uint16_t * value)105 static int tla202x_read_register(const struct device *dev, uint8_t reg, uint16_t *value)
106 {
107 int ret;
108
109 const struct tla202x_config *config = dev->config;
110 uint8_t tmp[2];
111
112 ret = i2c_write_read_dt(&config->bus, ®, sizeof(reg), tmp, sizeof(tmp));
113 if (ret) {
114 return ret;
115 }
116
117 *value = sys_get_be16(tmp);
118
119 return 0;
120 }
121
tla202x_write_register(const struct device * dev,uint8_t reg,uint16_t value)122 static int tla202x_write_register(const struct device *dev, uint8_t reg, uint16_t value)
123 {
124 int ret;
125
126 const struct tla202x_config *config = dev->config;
127 uint8_t tmp[3] = {reg};
128
129 sys_put_be16(value, &tmp[1]);
130
131 ret = i2c_write_dt(&config->bus, tmp, sizeof(tmp));
132 if (ret) {
133 return ret;
134 }
135
136 return 0;
137 }
138
tla202x_channel_setup(const struct device * dev,const struct adc_channel_cfg * cfg)139 static int tla202x_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg)
140 {
141 const struct tla202x_config *config = dev->config;
142 struct tla202x_data *data = dev->data;
143
144 if (cfg->channel_id >= config->channel_count) {
145 LOG_ERR("invalid channel selection %u", cfg->channel_id);
146 return -EINVAL;
147 }
148 tla202x_reg_config_t *reg_config = &data->reg_config[cfg->channel_id];
149
150 if (config->has_pga) {
151 *reg_config &= ~REG_CONFIG_PGA_msk;
152 switch (cfg->gain) {
153 case ADC_GAIN_1_3:
154 *reg_config |= PGA_6144 << REG_CONFIG_PGA_pos;
155 break;
156 case ADC_GAIN_1_2:
157 *reg_config |= PGA_4096 << REG_CONFIG_PGA_pos;
158 break;
159 case ADC_GAIN_1:
160 *reg_config |= PGA_2048 << REG_CONFIG_PGA_pos;
161 break;
162 case ADC_GAIN_2:
163 *reg_config |= PGA_1024 << REG_CONFIG_PGA_pos;
164 break;
165 case ADC_GAIN_4:
166 *reg_config |= PGA_512 << REG_CONFIG_PGA_pos;
167 break;
168 case ADC_GAIN_8:
169 *reg_config |= PGA_256 << REG_CONFIG_PGA_pos;
170 break;
171 default:
172 LOG_ERR("Invalid gain");
173 return -EINVAL;
174 }
175 } else {
176 if (cfg->gain != ADC_GAIN_1) {
177 LOG_ERR("Invalid gain");
178 return -EINVAL;
179 }
180 }
181
182 /*
183 * Only adc with more than one channels has a mux
184 */
185 #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
186 if (config->channel_count > 1) {
187 *reg_config &= ~REG_CONFIG_MUX_msk;
188
189 if (cfg->differential) {
190 if (cfg->input_positive == 0 && cfg->input_negative == 1) {
191 *reg_config |= MUX_DIFF_0_1 << REG_CONFIG_MUX_pos;
192 } else if (cfg->input_positive == 0 && cfg->input_negative == 3) {
193 *reg_config |= MUX_DIFF_0_3 << REG_CONFIG_MUX_pos;
194 } else if (cfg->input_positive == 1 && cfg->input_negative == 3) {
195 *reg_config |= MUX_DIFF_1_3 << REG_CONFIG_MUX_pos;
196 } else if (cfg->input_positive == 2 && cfg->input_negative == 3) {
197 *reg_config |= MUX_DIFF_2_3 << REG_CONFIG_MUX_pos;
198 } else {
199 LOG_ERR("Invalid channel config");
200 return -EINVAL;
201 }
202 } else {
203 if (cfg->input_positive == 0) {
204 *reg_config |= MUX_SINGLE_0 << REG_CONFIG_MUX_pos;
205 } else if (cfg->input_positive == 1) {
206 *reg_config |= MUX_SINGLE_1 << REG_CONFIG_MUX_pos;
207 } else if (cfg->input_positive == 2) {
208 *reg_config |= MUX_SINGLE_2 << REG_CONFIG_MUX_pos;
209 } else if (cfg->input_positive == 3) {
210 *reg_config |= MUX_SINGLE_3 << REG_CONFIG_MUX_pos;
211 } else {
212 LOG_ERR("Invalid channel config");
213 return -EINVAL;
214 }
215 }
216 }
217 #endif
218
219 if (cfg->reference != ADC_REF_INTERNAL) {
220 LOG_ERR("Invalid reference");
221 return -EINVAL;
222 }
223
224 if (cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
225 LOG_ERR("Invalid acquisition time");
226 return -EINVAL;
227 }
228
229 return 0;
230 }
231
tla202x_start_read(const struct device * dev,const struct adc_sequence * seq)232 static int tla202x_start_read(const struct device *dev, const struct adc_sequence *seq)
233 {
234 struct tla202x_data *data = dev->data;
235 const struct tla202x_config *config = dev->config;
236
237 const size_t num_extra_samples = seq->options ? seq->options->extra_samplings : 0;
238 const size_t num_samples = (1 + num_extra_samples) * POPCOUNT(seq->channels);
239
240 if (find_msb_set(seq->channels) > config->channel_count) {
241 LOG_ERR("Selected channel(s) not supported: %x", seq->channels);
242 return -EINVAL;
243 }
244
245 if (seq->resolution != ADC_RESOLUTION) {
246 LOG_ERR("Selected resolution not supported: %d", seq->resolution);
247 return -EINVAL;
248 }
249
250 if (seq->oversampling) {
251 LOG_ERR("Oversampling is not supported");
252 return -EINVAL;
253 }
254
255 if (seq->calibrate) {
256 LOG_ERR("Calibration is not supported");
257 return -EINVAL;
258 }
259
260 if (!seq->buffer) {
261 LOG_ERR("Buffer invalid");
262 return -EINVAL;
263 }
264
265 if (seq->buffer_size < (num_samples * sizeof(tla202x_reg_data_t))) {
266 LOG_ERR("buffer size too small");
267 return -EINVAL;
268 }
269
270 data->buffer = seq->buffer;
271
272 adc_context_start_read(&data->ctx, seq);
273
274 return adc_context_wait_for_completion(&data->ctx);
275 }
276
tla202x_read_async(const struct device * dev,const struct adc_sequence * seq,struct k_poll_signal * async)277 static int tla202x_read_async(const struct device *dev, const struct adc_sequence *seq,
278 struct k_poll_signal *async)
279 {
280 int ret;
281
282 struct tla202x_data *data = dev->data;
283
284 adc_context_lock(&data->ctx, async ? true : false, async);
285 ret = tla202x_start_read(dev, seq);
286 adc_context_release(&data->ctx, ret);
287
288 return ret;
289 }
290
tla202x_read(const struct device * dev,const struct adc_sequence * seq)291 static int tla202x_read(const struct device *dev, const struct adc_sequence *seq)
292 {
293 return tla202x_read_async(dev, seq, NULL);
294 }
295
tla202x_perform_read(const struct device * dev)296 static void tla202x_perform_read(const struct device *dev)
297 {
298 struct tla202x_data *data = dev->data;
299 tla202x_reg_config_t reg;
300 tla202x_reg_data_t res;
301 uint8_t ch;
302 int ret;
303
304 while (data->channels) {
305 /*
306 * Select correct channel
307 */
308 ch = find_lsb_set(data->channels) - 1;
309 reg = data->reg_config[ch];
310 LOG_DBG("reg: %x", reg);
311
312 /*
313 * Start single-shot conversion
314 */
315 WRITE_BIT(reg, REG_CONFIG_MODE_pos, 1);
316 WRITE_BIT(reg, REG_CONFIG_OS_pos, 1);
317 ret = tla202x_write_register(dev, REG_CONFIG, reg);
318 if (ret) {
319 LOG_WRN("Failed to start conversion");
320 }
321
322 /*
323 * Wait until sampling is done
324 */
325 k_usleep(WAKEUP_TIME_US + CONVERSION_TIME_US);
326 do {
327 k_yield();
328 ret = tla202x_read_register(dev, REG_CONFIG, ®);
329 if (ret < 0) {
330 adc_context_complete(&data->ctx, ret);
331 }
332 } while (!(reg & REG_CONFIG_OS_msk));
333
334 /*
335 * Read result
336 */
337 ret = tla202x_read_register(dev, REG_DATA, &res);
338 if (ret) {
339 adc_context_complete(&data->ctx, ret);
340 }
341
342 /*
343 * ADC data is stored in the upper 12 bits
344 */
345 res >>= REG_DATA_pos;
346 *data->buffer++ = res;
347
348 LOG_DBG("read channel %d, result = %d", ch, res);
349 WRITE_BIT(data->channels, ch, 0);
350 }
351
352 adc_context_on_sampling_done(&data->ctx, data->dev);
353 }
354
adc_context_start_sampling(struct adc_context * ctx)355 static void adc_context_start_sampling(struct adc_context *ctx)
356 {
357 struct tla202x_data *data = CONTAINER_OF(ctx, struct tla202x_data, ctx);
358 const struct device *dev = data->dev;
359
360 data->channels = ctx->sequence.channels;
361 data->repeat_buffer = data->buffer;
362
363 #ifdef CONFIG_ADC_ASYNC
364 k_sem_give(&data->acq_lock);
365 #else
366 tla202x_perform_read(dev);
367 #endif
368 }
369
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)370 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
371 {
372 struct tla202x_data *data = CONTAINER_OF(ctx, struct tla202x_data, ctx);
373
374 if (repeat_sampling) {
375 data->buffer = data->repeat_buffer;
376 }
377 }
378
379 #ifdef CONFIG_ADC_ASYNC
tla202x_acq_thread_fn(void * p1,void * p2,void * p3)380 static void tla202x_acq_thread_fn(void *p1, void *p2, void *p3)
381 {
382 const struct device *dev = p1;
383 struct tla202x_data *data = dev->data;
384
385 while (true) {
386 k_sem_take(&data->acq_lock, K_FOREVER);
387
388 tla202x_perform_read(dev);
389 }
390 }
391 #endif
392
tla202x_init(const struct device * dev)393 static int tla202x_init(const struct device *dev)
394 {
395 int ret;
396
397 const struct tla202x_config *config = dev->config;
398 struct tla202x_data *data = dev->data;
399
400 if (!i2c_is_ready_dt(&config->bus)) {
401 LOG_ERR("Bus not ready");
402 return -EINVAL;
403 }
404
405 for (uint8_t ch = 0; ch < MAX_CHANNELS; ch++) {
406 data->reg_config[ch] = REG_CONFIG_DEFAULT;
407 }
408
409 ret = tla202x_write_register(dev, REG_CONFIG, data->reg_config[0]);
410 if (ret) {
411 LOG_ERR("Device reset failed: %d", ret);
412 return ret;
413 }
414
415 adc_context_unlock_unconditionally(&data->ctx);
416
417 return 0;
418 }
419
420 static DEVICE_API(adc, tla202x_driver_api) = {
421 .channel_setup = tla202x_channel_setup,
422 .read = tla202x_read,
423 .ref_internal = 4096,
424 #ifdef CONFIG_ADC_ASYNC
425 .read_async = tla202x_read_async,
426 #endif
427 };
428
429 #define TLA202X_THREAD_INIT(t, n) \
430 K_THREAD_DEFINE(adc_##t##_##n##_thread, ACQ_THREAD_STACK_SIZE, tla202x_acq_thread_fn, \
431 DEVICE_DT_INST_GET(n), NULL, NULL, ACQ_THREAD_PRIORITY, 0, 0);
432
433 #define TLA202X_INIT(n, t, pga, channels) \
434 IF_ENABLED(CONFIG_ADC_ASYNC, (TLA202X_THREAD_INIT(t, n))) \
435 static const struct tla202x_config inst_##t##_##n##_config = { \
436 .bus = I2C_DT_SPEC_INST_GET(n), \
437 .has_pga = pga, \
438 .channel_count = channels, \
439 }; \
440 static struct tla202x_data inst_##t##_##n##_data = { \
441 .dev = DEVICE_DT_INST_GET(n), \
442 ADC_CONTEXT_INIT_LOCK(inst_##t##_##n##_data, ctx), \
443 ADC_CONTEXT_INIT_TIMER(inst_##t##_##n##_data, ctx), \
444 ADC_CONTEXT_INIT_SYNC(inst_##t##_##n##_data, ctx), \
445 IF_ENABLED(CONFIG_ADC_ASYNC, \
446 (.acq_lock = Z_SEM_INITIALIZER(inst_##t##_##n##_data.acq_lock, 0, 1),)) \
447 }; \
448 DEVICE_DT_INST_DEFINE(n, &tla202x_init, NULL, &inst_##t##_##n##_data, \
449 &inst_##t##_##n##_config, POST_KERNEL, \
450 CONFIG_ADC_TLA202X_INIT_PRIORITY, &tla202x_driver_api);
451
452 #define DT_DRV_COMPAT ti_tla2021
453 #define ADC_TLA2021_CHANNELS 1
454 #define ADC_TLA2021_PGA false
455 DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2021, ADC_TLA2021_PGA, ADC_TLA2021_CHANNELS)
456 #undef DT_DRV_COMPAT
457 #define DT_DRV_COMPAT ti_tla2022
458 #define ADC_TLA2022_CHANNELS 1
459 #define ADC_TLA2022_PGA true
460 DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2022, ADC_TLA2022_PGA, ADC_TLA2022_CHANNELS)
461 #undef DT_DRV_COMPAT
462 #define DT_DRV_COMPAT ti_tla2024
463 #define ADC_TLA2024_CHANNELS 4
464 #define ADC_TLA2024_PGA true
465 DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2024, ADC_TLA2024_PGA, ADC_TLA2024_CHANNELS)
466 #undef DT_DRV_COMPAT
467
468 BUILD_ASSERT(CONFIG_I2C_INIT_PRIORITY < CONFIG_ADC_TLA202X_INIT_PRIORITY);
469