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