1 /*
2 * Copyright 2023 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 #include <zephyr/drivers/adc.h>
9 #include <zephyr/drivers/pinctrl.h>
10 #include <zephyr/irq.h>
11 #include <Adc_Sar_Ip_HwAccess.h>
12 #include <Adc_Sar_Ip.h>
13 #include <Adc_Sar_Ip_Irq.h>
14
15 #define ADC_CONTEXT_USES_KERNEL_TIMER
16 #include "adc_context.h"
17
18 #define DT_DRV_COMPAT nxp_s32_adc_sar
19 LOG_MODULE_REGISTER(adc_nxp_s32_adc_sar, CONFIG_ADC_LOG_LEVEL);
20
21 /* Convert channel of group ADC to channel of physical ADC instance */
22 #define ADC_NXP_S32_GROUPCHAN_2_PHYCHAN(group, channel) \
23 (ADC_SAR_IP_HW_REG_SIZE * group + channel)
24
25 struct adc_nxp_s32_config {
26 ADC_Type *base;
27 uint8_t instance;
28 uint8_t group_channel;
29 uint8_t callback_select;
30 Adc_Sar_Ip_ConfigType *adc_cfg;
31 void (*irq_config_func)(const struct device *dev);
32 const struct pinctrl_dev_config *pin_cfg;
33 };
34
35 struct adc_nxp_s32_data {
36 const struct device *dev;
37 struct adc_context ctx;
38 uint16_t *buffer;
39 uint16_t *buf_end;
40 uint16_t *repeat_buffer;
41 uint32_t mask_channels;
42 uint8_t num_channels;
43 };
44
adc_nxp_s32_init(const struct device * dev)45 static int adc_nxp_s32_init(const struct device *dev)
46 {
47 const struct adc_nxp_s32_config *config = dev->config;
48 struct adc_nxp_s32_data *data = dev->data;
49 Adc_Sar_Ip_StatusType status;
50 /* This array shows max number of channels of each group */
51 uint8_t map_chan_group[ADC_SAR_IP_INSTANCE_COUNT][ADC_SAR_IP_NUM_GROUP_CHAN]
52 = FEATURE_ADC_MAX_CHN_COUNT;
53
54 data->num_channels = map_chan_group[config->instance][config->group_channel];
55
56 if (config->pin_cfg) {
57 if (pinctrl_apply_state(config->pin_cfg, PINCTRL_STATE_DEFAULT)) {
58 return -EIO;
59 }
60 }
61
62 status = Adc_Sar_Ip_Init(config->instance, config->adc_cfg);
63 if (status) {
64 return -EIO;
65 }
66
67 #if FEATURE_ADC_HAS_CALIBRATION
68 status = Adc_Sar_Ip_DoCalibration(config->instance);
69 if (status) {
70 return -EIO;
71 }
72 #endif
73
74 Adc_Sar_Ip_EnableNotifications(config->instance,
75 config->callback_select ?
76 ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN
77 : ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC);
78
79 data->dev = dev;
80 config->irq_config_func(dev);
81
82 adc_context_unlock_unconditionally(&data->ctx);
83
84 return 0;
85 }
86
adc_nxp_s32_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)87 static int adc_nxp_s32_channel_setup(const struct device *dev,
88 const struct adc_channel_cfg *channel_cfg)
89 {
90 struct adc_nxp_s32_data *data = dev->data;
91
92 if (channel_cfg->channel_id >= data->num_channels) {
93 LOG_ERR("Channel %d is not valid", channel_cfg->channel_id);
94 return -EINVAL;
95 }
96
97 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
98 LOG_ERR("Unsupported channel acquisition time");
99 return -ENOTSUP;
100 }
101
102 if (channel_cfg->differential) {
103 LOG_ERR("Differential channels are not supported");
104 return -ENOTSUP;
105 }
106
107 if (channel_cfg->gain != ADC_GAIN_1) {
108 LOG_ERR("Unsupported channel gain %d", channel_cfg->gain);
109 return -ENOTSUP;
110 }
111
112 if (channel_cfg->reference != ADC_REF_INTERNAL) {
113 LOG_ERR("Unsupported channel reference");
114 return -ENOTSUP;
115 }
116
117 return 0;
118 }
119
adc_nxp_s32_validate_buffer_size(const struct device * dev,const struct adc_sequence * sequence)120 static int adc_nxp_s32_validate_buffer_size(const struct device *dev,
121 const struct adc_sequence *sequence)
122 {
123 uint8_t active_channels = 0;
124 size_t needed_size;
125
126 active_channels = POPCOUNT(sequence->channels);
127
128 needed_size = active_channels * sizeof(uint16_t);
129 if (sequence->options) {
130 needed_size *= (1 + sequence->options->extra_samplings);
131 }
132
133 if (sequence->buffer_size < needed_size) {
134 return -ENOSPC;
135 }
136
137 return 0;
138 }
139
140 #if FEATURE_ADC_HAS_AVERAGING
adc_nxp_s32_set_averaging(const struct device * dev,uint8_t oversampling)141 static int adc_nxp_s32_set_averaging(const struct device *dev, uint8_t oversampling)
142 {
143 const struct adc_nxp_s32_config *config = dev->config;
144 Adc_Sar_Ip_AvgSelectType avg_sel = ADC_SAR_IP_AVG_4_CONV;
145 bool avg_en = true;
146
147 switch (oversampling) {
148 case 0:
149 avg_en = false;
150 break;
151 case 2:
152 avg_sel = ADC_SAR_IP_AVG_4_CONV;
153 break;
154 case 3:
155 avg_sel = ADC_SAR_IP_AVG_8_CONV;
156 break;
157 case 4:
158 avg_sel = ADC_SAR_IP_AVG_16_CONV;
159 break;
160 case 5:
161 avg_sel = ADC_SAR_IP_AVG_32_CONV;
162 break;
163 default:
164 LOG_ERR("Unsupported oversampling value");
165 return -ENOTSUP;
166 }
167 Adc_Sar_Ip_SetAveraging(config->instance, avg_en, avg_sel);
168
169 return 0;
170 }
171 #endif
172
173 #if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
adc_nxp_s32_set_resolution(const struct device * dev,uint8_t adc_resol)174 static int adc_nxp_s32_set_resolution(const struct device *dev, uint8_t adc_resol)
175 {
176 const struct adc_nxp_s32_config *config = dev->config;
177 Adc_Sar_Ip_Resolution resolution;
178
179 switch (adc_resol) {
180 case 8:
181 resolution = ADC_SAR_IP_RESOLUTION_8;
182 break;
183 case 10:
184 resolution = ADC_SAR_IP_RESOLUTION_10;
185 break;
186 case 12:
187 resolution = ADC_SAR_IP_RESOLUTION_12;
188 break;
189 case 14:
190 resolution = ADC_SAR_IP_RESOLUTION_14;
191 break;
192 default:
193 LOG_ERR("Unsupported resolution");
194 return -ENOTSUP;
195 }
196 Adc_Sar_Ip_SetResolution(config->instance, resolution);
197
198 return 0;
199 }
200 #endif
201
adc_nxp_s32_start_read_async(const struct device * dev,const struct adc_sequence * sequence)202 static int adc_nxp_s32_start_read_async(const struct device *dev,
203 const struct adc_sequence *sequence)
204 {
205 const struct adc_nxp_s32_config *config = dev->config;
206 struct adc_nxp_s32_data *data = dev->data;
207 int error;
208 uint32_t mask;
209 uint8_t channel;
210
211 if (find_msb_set(sequence->channels) > data->num_channels) {
212 LOG_ERR("Channels out of bit map");
213 return -EINVAL;
214 }
215
216 error = adc_nxp_s32_validate_buffer_size(dev, sequence);
217 if (error) {
218 LOG_ERR("Buffer size isn't enough");
219 return -EINVAL;
220 }
221
222 #if FEATURE_ADC_HAS_AVERAGING
223 error = adc_nxp_s32_set_averaging(dev, sequence->oversampling);
224 if (error) {
225 return -ENOTSUP;
226 }
227 #else
228 if (sequence->oversampling) {
229 LOG_ERR("Oversampling can't be changed");
230 return -ENOTSUP;
231 }
232 #endif
233
234 #if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
235 error = adc_nxp_s32_set_resolution(dev, sequence->resolution);
236 if (error) {
237 return -ENOTSUP;
238 }
239 #else
240 if (sequence->resolution != ADC_SAR_IP_MAX_RESOLUTION) {
241 LOG_ERR("Resolution can't be changed");
242 return -ENOTSUP;
243 }
244 #endif
245
246 if (sequence->calibrate) {
247 #if FEATURE_ADC_HAS_CALIBRATION
248 error = Adc_Sar_Ip_DoCalibration(config->instance);
249 if (error) {
250 LOG_ERR("Error during calibration");
251 return -EIO;
252 }
253 #else
254 LOG_ERR("Unsupported calibration");
255 return -ENOTSUP;
256 #endif
257 }
258
259 for (int i = 0; i < data->num_channels; i++) {
260 mask = (sequence->channels >> i) & 0x1;
261 channel = ADC_NXP_S32_GROUPCHAN_2_PHYCHAN(config->group_channel, i);
262 if (mask) {
263 Adc_Sar_Ip_EnableChannelNotifications(config->instance,
264 channel, ADC_SAR_IP_CHAN_NOTIF_EOC);
265 Adc_Sar_Ip_EnableChannel(config->instance,
266 ADC_SAR_IP_CONV_CHAIN_NORMAL, channel);
267 } else {
268 Adc_Sar_Ip_DisableChannelNotifications(config->instance,
269 channel, ADC_SAR_IP_CHAN_NOTIF_EOC);
270 Adc_Sar_Ip_DisableChannel(config->instance,
271 ADC_SAR_IP_CONV_CHAIN_NORMAL, channel);
272 }
273 }
274
275 /* Save ADC sequence sampling buffer and its end pointer address */
276 data->buffer = sequence->buffer;
277 if (config->callback_select) {
278 data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t);
279 }
280
281 adc_context_start_read(&data->ctx, sequence);
282 error = adc_context_wait_for_completion(&data->ctx);
283
284 return error;
285 }
286
adc_context_start_sampling(struct adc_context * ctx)287 static void adc_context_start_sampling(struct adc_context *ctx)
288 {
289 struct adc_nxp_s32_data *data = CONTAINER_OF(ctx, struct adc_nxp_s32_data, ctx);
290 const struct adc_nxp_s32_config *config = data->dev->config;
291
292 data->mask_channels = ctx->sequence.channels;
293 data->repeat_buffer = data->buffer;
294
295 Adc_Sar_Ip_StartConversion(config->instance, ADC_SAR_IP_CONV_CHAIN_NORMAL);
296 }
297
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)298 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
299 bool repeat_sampling)
300 {
301 struct adc_nxp_s32_data *const data =
302 CONTAINER_OF(ctx, struct adc_nxp_s32_data, ctx);
303
304 if (repeat_sampling) {
305 data->buffer = data->repeat_buffer;
306 }
307 }
308
adc_nxp_s32_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)309 static int adc_nxp_s32_read_async(const struct device *dev,
310 const struct adc_sequence *sequence,
311 struct k_poll_signal *async)
312 {
313 struct adc_nxp_s32_data *data = dev->data;
314 int error = 0;
315
316 adc_context_lock(&data->ctx, async ? true : false, async);
317 error = adc_nxp_s32_start_read_async(dev, sequence);
318 adc_context_release(&data->ctx, error);
319
320 return error;
321 }
322
adc_nxp_s32_read(const struct device * dev,const struct adc_sequence * sequence)323 static int adc_nxp_s32_read(const struct device *dev,
324 const struct adc_sequence *sequence)
325 {
326 return adc_nxp_s32_read_async(dev, sequence, NULL);
327 }
328
adc_nxp_s32_isr(const struct device * dev)329 static void adc_nxp_s32_isr(const struct device *dev)
330 {
331 const struct adc_nxp_s32_config *config = dev->config;
332
333 Adc_Sar_Ip_IRQHandler(config->instance);
334 }
335
336 #define ADC_NXP_S32_DRIVER_API(n) \
337 static const struct adc_driver_api adc_nxp_s32_driver_api_##n = { \
338 .channel_setup = adc_nxp_s32_channel_setup, \
339 .read = adc_nxp_s32_read, \
340 IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_nxp_s32_read_async,))\
341 .ref_internal = DT_INST_PROP(n, vref_mv), \
342 };
343
344 #define ADC_NXP_S32_IRQ_CONFIG(n) \
345 static void adc_nxp_s32_adc_sar_config_func_##n(const struct device *dev)\
346 { \
347 IRQ_CONNECT(DT_INST_IRQN(n), \
348 DT_INST_IRQ(n, priority), \
349 adc_nxp_s32_isr, DEVICE_DT_INST_GET(n), 0); \
350 irq_enable(DT_INST_IRQN(n)); \
351 };
352
353 #define ADC_NXP_S32_CALLBACK_DEFINE(n) \
354 void adc_nxp_s32_normal_end_conversion_callback##n(const uint16 PhysicalChanId)\
355 { \
356 const struct device *dev = DEVICE_DT_INST_GET(n); \
357 const struct adc_nxp_s32_config *config = dev->config; \
358 struct adc_nxp_s32_data *data = dev->data; \
359 uint16_t result = 0; \
360 \
361 result = Adc_Sar_Ip_GetConvData(n, PhysicalChanId); \
362 LOG_DBG("End conversion, channel %d, group %d, result = %d", \
363 ADC_SAR_IP_CHAN_2_BIT(PhysicalChanId), \
364 config->group_channel, result); \
365 \
366 *data->buffer++ = result; \
367 data->mask_channels &= \
368 ~BIT(ADC_SAR_IP_CHAN_2_BIT(PhysicalChanId)); \
369 \
370 if (!data->mask_channels) { \
371 adc_context_on_sampling_done(&data->ctx, \
372 (struct device *)dev); \
373 } \
374 }; \
375 void adc_nxp_s32_normal_endchain_callback##n(void) \
376 { \
377 const struct device *dev = DEVICE_DT_INST_GET(n); \
378 const struct adc_nxp_s32_config *config = dev->config; \
379 struct adc_nxp_s32_data *data = dev->data; \
380 uint16_t result = 0; \
381 uint8_t channel; \
382 \
383 while (data->mask_channels) { \
384 channel = ADC_NXP_S32_GROUPCHAN_2_PHYCHAN( \
385 config->group_channel, \
386 (find_lsb_set(data->mask_channels)-1)); \
387 result = Adc_Sar_Ip_GetConvData(n, channel); \
388 LOG_DBG("End chain, channel %d, group %d, result = %d", \
389 ADC_SAR_IP_CHAN_2_BIT(channel), \
390 config->group_channel, result); \
391 if (data->buffer < data->buf_end) { \
392 *data->buffer++ = result; \
393 } \
394 data->mask_channels &= \
395 ~BIT(ADC_SAR_IP_CHAN_2_BIT(channel)); \
396 } \
397 \
398 adc_context_on_sampling_done(&data->ctx, (struct device *)dev); \
399 };
400
401 #define ADC_NXP_S32_INSTANCE_CHECK(indx, n) \
402 ((DT_INST_REG_ADDR(n) == IP_ADC_##indx##_BASE) ? indx : 0)
403 #define ADC_NXP_S32_GET_INSTANCE(n) \
404 LISTIFY(__DEBRACKET ADC_INSTANCE_COUNT, ADC_NXP_S32_INSTANCE_CHECK, (|), n)
405
406 #define ADC_NXP_S32_INIT_DEVICE(n) \
407 ADC_NXP_S32_DRIVER_API(n) \
408 ADC_NXP_S32_CALLBACK_DEFINE(n) \
409 ADC_NXP_S32_IRQ_CONFIG(n) \
410 COND_CODE_1(DT_INST_NUM_PINCTRL_STATES(n), \
411 (PINCTRL_DT_INST_DEFINE(n);), (EMPTY)) \
412 static const Adc_Sar_Ip_ConfigType adc_nxp_s32_default_config##n = \
413 { \
414 .ConvMode = ADC_SAR_IP_CONV_MODE_ONESHOT, \
415 .AdcResolution = ADC_SAR_IP_RESOLUTION_14, \
416 .HighSpeedConvEn = DT_INST_PROP(n, high_speed), \
417 .EndOfNormalChainNotification = \
418 adc_nxp_s32_normal_endchain_callback##n, \
419 .EndOfConvNotification = \
420 adc_nxp_s32_normal_end_conversion_callback##n, \
421 }; \
422 static struct adc_nxp_s32_data adc_nxp_s32_data_##n = { \
423 ADC_CONTEXT_INIT_TIMER(adc_nxp_s32_data_##n, ctx), \
424 ADC_CONTEXT_INIT_LOCK(adc_nxp_s32_data_##n, ctx), \
425 ADC_CONTEXT_INIT_SYNC(adc_nxp_s32_data_##n, ctx), \
426 }; \
427 static const struct adc_nxp_s32_config adc_nxp_s32_config_##n = { \
428 .base = (ADC_Type *)DT_INST_REG_ADDR(n), \
429 .instance = ADC_NXP_S32_GET_INSTANCE(n), \
430 .group_channel = DT_INST_ENUM_IDX(n, group_channel), \
431 .callback_select = DT_INST_ENUM_IDX(n, callback_select), \
432 .adc_cfg = (Adc_Sar_Ip_ConfigType *)&adc_nxp_s32_default_config##n,\
433 .irq_config_func = adc_nxp_s32_adc_sar_config_func_##n, \
434 .pin_cfg = COND_CODE_1(DT_INST_NUM_PINCTRL_STATES(n), \
435 (PINCTRL_DT_INST_DEV_CONFIG_GET(n)), (NULL)), \
436 }; \
437 DEVICE_DT_INST_DEFINE(n, \
438 &adc_nxp_s32_init, \
439 NULL, \
440 &adc_nxp_s32_data_##n, \
441 &adc_nxp_s32_config_##n, \
442 POST_KERNEL, \
443 CONFIG_ADC_INIT_PRIORITY, \
444 &adc_nxp_s32_driver_api_##n);
445
446 DT_INST_FOREACH_STATUS_OKAY(ADC_NXP_S32_INIT_DEVICE)
447