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