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