1 /*
2  * Copyright (c) 2019 Vestas Wind Systems A/S
3  * Copyright (c) 2020 Innoseis BV
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 #include <zephyr/device.h>
8 #include <zephyr/devicetree.h>
9 #include <zephyr/drivers/adc.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/util.h>
15 
16 #define ADC_CONTEXT_USES_KERNEL_TIMER 1
17 #include "adc_context.h"
18 
19 #define DT_DRV_COMPAT ti_ads1119
20 
21 LOG_MODULE_REGISTER(ADS1119, CONFIG_ADC_LOG_LEVEL);
22 
23 
24 #define ADS1119_CONFIG_VREF(x) ((x) & BIT(0))
25 #define ADS1119_CONFIG_CM(x) ((x) & BIT(1))
26 #define ADS1119_CONFIG_DR(x) ((x) & (BIT_MASK(2) << 2))
27 #define ADS1119_CONFIG_GAIN(x) ((x) & BIT(4))
28 #define ADS1119_CONFIG_MUX(x) ((x) & (BIT_MASK(3) << 5))
29 
30 #define ADS1119_STATUS_MASK_ID BIT_MASK(7)
31 #define ADS1119_STATUS_MASK_READY BIT(7)
32 
33 #define ADS1119_REG_SHIFT 2
34 
35 #define ADS1119_RESOLUTION 16
36 #define ADS1119_REF_INTERNAL 2048
37 
38 enum ads1119_cmd {
39 	ADS1119_CMD_RESET       = 0x06,
40 	ADS1119_CMD_START_SYNC  = 0x08,
41 	ADS1119_CMD_POWER_DOWN  = 0x02,
42 	ADS1119_CMD_READ_DATA   = 0x10,
43 	ADS1119_CMD_READ_REG    = 0x20,
44 	ADS1119_CMD_WRITE_REG   = 0x40,
45 };
46 
47 enum ads1119_reg {
48 	ADS1119_REG_CONFIG      = 0 << ADS1119_REG_SHIFT,
49 	ADS1119_REG_STATUS      = 1 << ADS1119_REG_SHIFT,
50 };
51 
52 enum {
53 	ADS1119_CONFIG_VREF_INTERNAL    = 0,
54 	ADS1119_CONFIG_VREF_EXTERNAL    = 1,
55 };
56 
57 enum {
58 	ADS1119_CONFIG_MUX_DIFF_0_1     = 0,
59 	ADS1119_CONFIG_MUX_DIFF_2_3     = 1,
60 	ADS1119_CONFIG_MUX_DIFF_1_2     = 2,
61 	ADS1119_CONFIG_MUX_SINGLE_0     = 3,
62 	ADS1119_CONFIG_MUX_SINGLE_1     = 4,
63 	ADS1119_CONFIG_MUX_SINGLE_2     = 5,
64 	ADS1119_CONFIG_MUX_SINGLE_3     = 6,
65 	ADS1119_CONFIG_MUX_SHORTED      = 7,
66 };
67 
68 enum {
69 	ADS1119_CONFIG_DR_20            = 0,
70 	ADS1119_CONFIG_DR_90            = 1,
71 	ADS1119_CONFIG_DR_330           = 2,
72 	ADS1119_CONFIG_DR_1000          = 3,
73 	ADS1119_CONFIG_DR_DEFAULT       = ADS1119_CONFIG_DR_20,
74 };
75 
76 enum {
77 	ADS1119_CONFIG_GAIN_1   = 0,
78 	ADS1119_CONFIG_GAIN_4   = 1,
79 };
80 
81 enum {
82 	ADS1119_CONFIG_CM_SINGLE        = 0,
83 	ADS1119_CONFIG_CM_CONTINUOUS    = 1,
84 };
85 
86 struct ads1119_config {
87 	const struct i2c_dt_spec bus;
88 #if CONFIG_ADC_ASYNC
89 	k_thread_stack_t *stack;
90 #endif
91 };
92 
93 struct ads1119_data {
94 	struct adc_context ctx;
95 	k_timeout_t ready_time;
96 	struct k_sem acq_sem;
97 	int16_t *buffer;
98 	int16_t *buffer_ptr;
99 #if CONFIG_ADC_ASYNC
100 	struct k_thread thread;
101 #endif
102 	bool differential;
103 };
104 
ads1119_read_reg(const struct device * dev,enum ads1119_reg reg_addr,uint8_t * reg_val)105 static int ads1119_read_reg(const struct device *dev, enum ads1119_reg reg_addr, uint8_t *reg_val)
106 {
107 	const struct ads1119_config *config = dev->config;
108 
109 	return i2c_reg_read_byte_dt(&config->bus, ADS1119_CMD_READ_REG | reg_addr, reg_val);
110 }
111 
ads1119_write_reg(const struct device * dev,uint8_t reg)112 static int ads1119_write_reg(const struct device *dev, uint8_t reg)
113 {
114 	const struct ads1119_config *config = dev->config;
115 
116 	return i2c_reg_write_byte_dt(&config->bus, ADS1119_CMD_WRITE_REG, reg);
117 }
118 
ads1119_acq_time_to_dr(const struct device * dev,uint16_t acq_time)119 static inline int ads1119_acq_time_to_dr(const struct device *dev,
120 					 uint16_t acq_time)
121 {
122 	struct ads1119_data *data = dev->data;
123 	int odr = -EINVAL;
124 	uint16_t acq_value = ADC_ACQ_TIME_VALUE(acq_time);
125 	uint16_t ready_time_us = 0;
126 
127 	if (acq_time == ADC_ACQ_TIME_DEFAULT) {
128 		acq_value = ADS1119_CONFIG_DR_DEFAULT;
129 	} else if (ADC_ACQ_TIME_UNIT(acq_time) != ADC_ACQ_TIME_TICKS) {
130 		return -EINVAL;
131 	}
132 
133 	switch (acq_value) {
134 	case ADS1119_CONFIG_DR_20:
135 		odr = ADS1119_CONFIG_DR_20;
136 		ready_time_us = (1000*1000) / 20;
137 		break;
138 	case ADS1119_CONFIG_DR_90:
139 		odr = ADS1119_CONFIG_DR_90;
140 		ready_time_us = (1000*1000) / 90;
141 		break;
142 	case ADS1119_CONFIG_DR_330:
143 		odr = ADS1119_CONFIG_DR_330;
144 		ready_time_us = (1000*1000) / 330;
145 		break;
146 	case ADS1119_CONFIG_DR_1000:
147 		odr = ADS1119_CONFIG_DR_1000;
148 		ready_time_us = (1000*1000) / 1000;
149 		break;
150 	default:
151 		break;
152 	}
153 
154 	/* As per datasheet acquisition time is a bit longer wait a bit more
155 	 * to ensure data ready at first try
156 	 */
157 	data->ready_time = K_USEC(ready_time_us + 10);
158 
159 	return odr;
160 }
161 
ads1119_send_start_read(const struct device * dev)162 static int ads1119_send_start_read(const struct device *dev)
163 {
164 	const struct ads1119_config *config = dev->config;
165 	const uint8_t cmd = ADS1119_CMD_START_SYNC;
166 
167 	return i2c_write_dt(&config->bus, &cmd, sizeof(cmd));
168 }
169 
ads1119_wait_data_ready(const struct device * dev)170 static int ads1119_wait_data_ready(const struct device *dev)
171 {
172 	int rc;
173 	struct ads1119_data *data = dev->data;
174 
175 	k_sleep(data->ready_time);
176 	uint8_t status = 0;
177 
178 	rc = ads1119_read_reg(dev, ADS1119_REG_STATUS, &status);
179 	if (rc != 0) {
180 		return rc;
181 	}
182 
183 	while ((status & ADS1119_STATUS_MASK_READY) == 0) {
184 
185 		k_sleep(K_USEC(100));
186 		rc = ads1119_read_reg(dev, ADS1119_REG_STATUS, &status);
187 		if (rc != 0) {
188 			return rc;
189 		}
190 	}
191 
192 	return 0;
193 }
194 
ads1119_read_sample(const struct device * dev,uint16_t * buff)195 static int ads1119_read_sample(const struct device *dev, uint16_t *buff)
196 {
197 	int res;
198 	uint8_t rx_bytes[2];
199 	const struct ads1119_config *config = dev->config;
200 	const uint8_t cmd = ADS1119_CMD_READ_DATA;
201 
202 	res = i2c_write_read_dt(&config->bus,
203 			     &cmd, sizeof(cmd),
204 			     rx_bytes, sizeof(rx_bytes));
205 
206 	*buff = sys_get_be16(rx_bytes);
207 	return res;
208 }
209 
ads1119_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)210 static int ads1119_channel_setup(const struct device *dev,
211 				 const struct adc_channel_cfg *channel_cfg)
212 {
213 	struct ads1119_data *data = dev->data;
214 	uint8_t config = 0;
215 	int dr = 0;
216 
217 	if (channel_cfg->channel_id != 0) {
218 		return -EINVAL;
219 	}
220 
221 	switch (channel_cfg->reference) {
222 	case ADC_REF_EXTERNAL0:
223 		config |= ADS1119_CONFIG_VREF(ADS1119_CONFIG_VREF_EXTERNAL);
224 		break;
225 	case ADC_REF_INTERNAL:
226 		config |= ADS1119_CONFIG_VREF(ADS1119_CONFIG_VREF_INTERNAL);
227 		break;
228 	default:
229 		return -EINVAL;
230 	}
231 
232 	if (channel_cfg->differential) {
233 		if (channel_cfg->input_positive == 0 && channel_cfg->input_negative == 1) {
234 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_DIFF_0_1);
235 		} else if (channel_cfg->input_positive == 1 && channel_cfg->input_negative == 2) {
236 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_DIFF_1_2);
237 		} else if (channel_cfg->input_positive == 2 && channel_cfg->input_negative == 3) {
238 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_DIFF_2_3);
239 		} else {
240 			return -EINVAL;
241 		}
242 	} else {
243 		if (channel_cfg->input_positive == 0) {
244 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_SINGLE_0);
245 		} else if (channel_cfg->input_positive == 1) {
246 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_SINGLE_1);
247 		} else if (channel_cfg->input_positive == 2) {
248 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_SINGLE_2);
249 		} else if (channel_cfg->input_positive == 3) {
250 			config |= ADS1119_CONFIG_MUX(ADS1119_CONFIG_MUX_SINGLE_3);
251 		} else {
252 			return -EINVAL;
253 		}
254 	}
255 	data->differential = channel_cfg->differential;
256 
257 	dr = ads1119_acq_time_to_dr(dev, channel_cfg->acquisition_time);
258 	if (dr < 0) {
259 		return dr;
260 	}
261 
262 	config |= ADS1119_CONFIG_DR(dr);
263 
264 	switch (channel_cfg->gain) {
265 	case ADC_GAIN_1:
266 		config |= ADS1119_CONFIG_GAIN(ADS1119_CONFIG_GAIN_1);
267 		break;
268 	case ADC_GAIN_4:
269 		config |= ADS1119_CONFIG_GAIN(ADS1119_CONFIG_GAIN_4);
270 		break;
271 	default:
272 		return -EINVAL;
273 	}
274 
275 	config |= ADS1119_CONFIG_CM(ADS1119_CONFIG_CM_SINGLE); /* Only single shot supported */
276 
277 	return ads1119_write_reg(dev, config);
278 }
279 
280 
ads1119_validate_buffer_size(const struct adc_sequence * sequence)281 static int ads1119_validate_buffer_size(const struct adc_sequence *sequence)
282 {
283 	size_t needed = sizeof(int16_t);
284 
285 	if (sequence->options) {
286 		needed *= (1 + sequence->options->extra_samplings);
287 	}
288 
289 	if (sequence->buffer_size < needed) {
290 		return -ENOMEM;
291 	}
292 
293 	return 0;
294 }
295 
ads1119_validate_sequence(const struct device * dev,const struct adc_sequence * sequence)296 static int ads1119_validate_sequence(const struct device *dev, const struct adc_sequence *sequence)
297 {
298 	const struct ads1119_data *data = dev->data;
299 	const uint8_t resolution = data->differential ? ADS1119_RESOLUTION : ADS1119_RESOLUTION - 1;
300 
301 	if (sequence->resolution != resolution) {
302 		return -EINVAL;
303 	}
304 
305 	if (sequence->channels != BIT(0)) {
306 		return -EINVAL;
307 	}
308 
309 	if (sequence->oversampling) {
310 		return -EINVAL;
311 	}
312 
313 	return ads1119_validate_buffer_size(sequence);
314 }
315 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)316 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
317 					      bool repeat_sampling)
318 {
319 	struct ads1119_data *data = CONTAINER_OF(ctx,
320 						 struct ads1119_data,
321 						 ctx);
322 
323 	if (repeat_sampling) {
324 		data->buffer = data->buffer_ptr;
325 	}
326 }
327 
adc_context_start_sampling(struct adc_context * ctx)328 static void adc_context_start_sampling(struct adc_context *ctx)
329 {
330 	struct ads1119_data *data = CONTAINER_OF(ctx,
331 						 struct ads1119_data, ctx);
332 
333 	data->buffer_ptr = data->buffer;
334 	k_sem_give(&data->acq_sem);
335 }
336 
ads1119_adc_start_read(const struct device * dev,const struct adc_sequence * sequence,bool wait)337 static int ads1119_adc_start_read(const struct device *dev,
338 				  const struct adc_sequence *sequence,
339 				  bool wait)
340 {
341 	int rc;
342 	struct ads1119_data *data = dev->data;
343 
344 	rc = ads1119_validate_sequence(dev, sequence);
345 	if (rc != 0) {
346 		return rc;
347 	}
348 
349 	data->buffer = sequence->buffer;
350 
351 	adc_context_start_read(&data->ctx, sequence);
352 
353 	if (wait) {
354 		rc = adc_context_wait_for_completion(&data->ctx);
355 	}
356 	return rc;
357 }
358 
ads1119_adc_perform_read(const struct device * dev)359 static int ads1119_adc_perform_read(const struct device *dev)
360 {
361 	int rc;
362 	struct ads1119_data *data = dev->data;
363 
364 	k_sem_take(&data->acq_sem, K_FOREVER);
365 
366 	rc = ads1119_send_start_read(dev);
367 	if (rc) {
368 		adc_context_complete(&data->ctx, rc);
369 		return rc;
370 	}
371 
372 	rc = ads1119_wait_data_ready(dev);
373 	if (rc != 0) {
374 		adc_context_complete(&data->ctx, rc);
375 		return rc;
376 	}
377 
378 	rc = ads1119_read_sample(dev, data->buffer);
379 	if (rc != 0) {
380 		adc_context_complete(&data->ctx, rc);
381 		return rc;
382 	}
383 	data->buffer++;
384 
385 	adc_context_on_sampling_done(&data->ctx, dev);
386 
387 	return rc;
388 }
389 
390 #if CONFIG_ADC_ASYNC
ads1119_adc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)391 static int ads1119_adc_read_async(const struct device *dev,
392 				  const struct adc_sequence *sequence,
393 				  struct k_poll_signal *async)
394 {
395 	int rc;
396 	struct ads1119_data *data = dev->data;
397 
398 	adc_context_lock(&data->ctx, true, async);
399 	rc = ads1119_adc_start_read(dev, sequence, true);
400 	adc_context_release(&data->ctx, rc);
401 
402 	return rc;
403 }
ads1119_read(const struct device * dev,const struct adc_sequence * sequence)404 static int ads1119_read(const struct device *dev,
405 			const struct adc_sequence *sequence)
406 {
407 	int rc;
408 	struct ads1119_data *data = dev->data;
409 
410 	adc_context_lock(&data->ctx, false, NULL);
411 	rc = ads1119_adc_start_read(dev, sequence, true);
412 	adc_context_release(&data->ctx, rc);
413 
414 	return rc;
415 }
416 #else
ads1119_read(const struct device * dev,const struct adc_sequence * sequence)417 static int ads1119_read(const struct device *dev,
418 			const struct adc_sequence *sequence)
419 {
420 	int rc;
421 	struct ads1119_data *data = dev->data;
422 
423 	adc_context_lock(&data->ctx, false, NULL);
424 	rc = ads1119_adc_start_read(dev, sequence, false);
425 
426 	while (rc == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) {
427 		rc = ads1119_adc_perform_read(dev);
428 	}
429 
430 	adc_context_release(&data->ctx, rc);
431 	return rc;
432 }
433 #endif
434 
435 #if CONFIG_ADC_ASYNC
ads1119_acquisition_thread(void * p1,void * p2,void * p3)436 static void ads1119_acquisition_thread(void *p1, void *p2, void *p3)
437 {
438 	ARG_UNUSED(p2);
439 	ARG_UNUSED(p3);
440 
441 	const struct device *dev = p1;
442 	while (true) {
443 		ads1119_adc_perform_read(dev);
444 	}
445 }
446 #endif
447 
ads1119_init(const struct device * dev)448 static int ads1119_init(const struct device *dev)
449 {
450 	int rc;
451 	uint8_t status;
452 	const struct ads1119_config *config = dev->config;
453 	struct ads1119_data *data = dev->data;
454 
455 	adc_context_init(&data->ctx);
456 
457 	k_sem_init(&data->acq_sem, 0, 1);
458 
459 	if (!device_is_ready(config->bus.bus)) {
460 		return -ENODEV;
461 	}
462 
463 	rc = ads1119_read_reg(dev, ADS1119_REG_STATUS, &status);
464 	if (rc) {
465 		LOG_ERR("Could not get %s status", dev->name);
466 		return rc;
467 	}
468 
469 #if CONFIG_ADC_ASYNC
470 	k_tid_t tid =
471 		k_thread_create(&data->thread, config->stack,
472 				CONFIG_ADC_ADS1119_ACQUISITION_THREAD_STACK_SIZE,
473 				ads1119_acquisition_thread,
474 				(void *)dev, NULL, NULL,
475 				CONFIG_ADC_ADS1119_ASYNC_THREAD_INIT_PRIO,
476 				0, K_NO_WAIT);
477 	k_thread_name_set(tid, "adc_ads1119");
478 #endif
479 	adc_context_unlock_unconditionally(&data->ctx);
480 
481 	return rc;
482 }
483 
484 static const struct adc_driver_api api = {
485 	.channel_setup = ads1119_channel_setup,
486 	.read = ads1119_read,
487 	.ref_internal = ADS1119_REF_INTERNAL,
488 #ifdef CONFIG_ADC_ASYNC
489 	.read_async = ads1119_adc_read_async,
490 #endif
491 };
492 #define ADC_ADS1119_INST_DEFINE(n)							   \
493 	IF_ENABLED(CONFIG_ADC_ASYNC,							   \
494 		   (static								   \
495 		   K_KERNEL_STACK_DEFINE(thread_stack_##n,				   \
496 				      CONFIG_ADC_ADS1119_ACQUISITION_THREAD_STACK_SIZE);)) \
497 	static const struct ads1119_config config_##n = {				   \
498 		.bus = I2C_DT_SPEC_GET(DT_DRV_INST(n)),					   \
499 		IF_ENABLED(CONFIG_ADC_ASYNC, (.stack = thread_stack_##n))		   \
500 	};										   \
501 	static struct ads1119_data data_##n;						   \
502 	DEVICE_DT_INST_DEFINE(n, ads1119_init,						   \
503 		      NULL, &data_##n, &config_##n,					   \
504 		      POST_KERNEL, CONFIG_ADC_INIT_PRIORITY,				   \
505 		      &api);
506 
507 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS1119_INST_DEFINE);
508