1 /*
2  * Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT atmel_sam0_adc
8 
9 #include <soc.h>
10 #include <zephyr/drivers/adc.h>
11 #include <zephyr/drivers/pinctrl.h>
12 
13 #include <zephyr/logging/log.h>
14 #include <zephyr/irq.h>
15 LOG_MODULE_REGISTER(adc_sam0, CONFIG_ADC_LOG_LEVEL);
16 
17 #define ADC_CONTEXT_USES_KERNEL_TIMER
18 #include "adc_context.h"
19 
20 #if defined(CONFIG_SOC_SERIES_SAMD21) || defined(CONFIG_SOC_SERIES_SAMR21) || \
21 	defined(CONFIG_SOC_SERIES_SAMD20)
22 /*
23  * SAMD21 Manual 33.6.2.1: The first conversion after changing the reference
24  * is invalid, so we have to discard it.
25  */
26 #define ADC_SAM0_REFERENCE_GLITCH 1
27 #endif
28 
29 struct adc_sam0_data {
30 	struct adc_context ctx;
31 	const struct device *dev;
32 
33 	uint16_t *buffer;
34 
35 	/*
36 	 * Saved initial start, so we can reset the advances we've done
37 	 * if required
38 	 */
39 	uint16_t *repeat_buffer;
40 
41 #ifdef ADC_SAM0_REFERENCE_GLITCH
42 	uint8_t reference_changed;
43 #endif
44 };
45 
46 struct adc_sam0_cfg {
47 	Adc *regs;
48 	const struct pinctrl_dev_config *pcfg;
49 
50 #ifdef MCLK
51 	uint32_t mclk_mask;
52 	uint32_t gclk_mask;
53 	uint16_t gclk_id;
54 #else
55 	uint32_t gclk;
56 #endif
57 
58 	uint32_t freq;
59 	uint16_t prescaler;
60 
61 	void (*config_func)(const struct device *dev);
62 };
63 
wait_synchronization(Adc * const adc)64 static void wait_synchronization(Adc *const adc)
65 {
66 	while ((ADC_SYNC(adc) & ADC_SYNC_MASK) != 0) {
67 	}
68 }
69 
adc_sam0_acquisition_to_clocks(const struct device * dev,uint16_t acquisition_time)70 static int adc_sam0_acquisition_to_clocks(const struct device *dev,
71 					  uint16_t acquisition_time)
72 {
73 	const struct adc_sam0_cfg *const cfg = dev->config;
74 	uint64_t scaled_acq;
75 
76 	switch (ADC_ACQ_TIME_UNIT(acquisition_time)) {
77 	case ADC_ACQ_TIME_TICKS:
78 		if (ADC_ACQ_TIME_VALUE(acquisition_time) > 64U) {
79 			return -EINVAL;
80 		}
81 
82 		return (int)ADC_ACQ_TIME_VALUE(acquisition_time) - 1;
83 	case ADC_ACQ_TIME_MICROSECONDS:
84 		scaled_acq = (uint64_t)ADC_ACQ_TIME_VALUE(acquisition_time) *
85 			     1000000U;
86 		break;
87 	case ADC_ACQ_TIME_NANOSECONDS:
88 		scaled_acq = (uint64_t)ADC_ACQ_TIME_VALUE(acquisition_time) *
89 			     1000U;
90 		break;
91 	default:
92 		return -EINVAL;
93 	}
94 
95 	/*
96 	 * sample_time = (sample_length+1) * (clk_adc / 2)
97 	 * sample_length = sample_time * (2/clk_adc) - 1,
98 	 */
99 
100 	scaled_acq *= 2U;
101 	scaled_acq += cfg->freq / 2U;
102 	scaled_acq /= cfg->freq;
103 	if (scaled_acq <= 1U) {
104 		return 0;
105 	}
106 
107 	scaled_acq -= 1U;
108 	if (scaled_acq >= 64U) {
109 		return -EINVAL;
110 	}
111 
112 	return (int)scaled_acq;
113 }
114 
adc_sam0_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)115 static int adc_sam0_channel_setup(const struct device *dev,
116 				  const struct adc_channel_cfg *channel_cfg)
117 {
118 	const struct adc_sam0_cfg *const cfg = dev->config;
119 	Adc *const adc = cfg->regs;
120 	int retval;
121 	uint8_t sampctrl = 0;
122 
123 	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
124 		retval = adc_sam0_acquisition_to_clocks(dev,
125 							channel_cfg->acquisition_time);
126 		if (retval < 0) {
127 			LOG_ERR("Selected ADC acquisition time is not valid");
128 			return retval;
129 		}
130 
131 		sampctrl |= ADC_SAMPCTRL_SAMPLEN(retval);
132 	}
133 
134 	adc->SAMPCTRL.reg = sampctrl;
135 	wait_synchronization(adc);
136 
137 	uint8_t refctrl;
138 
139 	switch (channel_cfg->reference) {
140 	case ADC_REF_INTERNAL:
141 		refctrl = ADC_REFCTRL_REFSEL_INTERNAL | ADC_REFCTRL_REFCOMP;
142 		/* Enable the internal bandgap reference */
143 		ADC_BGEN = 1;
144 		break;
145 #ifdef ADC_REFCTRL_REFSEL_VDD_1
146 	case ADC_REF_VDD_1:
147 		refctrl = ADC_REFCTRL_REFSEL_VDD_1 | ADC_REFCTRL_REFCOMP;
148 		break;
149 #endif
150 	case ADC_REF_VDD_1_2:
151 		refctrl = ADC_REFCTRL_REFSEL_VDD_1_2 | ADC_REFCTRL_REFCOMP;
152 		break;
153 	case ADC_REF_EXTERNAL0:
154 		refctrl = ADC_REFCTRL_REFSEL_AREFA;
155 		break;
156 #ifdef ADC_REFCTRL_REFSEL_AREFB
157 	case ADC_REF_EXTERNAL1:
158 		refctrl = ADC_REFCTRL_REFSEL_AREFB;
159 		break;
160 #endif
161 	default:
162 		LOG_ERR("Selected reference is not valid");
163 		return -EINVAL;
164 	}
165 	if (adc->REFCTRL.reg != refctrl) {
166 #ifdef ADC_SAM0_REFERENCE_ENABLE_PROTECTED
167 		adc->CTRLA.bit.ENABLE = 0;
168 		wait_synchronization(adc);
169 #endif
170 		adc->REFCTRL.reg = refctrl;
171 		wait_synchronization(adc);
172 #ifdef ADC_SAM0_REFERENCE_ENABLE_PROTECTED
173 		adc->CTRLA.bit.ENABLE = 1;
174 		wait_synchronization(adc);
175 #endif
176 #ifdef ADC_SAM0_REFERENCE_GLITCH
177 		struct adc_sam0_data *data = dev->data;
178 
179 		data->reference_changed = 1;
180 #endif
181 	}
182 
183 
184 	uint32_t inputctrl = 0;
185 
186 	switch (channel_cfg->gain) {
187 	case ADC_GAIN_1:
188 #ifdef ADC_INPUTCTRL_GAIN_1X
189 		inputctrl = ADC_INPUTCTRL_GAIN_1X;
190 #endif
191 		break;
192 #ifdef ADC_INPUTCTRL_GAIN_DIV2
193 	case ADC_GAIN_1_2:
194 		inputctrl = ADC_INPUTCTRL_GAIN_DIV2;
195 		break;
196 #endif
197 #ifdef ADC_INPUTCTRL_GAIN_2X
198 	case ADC_GAIN_2:
199 		inputctrl = ADC_INPUTCTRL_GAIN_2X;
200 		break;
201 #endif
202 #ifdef ADC_INPUTCTRL_GAIN_4X
203 	case ADC_GAIN_4:
204 		inputctrl = ADC_INPUTCTRL_GAIN_4X;
205 		break;
206 #endif
207 #ifdef ADC_INPUTCTRL_GAIN_8X
208 	case ADC_GAIN_8:
209 		inputctrl = ADC_INPUTCTRL_GAIN_8X;
210 		break;
211 #endif
212 #ifdef ADC_INPUTCTRL_GAIN_16X
213 	case ADC_GAIN_16:
214 		inputctrl = ADC_INPUTCTRL_GAIN_16X;
215 		break;
216 #endif
217 	default:
218 		LOG_ERR("Selected ADC gain is not valid");
219 		return -EINVAL;
220 	}
221 
222 	inputctrl |= ADC_INPUTCTRL_MUXPOS(channel_cfg->input_positive);
223 	if (channel_cfg->differential) {
224 		inputctrl |= ADC_INPUTCTRL_MUXNEG(channel_cfg->input_negative);
225 
226 		ADC_DIFF(adc) |= ADC_DIFF_MASK;
227 	} else {
228 		inputctrl |= ADC_INPUTCTRL_MUXNEG_GND;
229 
230 		ADC_DIFF(adc) &= ~ADC_DIFF_MASK;
231 	}
232 	wait_synchronization(adc);
233 
234 	adc->INPUTCTRL.reg = inputctrl;
235 	wait_synchronization(adc);
236 
237 	/* Enable references if they're selected */
238 	switch (channel_cfg->input_positive) {
239 #ifdef ADC_INPUTCTRL_MUXPOS_TEMP_Val
240 	case ADC_INPUTCTRL_MUXPOS_TEMP_Val:
241 		ADC_TSEN = 1;
242 		break;
243 #endif
244 #ifdef ADC_INPUTCTRL_MUXPOS_PTAT_Val
245 	case ADC_INPUTCTRL_MUXPOS_PTAT_Val:
246 		ADC_TSEN = 1;
247 		break;
248 #endif
249 #ifdef ADC_INPUTCTRL_MUXPOS_CTAT_Val
250 	case ADC_INPUTCTRL_MUXPOS_CTAT_Val:
251 		ADC_TSEN = 1;
252 		break;
253 #endif
254 	case ADC_INPUTCTRL_MUXPOS_BANDGAP_Val:
255 		ADC_BGEN = 1;
256 		break;
257 	default:
258 		break;
259 	}
260 
261 
262 	return 0;
263 }
264 
adc_sam0_start_conversion(const struct device * dev)265 static void adc_sam0_start_conversion(const struct device *dev)
266 {
267 	const struct adc_sam0_cfg *const cfg = dev->config;
268 	Adc *const adc = cfg->regs;
269 
270 	LOG_DBG("Starting conversion");
271 
272 	adc->SWTRIG.reg = ADC_SWTRIG_START;
273 	/*
274 	 * Should be safe to not synchronize here because the only things
275 	 * that might access the ADC after this will wait for it to complete
276 	 * (synchronize finished implicitly)
277 	 */
278 }
279 
adc_context_start_sampling(struct adc_context * ctx)280 static void adc_context_start_sampling(struct adc_context *ctx)
281 {
282 	struct adc_sam0_data *data =
283 		CONTAINER_OF(ctx, struct adc_sam0_data, ctx);
284 
285 	adc_sam0_start_conversion(data->dev);
286 }
287 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)288 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
289 					      bool repeat_sampling)
290 {
291 	struct adc_sam0_data *data =
292 		CONTAINER_OF(ctx, struct adc_sam0_data, ctx);
293 
294 	if (repeat_sampling) {
295 		data->buffer = data->repeat_buffer;
296 	}
297 }
298 
check_buffer_size(const struct adc_sequence * sequence,uint8_t active_channels)299 static int check_buffer_size(const struct adc_sequence *sequence,
300 			     uint8_t active_channels)
301 {
302 	size_t needed_buffer_size;
303 
304 	needed_buffer_size = active_channels * sizeof(uint16_t);
305 	if (sequence->options) {
306 		needed_buffer_size *= (1U + sequence->options->extra_samplings);
307 	}
308 
309 	if (sequence->buffer_size < needed_buffer_size) {
310 		LOG_ERR("Provided buffer is too small (%u/%u)",
311 			sequence->buffer_size, needed_buffer_size);
312 		return -ENOMEM;
313 	}
314 	return 0;
315 }
316 
start_read(const struct device * dev,const struct adc_sequence * sequence)317 static int start_read(const struct device *dev,
318 		      const struct adc_sequence *sequence)
319 {
320 	const struct adc_sam0_cfg *const cfg = dev->config;
321 	struct adc_sam0_data *data = dev->data;
322 	Adc *const adc = cfg->regs;
323 	int error;
324 
325 	if (sequence->oversampling > 10U) {
326 		LOG_ERR("Invalid oversampling");
327 		return -EINVAL;
328 	}
329 
330 	adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM(sequence->oversampling);
331 	/* AVGCTRL is not synchronized */
332 
333 #ifdef CONFIG_SOC_SERIES_SAMD20
334 	/*
335 	 * Errata: silicon revisions B and C do not perform the automatic right
336 	 * shifts in accumulation
337 	 */
338 	if (sequence->oversampling > 4U && DSU->DID.bit.REVISION < 3) {
339 		adc->AVGCTRL.bit.ADJRES = sequence->oversampling - 4U;
340 	}
341 #endif
342 
343 	switch (sequence->resolution) {
344 	case 8:
345 		if (sequence->oversampling) {
346 			LOG_ERR("Oversampling requires 12 bit resolution");
347 			return -EINVAL;
348 		}
349 
350 		ADC_RESSEL(adc) = ADC_RESSEL_8BIT;
351 		break;
352 	case 10:
353 		if (sequence->oversampling) {
354 			LOG_ERR("Oversampling requires 12 bit resolution");
355 			return -EINVAL;
356 		}
357 
358 		ADC_RESSEL(adc) = ADC_RESSEL_10BIT;
359 		break;
360 	case 12:
361 		if (sequence->oversampling) {
362 			ADC_RESSEL(adc) = ADC_RESSEL_16BIT;
363 		} else {
364 			ADC_RESSEL(adc) = ADC_RESSEL_12BIT;
365 		}
366 		break;
367 	default:
368 		LOG_ERR("ADC resolution value %d is not valid",
369 			sequence->resolution);
370 		return -EINVAL;
371 	}
372 
373 	wait_synchronization(adc);
374 
375 	if ((sequence->channels == 0)
376 		|| ((sequence->channels & (sequence->channels - 1)) != 0)) {
377 		/* The caller is expected to identify a single input channel, which will
378 		 * typically be the positive input, though no check is made for this...
379 		 *
380 		 * While ensuring that the channels bitfield matches the positive input
381 		 * might be sensible, this will likely break users before this revision
382 		 * was put in place.
383 		 */
384 		LOG_ERR("Channel scanning is not supported");
385 		return -ENOTSUP;
386 	}
387 
388 	error = check_buffer_size(sequence, 1);
389 	if (error) {
390 		return error;
391 	}
392 
393 	data->buffer = sequence->buffer;
394 	data->repeat_buffer = sequence->buffer;
395 
396 	/* At this point we allow the scheduler to do other things while
397 	 * we wait for the conversions to complete. This is provided by the
398 	 * adc_context functions. However, the caller of this function is
399 	 * blocked until the results are in.
400 	 */
401 	adc_context_start_read(&data->ctx, sequence);
402 
403 	error = adc_context_wait_for_completion(&data->ctx);
404 	return error;
405 }
406 
adc_sam0_read(const struct device * dev,const struct adc_sequence * sequence)407 static int adc_sam0_read(const struct device *dev,
408 			 const struct adc_sequence *sequence)
409 {
410 	struct adc_sam0_data *data = dev->data;
411 	int error;
412 
413 	adc_context_lock(&data->ctx, false, NULL);
414 	error = start_read(dev, sequence);
415 	adc_context_release(&data->ctx, error);
416 
417 	return error;
418 }
419 
adc_sam0_isr(const struct device * dev)420 static void adc_sam0_isr(const struct device *dev)
421 {
422 	struct adc_sam0_data *data = dev->data;
423 	const struct adc_sam0_cfg *const cfg = dev->config;
424 	Adc *const adc = cfg->regs;
425 	uint16_t result;
426 
427 	adc->INTFLAG.reg = ADC_INTFLAG_MASK;
428 
429 	result = (uint16_t)(adc->RESULT.reg);
430 
431 #ifdef ADC_SAM0_REFERENCE_GLITCH
432 	if (data->reference_changed) {
433 		data->reference_changed = 0;
434 		LOG_DBG("Discarded initial conversion due to reference change");
435 
436 		adc_sam0_start_conversion(dev);
437 		return;
438 	}
439 #endif
440 
441 	*data->buffer++ = result;
442 	adc_context_on_sampling_done(&data->ctx, dev);
443 }
444 
adc_sam0_init(const struct device * dev)445 static int adc_sam0_init(const struct device *dev)
446 {
447 	const struct adc_sam0_cfg *const cfg = dev->config;
448 	struct adc_sam0_data *data = dev->data;
449 	Adc *const adc = cfg->regs;
450 	int retval;
451 
452 #ifdef MCLK
453 	GCLK->PCHCTRL[cfg->gclk_id].reg = cfg->gclk_mask | GCLK_PCHCTRL_CHEN;
454 
455 	MCLK_ADC |= cfg->mclk_mask;
456 #else
457 	PM->APBCMASK.bit.ADC_ = 1;
458 
459 	GCLK->CLKCTRL.reg = cfg->gclk | GCLK_CLKCTRL_CLKEN;
460 #endif
461 
462 	retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
463 	if (retval < 0) {
464 		return retval;
465 	}
466 
467 	ADC_PRESCALER(adc) = cfg->prescaler;
468 	wait_synchronization(adc);
469 
470 	adc->INTENCLR.reg = ADC_INTENCLR_MASK;
471 	adc->INTFLAG.reg = ADC_INTFLAG_MASK;
472 
473 	cfg->config_func(dev);
474 
475 	adc->INTENSET.reg = ADC_INTENSET_RESRDY;
476 
477 	data->dev = dev;
478 #ifdef ADC_SAM0_REFERENCE_GLITCH
479 	data->reference_changed = 1;
480 #endif
481 
482 	adc->CTRLA.bit.ENABLE = 1;
483 	wait_synchronization(adc);
484 
485 	adc_context_unlock_unconditionally(&data->ctx);
486 
487 	return 0;
488 }
489 
490 #ifdef CONFIG_ADC_ASYNC
adc_sam0_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)491 static int adc_sam0_read_async(const struct device *dev,
492 			       const struct adc_sequence *sequence,
493 			       struct k_poll_signal *async)
494 {
495 	struct adc_sam0_data *data = dev->data;
496 	int error;
497 
498 	adc_context_lock(&data->ctx, true, async);
499 	error = start_read(dev, sequence);
500 	adc_context_release(&data->ctx, error);
501 
502 	return error;
503 }
504 #endif
505 
506 static const struct adc_driver_api adc_sam0_api = {
507 	.channel_setup = adc_sam0_channel_setup,
508 	.read = adc_sam0_read,
509 #ifdef CONFIG_ADC_ASYNC
510 	.read_async = adc_sam0_read_async,
511 #endif
512 };
513 
514 
515 #ifdef MCLK
516 
517 #define ADC_SAM0_CLOCK_CONTROL(n)					\
518 	.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)),	\
519 	.gclk_mask = UTIL_CAT(GCLK_PCHCTRL_GEN_GCLK,			\
520 			      DT_INST_PROP(n, gclk)),			\
521 	.gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),	\
522 	.prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV,			\
523 			      UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)),
524 
525 #define ADC_SAM0_CONFIGURE(n)						\
526 do {									\
527 	const struct adc_sam0_cfg *const cfg = dev->config;		\
528 	Adc * const adc = cfg->regs;					\
529 	adc->CALIB.reg = ADC_SAM0_BIASCOMP(n)				\
530 			 | ADC_SAM0_BIASR2R(n)				\
531 			 | ADC_SAM0_BIASREFBUF(n);			\
532 } while (false)
533 
534 #else
535 
536 #define ADC_SAM0_CLOCK_CONTROL(n)					\
537 	.gclk = UTIL_CAT(GCLK_CLKCTRL_GEN_GCLK,	DT_INST_PROP(n, gclk)) |\
538 			 GCLK_CLKCTRL_ID_ADC,				\
539 	.prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV,			\
540 			      UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)),
541 
542 #define ADC_SAM0_CONFIGURE(n)						\
543 do {									\
544 	const struct adc_sam0_cfg *const cfg = dev->config;		\
545 	Adc * const adc = cfg->regs;					\
546 	/* Linearity is split across two words */			\
547 	uint32_t lin = ((*(uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) &		\
548 		     ADC_FUSES_LINEARITY_0_Msk) >>			\
549 		     ADC_FUSES_LINEARITY_0_Pos;				\
550 	lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) &		\
551 		 ADC_FUSES_LINEARITY_1_Msk) >>				\
552 		 ADC_FUSES_LINEARITY_1_Pos) << 4;			\
553 	uint32_t bias = ((*(uint32_t *)ADC_FUSES_BIASCAL_ADDR) &		\
554 		      ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos;	\
555 	adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) |			\
556 			 ADC_CALIB_LINEARITY_CAL(lin);			\
557 } while (false)
558 
559 #endif
560 
561 #define ADC_SAM0_DEVICE(n)						\
562 	PINCTRL_DT_INST_DEFINE(n);					\
563 	static void adc_sam0_config_##n(const struct device *dev);	\
564 	static const struct adc_sam0_cfg adc_sam_cfg_##n = {		\
565 		.regs = (Adc *)DT_INST_REG_ADDR(n),			\
566 		ADC_SAM0_CLOCK_CONTROL(n)				\
567 		.freq = UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK,		\
568 					  DT_INST_PROP(n, gclk)),	\
569 					  _FREQ_HZ) /			\
570 			DT_INST_PROP(n, prescaler),			\
571 		.config_func = &adc_sam0_config_##n,			\
572 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		\
573 	};								\
574 	static struct adc_sam0_data adc_sam_data_##n = {		\
575 		ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx),		\
576 		ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx),		\
577 		ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx),		\
578 	};								\
579 	DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL,			\
580 			    &adc_sam_data_##n,				\
581 			    &adc_sam_cfg_##n, POST_KERNEL,		\
582 			    CONFIG_ADC_INIT_PRIORITY,			\
583 			    &adc_sam0_api);				\
584 	static void adc_sam0_config_##n(const struct device *dev)	\
585 	{								\
586 		IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq),	\
587 			    DT_INST_IRQ_BY_NAME(n, resrdy, priority),	\
588 			    adc_sam0_isr,				\
589 			    DEVICE_DT_INST_GET(n), 0);			\
590 		irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq));	\
591 		ADC_SAM0_CONFIGURE(n);					\
592 	}
593 
594 DT_INST_FOREACH_STATUS_OKAY(ADC_SAM0_DEVICE)
595