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, &reg, 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, &reg);
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