1 /*
2  * Copyright (c) 2022 Telink Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT telink_b91_adc
8 
9 /* Local driver headers */
10 #define ADC_CONTEXT_USES_KERNEL_TIMER
11 #include "adc_context.h"
12 
13 /* Zephyr Device Tree headers */
14 #include <zephyr/dt-bindings/adc/b91-adc.h>
15 
16 /* Zephyr Logging headers */
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(adc_b91, CONFIG_ADC_LOG_LEVEL);
19 
20 /* Telink HAL headers */
21 #include <adc.h>
22 
23 /* ADC B91 defines */
24 #define SIGN_BIT_POSITION          (13)
25 #define AREG_ADC_DATA_STATUS       (0xf6)
26 #define ADC_DATA_READY             BIT(0)
27 
28 /* B91 ADC driver data */
29 struct b91_adc_data {
30 	struct adc_context ctx;
31 	int16_t *buffer;
32 	int16_t *repeat_buffer;
33 	uint8_t differential;
34 	uint8_t resolution_divider;
35 	struct k_sem acq_sem;
36 	struct k_thread thread;
37 
38 	K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_B91_ACQUISITION_THREAD_STACK_SIZE);
39 };
40 
41 struct b91_adc_cfg {
42 	uint32_t sample_freq;
43 	uint16_t vref_internal_mv;
44 };
45 
46 /* Validate ADC data buffer size */
adc_b91_validate_buffer_size(const struct adc_sequence * sequence)47 static int adc_b91_validate_buffer_size(const struct adc_sequence *sequence)
48 {
49 	size_t needed = sizeof(int16_t);
50 
51 	if (sequence->options) {
52 		needed *= (1 + sequence->options->extra_samplings);
53 	}
54 
55 	if (sequence->buffer_size < needed) {
56 		return -ENOMEM;
57 	}
58 
59 	return 0;
60 }
61 
62 /* Validate ADC read API input parameters */
adc_b91_validate_sequence(const struct adc_sequence * sequence)63 static int adc_b91_validate_sequence(const struct adc_sequence *sequence)
64 {
65 	int status;
66 
67 	if (sequence->channels != BIT(0)) {
68 		LOG_ERR("Only channel 0 is supported.");
69 		return -ENOTSUP;
70 	}
71 
72 	if (sequence->oversampling) {
73 		LOG_ERR("Oversampling is not supported.");
74 		return -ENOTSUP;
75 	}
76 
77 	status = adc_b91_validate_buffer_size(sequence);
78 	if (status) {
79 		LOG_ERR("Buffer size too small.");
80 		return status;
81 	}
82 
83 	return 0;
84 }
85 
86 /* Convert dts pin to B91 SDK pin */
adc_b91_get_pin(uint8_t dt_pin)87 static adc_input_pin_def_e adc_b91_get_pin(uint8_t dt_pin)
88 {
89 	adc_input_pin_def_e adc_pin;
90 
91 	switch (dt_pin) {
92 	case DT_ADC_GPIO_PB0:
93 		adc_pin = ADC_GPIO_PB0;
94 		break;
95 	case DT_ADC_GPIO_PB1:
96 		adc_pin = ADC_GPIO_PB1;
97 		break;
98 	case DT_ADC_GPIO_PB2:
99 		adc_pin = ADC_GPIO_PB2;
100 		break;
101 	case DT_ADC_GPIO_PB3:
102 		adc_pin = ADC_GPIO_PB3;
103 		break;
104 	case DT_ADC_GPIO_PB4:
105 		adc_pin = ADC_GPIO_PB4;
106 		break;
107 	case DT_ADC_GPIO_PB5:
108 		adc_pin = ADC_GPIO_PB5;
109 		break;
110 	case DT_ADC_GPIO_PB6:
111 		adc_pin = ADC_GPIO_PB6;
112 		break;
113 	case DT_ADC_GPIO_PB7:
114 		adc_pin = ADC_GPIO_PB7;
115 		break;
116 	case DT_ADC_GPIO_PD0:
117 		adc_pin = ADC_GPIO_PD0;
118 		break;
119 	case DT_ADC_GPIO_PD1:
120 		adc_pin = ADC_GPIO_PD1;
121 		break;
122 	case DT_ADC_VBAT:
123 		adc_pin = ADC_VBAT;
124 		break;
125 
126 	default:
127 		adc_pin = NOINPUTN;
128 		break;
129 	}
130 
131 	return adc_pin;
132 }
133 
134 /* Get ADC value */
adc_b91_get_code(void)135 static signed short adc_b91_get_code(void)
136 {
137 	signed short adc_code;
138 
139 	analog_write_reg8(areg_adc_data_sample_control,
140 			  analog_read_reg8(areg_adc_data_sample_control) | FLD_NOT_SAMPLE_ADC_DATA);
141 
142 	adc_code = analog_read_reg16(areg_adc_misc_l);
143 
144 	analog_write_reg8(areg_adc_data_sample_control,
145 		analog_read_reg8(areg_adc_data_sample_control) & (~FLD_NOT_SAMPLE_ADC_DATA));
146 
147 	return adc_code;
148 }
149 
150 /* ADC Context API implementation: start sampling */
adc_context_start_sampling(struct adc_context * ctx)151 static void adc_context_start_sampling(struct adc_context *ctx)
152 {
153 	struct b91_adc_data *data =
154 		CONTAINER_OF(ctx, struct b91_adc_data, ctx);
155 
156 	data->repeat_buffer = data->buffer;
157 
158 	adc_power_on();
159 
160 	k_sem_give(&data->acq_sem);
161 }
162 
163 /* ADC Context API implementation: buffer pointer */
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)164 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
165 {
166 	struct b91_adc_data *data =
167 		CONTAINER_OF(ctx, struct b91_adc_data, ctx);
168 
169 	if (repeat_sampling) {
170 		data->buffer = data->repeat_buffer;
171 	}
172 }
173 
174 /* Start ADC measurements */
adc_b91_adc_start_read(const struct device * dev,const struct adc_sequence * sequence)175 static int adc_b91_adc_start_read(const struct device *dev, const struct adc_sequence *sequence)
176 {
177 	int status;
178 	struct b91_adc_data *data = dev->data;
179 
180 	/* Validate input parameters */
181 	status = adc_b91_validate_sequence(sequence);
182 	if (status != 0) {
183 		return status;
184 	}
185 
186 	/* Set resolution */
187 	switch (sequence->resolution) {
188 	case 14:
189 		adc_set_resolution(ADC_RES14);
190 		data->resolution_divider = 1;
191 		break;
192 	case 12:
193 		adc_set_resolution(ADC_RES12);
194 		data->resolution_divider = 4;
195 		break;
196 	case 10:
197 		adc_set_resolution(ADC_RES10);
198 		data->resolution_divider = 16;
199 		break;
200 	case 8:
201 		adc_set_resolution(ADC_RES8);
202 		data->resolution_divider = 64;
203 		break;
204 	default:
205 		LOG_ERR("Selected ADC resolution is not supported.");
206 		return -EINVAL;
207 	}
208 
209 	/* Save buffer */
210 	data->buffer = sequence->buffer;
211 
212 	/* Start ADC conversion */
213 	adc_context_start_read(&data->ctx, sequence);
214 
215 	return adc_context_wait_for_completion(&data->ctx);
216 }
217 
218 /* Main ADC Acquisition thread */
adc_b91_acquisition_thread(void * p1,void * p2,void * p3)219 static void adc_b91_acquisition_thread(void *p1, void *p2, void *p3)
220 {
221 	ARG_UNUSED(p2);
222 	ARG_UNUSED(p3);
223 
224 	const struct device *dev = p1;
225 	int16_t adc_code;
226 	struct b91_adc_data *data = dev->data;
227 
228 	while (true) {
229 		/* Wait for Acquisition semaphore */
230 		k_sem_take(&data->acq_sem, K_FOREVER);
231 
232 		/* Wait for ADC data ready */
233 		while ((analog_read_reg8(AREG_ADC_DATA_STATUS) & ADC_DATA_READY)
234 				!= ADC_DATA_READY) {
235 		}
236 
237 		/* Perform read */
238 		adc_code = (adc_b91_get_code() / data->resolution_divider);
239 		if (!data->differential) {
240 			/* Sign bit is not used in case of single-ended configuration */
241 			adc_code = adc_code * 2;
242 
243 			/* Do not return negative value for single-ended configuration */
244 			if (adc_code < 0) {
245 				adc_code = 0;
246 			}
247 		}
248 		*data->buffer++ = adc_code;
249 
250 		/* Power off ADC */
251 		adc_power_off();
252 
253 		/* Release ADC context */
254 		adc_context_on_sampling_done(&data->ctx, dev);
255 	}
256 }
257 
258 /* ADC Driver initialization */
adc_b91_init(const struct device * dev)259 static int adc_b91_init(const struct device *dev)
260 {
261 	struct b91_adc_data *data = dev->data;
262 
263 	k_sem_init(&data->acq_sem, 0, 1);
264 
265 	k_thread_create(&data->thread, data->stack,
266 			CONFIG_ADC_B91_ACQUISITION_THREAD_STACK_SIZE,
267 			adc_b91_acquisition_thread,
268 			(void *)dev, NULL, NULL,
269 			CONFIG_ADC_B91_ACQUISITION_THREAD_PRIO,
270 			0, K_NO_WAIT);
271 
272 	adc_context_unlock_unconditionally(&data->ctx);
273 
274 	return 0;
275 }
276 
277 /* API implementation: channel_setup */
adc_b91_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)278 static int adc_b91_channel_setup(const struct device *dev,
279 				 const struct adc_channel_cfg *channel_cfg)
280 {
281 	adc_ref_vol_e vref_internal_mv;
282 	adc_sample_freq_e sample_freq;
283 	adc_pre_scale_e pre_scale;
284 	adc_sample_cycle_e sample_cycl;
285 	adc_input_pin_def_e input_positive;
286 	adc_input_pin_def_e input_negative;
287 	struct b91_adc_data *data = dev->data;
288 	const struct b91_adc_cfg *config = dev->config;
289 
290 	/* Check channel ID */
291 	if (channel_cfg->channel_id > 0) {
292 		LOG_ERR("Only channel 0 is supported.");
293 		return -EINVAL;
294 	}
295 
296 	/* Check reference */
297 	if (channel_cfg->reference != ADC_REF_INTERNAL) {
298 		LOG_ERR("Selected ADC reference is not supported.");
299 		return -EINVAL;
300 	}
301 
302 	/* Check internal reference */
303 	switch (config->vref_internal_mv) {
304 	case 900:
305 		vref_internal_mv = ADC_VREF_0P9V;
306 		break;
307 	case 1200:
308 		vref_internal_mv = ADC_VREF_1P2V;
309 		break;
310 	default:
311 		LOG_ERR("Selected reference voltage is not supported.");
312 		return -EINVAL;
313 	}
314 
315 	/* Check sample frequency */
316 	switch (config->sample_freq) {
317 	case 23000:
318 		sample_freq = ADC_SAMPLE_FREQ_23K;
319 		break;
320 	case 48000:
321 		sample_freq = ADC_SAMPLE_FREQ_48K;
322 		break;
323 	case 96000:
324 		sample_freq = ADC_SAMPLE_FREQ_96K;
325 		break;
326 	default:
327 		LOG_ERR("Selected sample frequency is not supported.");
328 		return -EINVAL;
329 	}
330 
331 	/* Check gain */
332 	switch (channel_cfg->gain) {
333 	case ADC_GAIN_1:
334 		pre_scale = ADC_PRESCALE_1;
335 		break;
336 	case ADC_GAIN_1_4:
337 		pre_scale = ADC_PRESCALE_1F4;
338 		break;
339 	default:
340 		LOG_ERR("Selected ADC gain is not supported.");
341 		return -EINVAL;
342 	}
343 
344 	/* Check acquisition time */
345 	switch (channel_cfg->acquisition_time) {
346 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 3):
347 		sample_cycl = ADC_SAMPLE_CYC_3;
348 		break;
349 	case ADC_ACQ_TIME_DEFAULT:
350 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 6):
351 		sample_cycl = ADC_SAMPLE_CYC_6;
352 		break;
353 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 9):
354 		sample_cycl = ADC_SAMPLE_CYC_9;
355 		break;
356 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 12):
357 		sample_cycl = ADC_SAMPLE_CYC_12;
358 		break;
359 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 18):
360 		sample_cycl = ADC_SAMPLE_CYC_18;
361 		break;
362 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 24):
363 		sample_cycl = ADC_SAMPLE_CYC_24;
364 		break;
365 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 36):
366 		sample_cycl = ADC_SAMPLE_CYC_36;
367 		break;
368 	case ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 48):
369 		sample_cycl = ADC_SAMPLE_CYC_48;
370 		break;
371 
372 	default:
373 		LOG_ERR("Selected ADC acquisition time is not supported.");
374 		return -EINVAL;
375 	}
376 
377 	/* Check for valid pins configuration */
378 	input_positive = adc_b91_get_pin(channel_cfg->input_positive);
379 	input_negative = adc_b91_get_pin(channel_cfg->input_negative);
380 	if ((input_positive == (uint8_t)ADC_VBAT || input_negative == (uint8_t)ADC_VBAT) &&
381 		channel_cfg->differential) {
382 		LOG_ERR("VBAT pin is not available for differential mode.");
383 		return -EINVAL;
384 	} else if (channel_cfg->differential && (input_negative == (uint8_t)NOINPUTN)) {
385 		LOG_ERR("Negative input is not selected.");
386 		return -EINVAL;
387 	}
388 
389 	/* Init ADC */
390 	data->differential = channel_cfg->differential;
391 	adc_init(vref_internal_mv, pre_scale, sample_freq);
392 	adc_set_vbat_divider(ADC_VBAT_DIV_OFF);
393 	adc_set_tsample_cycle(sample_cycl);
394 
395 	/* Init ADC Pins */
396 	if (channel_cfg->differential) {
397 		/* Differential pins configuration */
398 		adc_pin_config(ADC_GPIO_MODE, input_positive);
399 		adc_pin_config(ADC_GPIO_MODE, input_negative);
400 		adc_set_diff_input(channel_cfg->input_positive, channel_cfg->input_negative);
401 	} else if (input_positive == (uint8_t)ADC_VBAT) {
402 		/* Single-ended Vbat pin configuration */
403 		adc_set_diff_input(ADC_VBAT, GND);
404 	} else {
405 		/* Single-ended GPIO pin configuration */
406 		adc_pin_config(ADC_GPIO_MODE, input_positive);
407 		adc_set_diff_input(channel_cfg->input_positive, GND);
408 	}
409 
410 	return 0;
411 }
412 
413 /* API implementation: read */
adc_b91_read(const struct device * dev,const struct adc_sequence * sequence)414 static int adc_b91_read(const struct device *dev,
415 			const struct adc_sequence *sequence)
416 {
417 	int status;
418 	struct b91_adc_data *data = dev->data;
419 
420 	adc_context_lock(&data->ctx, false, NULL);
421 	status = adc_b91_adc_start_read(dev, sequence);
422 	adc_context_release(&data->ctx, status);
423 
424 	return status;
425 }
426 
427 #ifdef CONFIG_ADC_ASYNC
428 /* API implementation: read_async */
adc_b91_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)429 static int adc_b91_read_async(const struct device *dev,
430 			      const struct adc_sequence *sequence,
431 			      struct k_poll_signal *async)
432 {
433 	int status;
434 	struct b91_adc_data *data = dev->data;
435 
436 	adc_context_lock(&data->ctx, true, async);
437 	status = adc_b91_adc_start_read(dev, sequence);
438 	adc_context_release(&data->ctx, status);
439 
440 	return status;
441 }
442 #endif /* CONFIG_ADC_ASYNC */
443 
444 static struct b91_adc_data data_0 = {
445 	ADC_CONTEXT_INIT_TIMER(data_0, ctx),
446 	ADC_CONTEXT_INIT_LOCK(data_0, ctx),
447 	ADC_CONTEXT_INIT_SYNC(data_0, ctx),
448 };
449 
450 static const struct b91_adc_cfg cfg_0 = {
451 	.sample_freq = DT_INST_PROP(0, sample_freq),
452 	.vref_internal_mv = DT_INST_PROP(0, vref_internal_mv),
453 };
454 
455 static const struct adc_driver_api adc_b91_driver_api = {
456 	.channel_setup = adc_b91_channel_setup,
457 	.read = adc_b91_read,
458 #ifdef CONFIG_ADC_ASYNC
459 	.read_async = adc_b91_read_async,
460 #endif
461 	.ref_internal = cfg_0.vref_internal_mv,
462 };
463 
464 DEVICE_DT_INST_DEFINE(0, adc_b91_init, NULL,
465 		      &data_0,  &cfg_0,
466 		      POST_KERNEL,
467 		      CONFIG_ADC_INIT_PRIORITY,
468 		      &adc_b91_driver_api);
469