1 /*
2  * Copyright (c) 2017 comsuisse AG
3  * Copyright (c) 2018 Justin Watson
4  * Copyright (c) 2023 Gerson Fernando Budke
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define DT_DRV_COMPAT atmel_sam_afec
10 
11 /** @file
12  * @brief Atmel SAM MCU family ADC (AFEC) driver.
13  *
14  * This is an implementation of the Zephyr ADC driver using the SAM Analog
15  * Front-End Controller (AFEC) peripheral.
16  */
17 
18 #include <errno.h>
19 #include <zephyr/sys/__assert.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/device.h>
22 #include <zephyr/init.h>
23 #include <soc.h>
24 #include <zephyr/drivers/adc.h>
25 #include <zephyr/drivers/pinctrl.h>
26 #include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
27 
28 #define ADC_CONTEXT_USES_KERNEL_TIMER
29 #include "adc_context.h"
30 
31 #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL
32 #include <zephyr/logging/log.h>
33 #include <zephyr/irq.h>
34 LOG_MODULE_REGISTER(adc_sam_afec);
35 
36 #define NUM_CHANNELS 12
37 #define CONF_ADC_PRESCALER ((SOC_ATMEL_SAM_MCK_FREQ_HZ / 15000000) - 1)
38 #ifndef AFEC_MR_ONE
39 #define AFEC_MR_ONE AFEC_MR_ANACH
40 #endif
41 
42 typedef void (*cfg_func_t)(const struct device *dev);
43 
44 struct adc_sam_data {
45 	struct adc_context ctx;
46 	const struct device *dev;
47 
48 	/* Pointer to the buffer in the sequence. */
49 	uint16_t *buffer;
50 
51 	/* Pointer to the beginning of a sample. Consider the number of
52 	 * channels in the sequence: this buffer changes by that amount
53 	 * so all the channels would get repeated.
54 	 */
55 	uint16_t *repeat_buffer;
56 
57 	/* Bit mask of the channels to be sampled. */
58 	uint32_t channels;
59 
60 	/* Index of the channel being sampled. */
61 	uint8_t channel_id;
62 };
63 
64 struct adc_sam_cfg {
65 	Afec *regs;
66 	cfg_func_t cfg_func;
67 	const struct atmel_sam_pmc_config clock_cfg;
68 	const struct pinctrl_dev_config *pcfg;
69 };
70 
adc_sam_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)71 static int adc_sam_channel_setup(const struct device *dev,
72 				 const struct adc_channel_cfg *channel_cfg)
73 {
74 	const struct adc_sam_cfg * const cfg = dev->config;
75 	Afec *const afec = cfg->regs;
76 
77 	uint8_t channel_id = channel_cfg->channel_id;
78 
79 	/* Clear the gain bits for the channel. */
80 	afec->AFEC_CGR &= ~(3 << channel_id * 2U);
81 
82 	switch (channel_cfg->gain) {
83 	case ADC_GAIN_1:
84 		/* A value of 0 in this register is a gain of 1. */
85 		break;
86 	case ADC_GAIN_1_2:
87 		afec->AFEC_CGR |= (1 << (channel_id * 2U));
88 		break;
89 	case ADC_GAIN_1_4:
90 		afec->AFEC_CGR |= (2 << (channel_id * 2U));
91 		break;
92 	default:
93 		LOG_ERR("Selected ADC gain is not valid");
94 		return -EINVAL;
95 	}
96 
97 	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
98 		LOG_ERR("Selected ADC acquisition time is not valid");
99 		return -EINVAL;
100 	}
101 
102 	if (channel_cfg->reference != ADC_REF_EXTERNAL0) {
103 		LOG_ERR("Selected reference is not valid");
104 		return -EINVAL;
105 	}
106 
107 	if (channel_cfg->differential) {
108 		LOG_ERR("Differential input is not supported");
109 		return -EINVAL;
110 	}
111 
112 #ifdef AFEC_11147
113 	/* Set single ended channels to unsigned and differential channels
114 	 * to signed conversions.
115 	 */
116 	afec->AFEC_EMR &= ~(AFEC_EMR_SIGNMODE(
117 			  AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN_Val));
118 #endif
119 
120 	return 0;
121 }
122 
adc_sam_start_conversion(const struct device * dev)123 static void adc_sam_start_conversion(const struct device *dev)
124 {
125 	const struct adc_sam_cfg *const cfg = dev->config;
126 	struct adc_sam_data *data = dev->data;
127 	Afec *const afec = cfg->regs;
128 
129 	data->channel_id = find_lsb_set(data->channels) - 1;
130 
131 	LOG_DBG("Starting channel %d", data->channel_id);
132 
133 	/* Disable all channels. */
134 	afec->AFEC_CHDR = 0xfff;
135 	afec->AFEC_IDR = 0xfff;
136 
137 	/* Enable the ADC channel. This also enables/selects the channel pin as
138 	 * an input to the AFEC (50.5.1 SAM E70 datasheet).
139 	 */
140 	afec->AFEC_CHER = (1 << data->channel_id);
141 
142 	/* Enable the interrupt for the channel. */
143 	afec->AFEC_IER = (1 << data->channel_id);
144 
145 	/* Start the conversions. */
146 	afec->AFEC_CR = AFEC_CR_START;
147 }
148 
149 /**
150  * This is only called once at the beginning of all the conversions,
151  * all channels as a group.
152  */
adc_context_start_sampling(struct adc_context * ctx)153 static void adc_context_start_sampling(struct adc_context *ctx)
154 {
155 	struct adc_sam_data *data = CONTAINER_OF(ctx, struct adc_sam_data, ctx);
156 
157 	data->channels = ctx->sequence.channels;
158 
159 	adc_sam_start_conversion(data->dev);
160 }
161 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)162 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
163 					      bool repeat_sampling)
164 {
165 	struct adc_sam_data *data = CONTAINER_OF(ctx, struct adc_sam_data, ctx);
166 
167 	if (repeat_sampling) {
168 		data->buffer = data->repeat_buffer;
169 	}
170 }
171 
check_buffer_size(const struct adc_sequence * sequence,uint8_t active_channels)172 static int check_buffer_size(const struct adc_sequence *sequence,
173 			     uint8_t active_channels)
174 {
175 	size_t needed_buffer_size;
176 	needed_buffer_size = active_channels * sizeof(uint16_t);
177 	if (sequence->options) {
178 		needed_buffer_size *= (1 + sequence->options->extra_samplings);
179 	}
180 	if (sequence->buffer_size < needed_buffer_size) {
181 		LOG_ERR("Provided buffer is too small (%u/%u)",
182 				sequence->buffer_size, needed_buffer_size);
183 		return -ENOMEM;
184 	}
185 	return 0;
186 }
187 
start_read(const struct device * dev,const struct adc_sequence * sequence)188 static int start_read(const struct device *dev,
189 		      const struct adc_sequence *sequence)
190 {
191 	struct adc_sam_data *data = dev->data;
192 	int error = 0;
193 	uint32_t channels = sequence->channels;
194 
195 	data->channels = 0U;
196 
197 	/* Signal an error if the channel selection is invalid (no channels or
198 	 * a non-existing one is selected).
199 	 */
200 	if (channels == 0U ||
201 	    (channels & (~0UL << NUM_CHANNELS))) {
202 		LOG_ERR("Invalid selection of channels");
203 		return -EINVAL;
204 	}
205 
206 	if (sequence->oversampling != 0U) {
207 		LOG_ERR("Oversampling is not supported");
208 		return -EINVAL;
209 	}
210 
211 	if (sequence->resolution != 12U) {
212 		/* TODO JKW: Support the Enhanced Resolution Mode 50.6.3 page
213 		 * 1544.
214 		 */
215 		LOG_ERR("ADC resolution value %d is not valid",
216 			    sequence->resolution);
217 		return -EINVAL;
218 	}
219 
220 	uint8_t num_active_channels = 0U;
221 	uint8_t channel = 0U;
222 
223 	while (channels > 0) {
224 		if (channels & 1) {
225 			++num_active_channels;
226 		}
227 		channels >>= 1;
228 		++channel;
229 	}
230 
231 	error = check_buffer_size(sequence, num_active_channels);
232 	if (error) {
233 		return error;
234 	}
235 
236 	/* In the context you have a pointer to the adc_sam_data structure
237 	 * only.
238 	 */
239 	data->buffer = sequence->buffer;
240 	data->repeat_buffer = sequence->buffer;
241 
242 	/* At this point we allow the scheduler to do other things while
243 	 * we wait for the conversions to complete. This is provided by the
244 	 * adc_context functions. However, the caller of this function is
245 	 * blocked until the results are in.
246 	 */
247 	adc_context_start_read(&data->ctx, sequence);
248 
249 	error = adc_context_wait_for_completion(&data->ctx);
250 	return error;
251 }
252 
adc_sam_read(const struct device * dev,const struct adc_sequence * sequence)253 static int adc_sam_read(const struct device *dev,
254 			const struct adc_sequence *sequence)
255 {
256 	struct adc_sam_data *data = dev->data;
257 	int error;
258 
259 	adc_context_lock(&data->ctx, false, NULL);
260 	error = start_read(dev, sequence);
261 	adc_context_release(&data->ctx, error);
262 
263 	return error;
264 }
265 
adc_sam_init(const struct device * dev)266 static int adc_sam_init(const struct device *dev)
267 {
268 	const struct adc_sam_cfg *const cfg = dev->config;
269 	struct adc_sam_data *data = dev->data;
270 	Afec *const afec = cfg->regs;
271 	int retval;
272 
273 	/* Reset the AFEC. */
274 	afec->AFEC_CR = AFEC_CR_SWRST;
275 
276 	afec->AFEC_MR = AFEC_MR_TRGEN_DIS
277 		      | AFEC_MR_SLEEP_NORMAL
278 		      | AFEC_MR_FWUP_OFF
279 		      | AFEC_MR_FREERUN_OFF
280 		      | AFEC_MR_PRESCAL(CONF_ADC_PRESCALER)
281 		      | AFEC_MR_STARTUP_SUT96
282 		      | AFEC_MR_ONE
283 		      | AFEC_MR_USEQ_NUM_ORDER;
284 
285 	/* Set all channels CM voltage to Vrefp/2 (512). */
286 	for (int i = 0; i < NUM_CHANNELS; i++) {
287 		afec->AFEC_CSELR = i;
288 		afec->AFEC_COCR = 512;
289 	}
290 
291 	/* Enable PGA and Current Bias. */
292 	afec->AFEC_ACR = AFEC_ACR_IBCTL(1)
293 #ifdef AFEC_11147
294 		       | AFEC_ACR_PGA0EN
295 		       | AFEC_ACR_PGA1EN
296 #endif
297 		       ;
298 
299 	/* Enable AFEC clock in PMC */
300 	(void)clock_control_on(SAM_DT_PMC_CONTROLLER,
301 			       (clock_control_subsys_t)&cfg->clock_cfg);
302 
303 	/* Connect pins to the peripheral */
304 	retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
305 	if (retval < 0) {
306 		return retval;
307 	}
308 
309 	cfg->cfg_func(dev);
310 
311 	data->dev = dev;
312 
313 	adc_context_unlock_unconditionally(&data->ctx);
314 
315 	return retval;
316 }
317 
318 #ifdef CONFIG_ADC_ASYNC
adc_sam_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)319 static int adc_sam_read_async(const struct device *dev,
320 			      const struct adc_sequence *sequence,
321 			      struct k_poll_signal *async)
322 {
323 	struct adc_sam_data *data = dev->data;
324 	int error;
325 
326 	adc_context_lock(&data->ctx, true, async);
327 	error = start_read(dev, sequence);
328 	adc_context_release(&data->ctx, error);
329 
330 	return error;
331 }
332 #endif
333 
334 static const struct adc_driver_api adc_sam_api = {
335 	.channel_setup = adc_sam_channel_setup,
336 	.read = adc_sam_read,
337 #ifdef CONFIG_ADC_ASYNC
338 	.read_async = adc_sam_read_async,
339 #endif
340 };
341 
adc_sam_isr(const struct device * dev)342 static void adc_sam_isr(const struct device *dev)
343 {
344 	struct adc_sam_data *data = dev->data;
345 	const struct adc_sam_cfg *const cfg = dev->config;
346 	Afec *const afec = cfg->regs;
347 	uint16_t result;
348 
349 	afec->AFEC_CHDR |= BIT(data->channel_id);
350 	afec->AFEC_IDR |= BIT(data->channel_id);
351 
352 	afec->AFEC_CSELR = AFEC_CSELR_CSEL(data->channel_id);
353 	result = (uint16_t)(afec->AFEC_CDR);
354 
355 	*data->buffer++ = result;
356 	data->channels &= ~BIT(data->channel_id);
357 
358 	if (data->channels) {
359 		adc_sam_start_conversion(dev);
360 	} else {
361 		/* Called once all conversions have completed.*/
362 		adc_context_on_sampling_done(&data->ctx, dev);
363 	}
364 }
365 
366 #define ADC_SAM_INIT(n)							\
367 	PINCTRL_DT_INST_DEFINE(n);					\
368 	static void adc##n##_sam_cfg_func(const struct device *dev);	\
369 									\
370 	static const struct adc_sam_cfg adc##n##_sam_cfg = {		\
371 		.regs = (Afec *)DT_INST_REG_ADDR(n),			\
372 		.cfg_func = adc##n##_sam_cfg_func,			\
373 		.clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n),		\
374 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),		\
375 	};								\
376 									\
377 	static struct adc_sam_data adc##n##_sam_data = {		\
378 		ADC_CONTEXT_INIT_TIMER(adc##n##_sam_data, ctx),		\
379 		ADC_CONTEXT_INIT_LOCK(adc##n##_sam_data, ctx),		\
380 		ADC_CONTEXT_INIT_SYNC(adc##n##_sam_data, ctx),		\
381 	};								\
382 									\
383 	DEVICE_DT_INST_DEFINE(n, adc_sam_init, NULL,			\
384 			    &adc##n##_sam_data,				\
385 			    &adc##n##_sam_cfg, POST_KERNEL,		\
386 			    CONFIG_ADC_INIT_PRIORITY,			\
387 			    &adc_sam_api);				\
388 									\
389 	static void adc##n##_sam_cfg_func(const struct device *dev)	\
390 	{								\
391 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority),	\
392 			    adc_sam_isr,				\
393 			    DEVICE_DT_INST_GET(n), 0);			\
394 		irq_enable(DT_INST_IRQN(n));				\
395 	}
396 
397 DT_INST_FOREACH_STATUS_OKAY(ADC_SAM_INIT)
398