1 /*
2  * Copyright 2023-2024 NXP
3  * Copyright (c) 2020 Toby Firth
4  *
5  * Based on adc_mcux_adc16.c and adc_mcux_adc12.c, which are:
6  * Copyright (c) 2017-2018, NXP
7  * Copyright (c) 2019 Vestas Wind Systems A/S
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #define DT_DRV_COMPAT nxp_lpc_lpadc
13 
14 #include <errno.h>
15 #include <zephyr/drivers/adc.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/drivers/regulator.h>
18 #include <zephyr/drivers/clock_control.h>
19 #include <zephyr/drivers/pinctrl.h>
20 
21 #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL
22 #include <zephyr/logging/log.h>
23 #include <zephyr/irq.h>
24 #include <fsl_lpadc.h>
25 LOG_MODULE_REGISTER(nxp_mcux_lpadc);
26 
27 /*
28  * Currently, no instance of the ADC IP has more than
29  * 8 channels present. Therefore, we treat channels
30  * with an index 8 or higher as a side b channel, with
31  * the channel index given by channel_num % 8
32  */
33 #define CHANNELS_PER_SIDE 0x8
34 
35 #define ADC_CONTEXT_USES_KERNEL_TIMER
36 #include "adc_context.h"
37 
38 struct mcux_lpadc_config {
39 	ADC_Type *base;
40 	lpadc_reference_voltage_source_t voltage_ref;
41 	uint8_t power_level;
42 	uint32_t calibration_average;
43 	uint32_t offset_a;
44 	uint32_t offset_b;
45 	void (*irq_config_func)(const struct device *dev);
46 	const struct pinctrl_dev_config *pincfg;
47 	const struct device *ref_supplies;
48 	const struct device *clock_dev;
49 	clock_control_subsys_t clock_subsys;
50 	int32_t ref_supply_val;
51 };
52 
53 struct mcux_lpadc_data {
54 	const struct device *dev;
55 	struct adc_context ctx;
56 	uint16_t *buffer;
57 	uint16_t *repeat_buffer;
58 	uint32_t channels;
59 	lpadc_conv_command_config_t cmd_config[CONFIG_LPADC_CHANNEL_COUNT];
60 };
61 
mcux_lpadc_acquisition_time_setup(const struct device * dev,uint16_t acq_time,lpadc_conv_command_config_t * cmd)62 static int mcux_lpadc_acquisition_time_setup(const struct device *dev, uint16_t acq_time,
63 					     lpadc_conv_command_config_t *cmd)
64 {
65 	const struct mcux_lpadc_config *config = dev->config;
66 	uint32_t adc_freq_hz = 0;
67 	uint32_t conversion_factor = 0;
68 	uint32_t acquisition_time_value = ADC_ACQ_TIME_VALUE(acq_time);
69 	uint8_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(acq_time);
70 
71 	if (ADC_ACQ_TIME_DEFAULT == acquisition_time_value) {
72 		return 0;
73 	}
74 
75 	/* If the acquisition time is expressed in ADC ticks, then directly compare
76 	 * the acquisition time with configuration items (3, 5, 7, etc. ADC ticks)
77 	 * supported by the LPADC. The conversion factor is set to 1 (means do not need
78 	 * to convert configuration items from ADC ticks to nanoseconds).
79 	 * If the acquisition time is expressed in microseconds or nanoseconds, First
80 	 * calculate the ADC cycle based on the ADC clock, then convert the configuration
81 	 * items supported by LPADC into nanoseconds, and finally compare the acquisition
82 	 * time with configuration items. The conversion factor is equal to the ADC cycle
83 	 * (means convert configuration items from ADC ticks to nanoseconds).
84 	 */
85 	if (ADC_ACQ_TIME_TICKS == acquisition_time_unit) {
86 		conversion_factor = 1;
87 	} else {
88 		if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &adc_freq_hz)) {
89 			LOG_ERR("Get clock rate failed");
90 			return -EINVAL;
91 		}
92 
93 		conversion_factor = 1000000000 / adc_freq_hz;
94 
95 		if (ADC_ACQ_TIME_MICROSECONDS == acquisition_time_unit) {
96 			acquisition_time_value *= 1000;
97 		}
98 	}
99 
100 	if ((3 * conversion_factor) >= acquisition_time_value) {
101 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK3;
102 	} else if ((5 * conversion_factor) >= acquisition_time_value) {
103 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK5;
104 	} else if ((7 * conversion_factor) >= acquisition_time_value) {
105 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK7;
106 	} else if ((11 * conversion_factor) >= acquisition_time_value) {
107 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK11;
108 	} else if ((19 * conversion_factor) >= acquisition_time_value) {
109 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK19;
110 	} else if ((35 * conversion_factor) >= acquisition_time_value) {
111 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK35;
112 	} else if ((67 * conversion_factor) >= acquisition_time_value) {
113 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK67;
114 	} else if ((131 * conversion_factor) >= acquisition_time_value) {
115 		cmd->sampleTimeMode = kLPADC_SampleTimeADCK131;
116 	} else {
117 		return -EINVAL;
118 	}
119 
120 	return 0;
121 }
122 
mcux_lpadc_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)123 static int mcux_lpadc_channel_setup(const struct device *dev,
124 				const struct adc_channel_cfg *channel_cfg)
125 {
126 	const struct mcux_lpadc_config *config = dev->config;
127 	const struct device *regulator = config->ref_supplies;
128 	int32_t vref_uv = config->ref_supply_val * 1000;
129 	struct mcux_lpadc_data *data = dev->data;
130 	lpadc_conv_command_config_t *cmd;
131 	uint8_t channel_side;
132 	uint8_t channel_num;
133 	int err;
134 
135 	/* User may configure maximum number of active channels */
136 	if (channel_cfg->channel_id >= CONFIG_LPADC_CHANNEL_COUNT) {
137 		LOG_ERR("Channel %d is not valid", channel_cfg->channel_id);
138 		return -EINVAL;
139 	}
140 
141 	/* Select ADC CMD register to configure based off channel ID */
142 	cmd = &data->cmd_config[channel_cfg->channel_id];
143 
144 	/* If bit 5 of input_positive is set, then channel side B is used */
145 	channel_side = 0x20 & channel_cfg->input_positive;
146 	/* Channel number is selected by lower 4 bits of input_positive */
147 	channel_num = ADC_CMDL_ADCH(channel_cfg->input_positive);
148 
149 	LOG_DBG("Channel num: %u, channel side: %c", channel_num,
150 		channel_side == 0 ? 'A' : 'B');
151 
152 	LPADC_GetDefaultConvCommandConfig(cmd);
153 
154 	/* Configure LPADC acquisition time. */
155 	if (mcux_lpadc_acquisition_time_setup(dev, channel_cfg->acquisition_time, cmd)) {
156 		LOG_ERR("LPADC acquisition time setting failed");
157 		return -EINVAL;
158 	}
159 
160 #if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && \
161 	(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U))
162 	if (channel_cfg->differential) {
163 		/* Channel pairs must match in differential mode */
164 		if ((ADC_CMDL_ADCH(channel_cfg->input_positive)) !=
165 		   (ADC_CMDL_ADCH(channel_cfg->input_negative))) {
166 			return -ENOTSUP;
167 		}
168 
169 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
170 		/* Check to see which channel is the positive input */
171 		if (channel_cfg->input_positive & 0x20) {
172 			/* Channel B is positive side */
173 			cmd->sampleChannelMode =
174 				kLPADC_SampleChannelDiffBothSideBA;
175 		} else {
176 			/* Channel A is positive side */
177 			cmd->sampleChannelMode =
178 				kLPADC_SampleChannelDiffBothSideAB;
179 		}
180 #else
181 		cmd->sampleChannelMode = kLPADC_SampleChannelDiffBothSide;
182 #endif
183 	} else if (channel_side != 0) {
184 		cmd->sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
185 	} else {
186 		/* Default value for sampleChannelMode is SideA */
187 	}
188 #endif
189 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
190 	/*
191 	 * The true scaling factor used by the LPADC is 30/64, instead of
192 	 * 1/2. Select 1/2 as this is the closest scaling factor available
193 	 * in Zephyr.
194 	 */
195 	if (channel_cfg->gain == ADC_GAIN_1_2) {
196 		LOG_INF("Channel gain of 30/64 selected");
197 		cmd->sampleScaleMode = kLPADC_SamplePartScale;
198 	} else if (channel_cfg->gain == ADC_GAIN_1) {
199 		cmd->sampleScaleMode = kLPADC_SampleFullScale;
200 	} else {
201 		LOG_ERR("Invalid channel gain");
202 		return -EINVAL;
203 	}
204 #else
205 	if (channel_cfg->gain != ADC_GAIN_1) {
206 		LOG_ERR("Invalid channel gain");
207 		return -EINVAL;
208 	}
209 #endif
210 
211 	/*
212 	 * ADC_REF_EXTERNAL1: Use SoC internal regulator as LPADC reference voltage.
213 	 * ADC_REF_EXTERNAL0: Use other voltage source (maybe also within the SoCs)
214 	 * as LPADC reference voltage, like VREFH, VDDA, etc.
215 	 */
216 	if (channel_cfg->reference == ADC_REF_EXTERNAL1) {
217 		LOG_DBG("ref external1");
218 		if (regulator != NULL) {
219 			err = regulator_set_voltage(regulator, vref_uv, vref_uv);
220 			if (err < 0) {
221 				return err;
222 			}
223 		} else {
224 			return -EINVAL;
225 		}
226 	} else if (channel_cfg->reference == ADC_REF_EXTERNAL0) {
227 		LOG_DBG("ref external0");
228 	} else {
229 		LOG_DBG("ref not support");
230 		return -EINVAL;
231 	}
232 
233 	cmd->channelNumber = channel_num;
234 	return 0;
235 }
236 
mcux_lpadc_start_read(const struct device * dev,const struct adc_sequence * sequence)237 static int mcux_lpadc_start_read(const struct device *dev,
238 		 const struct adc_sequence *sequence)
239 {
240 	const struct mcux_lpadc_config *config = dev->config;
241 	struct mcux_lpadc_data *data = dev->data;
242 	lpadc_hardware_average_mode_t hardware_average_mode;
243 	uint8_t channel, last_enabled;
244 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) \
245 	&& FSL_FEATURE_LPADC_HAS_CMDL_MODE
246 	lpadc_conversion_resolution_mode_t resolution_mode;
247 
248 	switch (sequence->resolution) {
249 	case 12:
250 	case 13:
251 		resolution_mode = kLPADC_ConversionResolutionStandard;
252 		break;
253 	case 16:
254 		resolution_mode = kLPADC_ConversionResolutionHigh;
255 		break;
256 	default:
257 		LOG_ERR("Unsupported resolution %d", sequence->resolution);
258 		return -ENOTSUP;
259 	}
260 #else
261 	/* If FSL_FEATURE_LPADC_HAS_CMDL_MODE is not defined
262 	   only 12/13 bit resolution is supported. */
263 	if (sequence->resolution != 12 && sequence->resolution != 13) {
264 		LOG_ERR("Unsupported resolution %d", sequence->resolution);
265 		return -ENOTSUP;
266 	}
267 #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
268 
269 	switch (sequence->oversampling) {
270 	case 0:
271 		hardware_average_mode = kLPADC_HardwareAverageCount1;
272 		break;
273 	case 1:
274 		hardware_average_mode = kLPADC_HardwareAverageCount2;
275 		break;
276 	case 2:
277 		hardware_average_mode = kLPADC_HardwareAverageCount4;
278 		break;
279 	case 3:
280 		hardware_average_mode = kLPADC_HardwareAverageCount8;
281 		break;
282 	case 4:
283 		hardware_average_mode = kLPADC_HardwareAverageCount16;
284 		break;
285 	case 5:
286 		hardware_average_mode = kLPADC_HardwareAverageCount32;
287 		break;
288 	case 6:
289 		hardware_average_mode = kLPADC_HardwareAverageCount64;
290 		break;
291 	case 7:
292 		hardware_average_mode = kLPADC_HardwareAverageCount128;
293 		break;
294 	default:
295 		LOG_ERR("Unsupported oversampling value %d",
296 			sequence->oversampling);
297 		return -ENOTSUP;
298 	}
299 
300 	/*
301 	 * Now, look at the selected channels to determine which ADC channels
302 	 * we need to configure, and set those channels up.
303 	 *
304 	 * Since this ADC supports chaining channels in hardware, we will
305 	 * start with the highest channel ID and work downwards, chaining
306 	 * channels as we go.
307 	 */
308 	channel = CONFIG_LPADC_CHANNEL_COUNT;
309 	last_enabled = 0;
310 	while (channel-- > 0) {
311 		if (sequence->channels & BIT(channel)) {
312 			/* Setup this channel command */
313 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
314 			data->cmd_config[channel].conversionResolutionMode =
315 				resolution_mode;
316 #endif
317 			data->cmd_config[channel].hardwareAverageMode =
318 				hardware_average_mode;
319 			if (last_enabled) {
320 				/* Chain channel */
321 				data->cmd_config[channel].chainedNextCommandNumber =
322 					last_enabled + 1;
323 				LOG_DBG("Chaining channel %u to %u",
324 					channel, last_enabled);
325 			} else {
326 				/* End of chain */
327 				data->cmd_config[channel].chainedNextCommandNumber = 0;
328 			}
329 			last_enabled = channel;
330 			LPADC_SetConvCommandConfig(config->base,
331 				channel + 1, &data->cmd_config[channel]);
332 		}
333 	};
334 
335 	data->buffer = sequence->buffer;
336 
337 	adc_context_start_read(&data->ctx, sequence);
338 	int error = adc_context_wait_for_completion(&data->ctx);
339 
340 	return error;
341 }
342 
mcux_lpadc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)343 static int mcux_lpadc_read_async(const struct device *dev,
344 			const struct adc_sequence *sequence,
345 			struct k_poll_signal *async)
346 {
347 	struct mcux_lpadc_data *data = dev->data;
348 	int error;
349 
350 	adc_context_lock(&data->ctx, async ? true : false, async);
351 	error = mcux_lpadc_start_read(dev, sequence);
352 	adc_context_release(&data->ctx, error);
353 
354 	return error;
355 }
356 
mcux_lpadc_read(const struct device * dev,const struct adc_sequence * sequence)357 static int mcux_lpadc_read(const struct device *dev,
358 		   const struct adc_sequence *sequence)
359 {
360 	return mcux_lpadc_read_async(dev, sequence, NULL);
361 }
362 
mcux_lpadc_start_channel(const struct device * dev)363 static void mcux_lpadc_start_channel(const struct device *dev)
364 {
365 	const struct mcux_lpadc_config *config = dev->config;
366 	struct mcux_lpadc_data *data = dev->data;
367 	lpadc_conv_trigger_config_t trigger_config;
368 	uint8_t first_channel;
369 
370 	first_channel = find_lsb_set(data->channels) - 1;
371 
372 	LOG_DBG("Starting channel %d, input %d", first_channel,
373 		data->cmd_config[first_channel].channelNumber);
374 
375 	LPADC_GetDefaultConvTriggerConfig(&trigger_config);
376 
377 	trigger_config.targetCommandId = first_channel + 1;
378 
379 	/* configures trigger0. */
380 	LPADC_SetConvTriggerConfig(config->base, 0, &trigger_config);
381 
382 	/* 1 is trigger0 mask. */
383 	LPADC_DoSoftwareTrigger(config->base, 1);
384 }
385 
adc_context_start_sampling(struct adc_context * ctx)386 static void adc_context_start_sampling(struct adc_context *ctx)
387 {
388 	struct mcux_lpadc_data *data =
389 	CONTAINER_OF(ctx, struct mcux_lpadc_data, ctx);
390 
391 	data->channels = ctx->sequence.channels;
392 	data->repeat_buffer = data->buffer;
393 
394 	mcux_lpadc_start_channel(data->dev);
395 }
396 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)397 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
398 			  bool repeat_sampling)
399 {
400 	struct mcux_lpadc_data *data =
401 		CONTAINER_OF(ctx, struct mcux_lpadc_data, ctx);
402 
403 	if (repeat_sampling) {
404 		data->buffer = data->repeat_buffer;
405 	}
406 }
407 
mcux_lpadc_isr(const struct device * dev)408 static void mcux_lpadc_isr(const struct device *dev)
409 {
410 	const struct mcux_lpadc_config *config = dev->config;
411 	struct mcux_lpadc_data *data = dev->data;
412 	ADC_Type *base = config->base;
413 
414 	lpadc_conv_result_t conv_result;
415 	lpadc_sample_channel_mode_t conv_mode;
416 	int16_t result;
417 	uint16_t channel;
418 
419 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) \
420 	&& (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
421 	LPADC_GetConvResult(base, &conv_result, 0U);
422 #else
423 	LPADC_GetConvResult(base, &conv_result);
424 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
425 
426 	channel = conv_result.commandIdSource - 1;
427 	LOG_DBG("Finished channel %d. Raw result is 0x%04x",
428 		channel, conv_result.convValue);
429 	/*
430 	 * For 12 or 13 bit resolution the LSBs will be 0, so a bit shift
431 	 * is needed. For differential modes, the ADC conversion to
432 	 * millivolts expects to use a shift one less than the resolution.
433 	 *
434 	 * For 16 bit modes, the adc value can be left untouched. ADC
435 	 * API should treat the value as signed if the channel is
436 	 * in differential mode
437 	 */
438 	conv_mode = data->cmd_config[channel].sampleChannelMode;
439 	if (data->ctx.sequence.resolution < 15) {
440 		result = ((conv_result.convValue >> 3) & 0xFFF);
441 #if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && \
442 	(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U))
443 #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
444 		if (conv_mode == kLPADC_SampleChannelDiffBothSideAB ||
445 		    conv_mode == kLPADC_SampleChannelDiffBothSideBA) {
446 #else
447 		if (conv_mode == kLPADC_SampleChannelDiffBothSide) {
448 #endif
449 			if ((conv_result.convValue & 0x8000)) {
450 				/* 13 bit mode, MSB is sign bit. (2's complement) */
451 				result -= 0x1000;
452 			}
453 		}
454 		*data->buffer++ = result;
455 #endif
456 	} else {
457 		*data->buffer++ = conv_result.convValue;
458 	}
459 
460 
461 	data->channels &= ~BIT(channel);
462 
463 	/*
464 	 * Hardware will automatically continue sampling, so no need
465 	 * to issue new trigger
466 	 */
467 	if (data->channels == 0) {
468 		adc_context_on_sampling_done(&data->ctx, dev);
469 	}
470 }
471 
472 static int mcux_lpadc_init(const struct device *dev)
473 {
474 	const struct mcux_lpadc_config *config = dev->config;
475 	struct mcux_lpadc_data *data = dev->data;
476 	ADC_Type *base = config->base;
477 	lpadc_config_t adc_config;
478 	int err;
479 
480 	err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
481 	if (err) {
482 		return err;
483 	}
484 
485 	/* Enable necessary regulators */
486 	const struct device *regulator = config->ref_supplies;
487 
488 	if (regulator != NULL) {
489 		err = regulator_enable(regulator);
490 		if (err) {
491 			return err;
492 		}
493 	}
494 
495 	LPADC_GetDefaultConfig(&adc_config);
496 
497 	adc_config.enableAnalogPreliminary = true;
498 	adc_config.referenceVoltageSource = config->voltage_ref;
499 
500 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) \
501 	&& FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
502 	adc_config.conversionAverageMode = config->calibration_average;
503 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
504 
505 #if !(DT_ANY_INST_HAS_PROP_STATUS_OKAY(no_power_level))
506 		adc_config.powerLevelMode = config->power_level;
507 #endif
508 
509 	LPADC_Init(base, &adc_config);
510 
511 	/* Do ADC calibration. */
512 #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) \
513 	&& FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
514 #if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) \
515 	&& FSL_FEATURE_LPADC_HAS_OFSTRIM
516 	/* Request offset calibration. */
517 #if defined(CONFIG_LPADC_DO_OFFSET_CALIBRATION) \
518 	&& CONFIG_LPADC_DO_OFFSET_CALIBRATION
519 	LPADC_DoOffsetCalibration(base);
520 #else
521 	LPADC_SetOffsetValue(base,
522 			config->offset_a,
523 			config->offset_b);
524 #endif  /* DEMO_LPADC_DO_OFFSET_CALIBRATION */
525 #endif  /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
526 	/* Request gain calibration. */
527 	LPADC_DoAutoCalibration(base);
528 #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */
529 
530 #if (defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) \
531 	&& FSL_FEATURE_LPADC_HAS_CFG_CALOFS)
532 	/* Do auto calibration. */
533 	LPADC_DoAutoCalibration(base);
534 #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
535 
536 /* Enable the watermark interrupt. */
537 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) \
538 	&& (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
539 	LPADC_EnableInterrupts(base, kLPADC_FIFO0WatermarkInterruptEnable);
540 #else
541 	LPADC_EnableInterrupts(base, kLPADC_FIFOWatermarkInterruptEnable);
542 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
543 
544 	config->irq_config_func(dev);
545 	data->dev = dev;
546 
547 	adc_context_unlock_unconditionally(&data->ctx);
548 
549 	return 0;
550 }
551 
552 static DEVICE_API(adc, mcux_lpadc_driver_api) = {
553 	.channel_setup = mcux_lpadc_channel_setup,
554 	.read = mcux_lpadc_read,
555 #ifdef CONFIG_ADC_ASYNC
556 	.read_async = mcux_lpadc_read_async,
557 #endif
558 };
559 
560 #define LPADC_MCUX_INIT(n)						\
561 									\
562 	static void mcux_lpadc_config_func_##n(const struct device *dev);	\
563 									\
564 	PINCTRL_DT_INST_DEFINE(n);						\
565 	static const struct mcux_lpadc_config mcux_lpadc_config_##n = {	\
566 		.base = (ADC_Type *)DT_INST_REG_ADDR(n),	\
567 		.voltage_ref =	DT_INST_PROP(n, voltage_ref),	\
568 		.calibration_average = DT_INST_ENUM_IDX_OR(n, calibration_average, 0),	\
569 		.power_level = DT_INST_PROP_OR(n, power_level, 0),	\
570 		.offset_a = DT_INST_PROP(n, offset_value_a),	\
571 		.offset_b = DT_INST_PROP(n, offset_value_b),	\
572 		.irq_config_func = mcux_lpadc_config_func_##n,				\
573 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),			\
574 		.ref_supplies = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, nxp_references),\
575 						(DEVICE_DT_GET(DT_PHANDLE(DT_DRV_INST(n),\
576 						nxp_references))), (NULL)),\
577 		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)),                                \
578 		.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\
579 		.ref_supply_val = COND_CODE_1(\
580 						DT_INST_NODE_HAS_PROP(n, nxp_references),\
581 						(DT_PHA(DT_DRV_INST(n), nxp_references, vref_mv)), \
582 						(0)),\
583 	};									\
584 	static struct mcux_lpadc_data mcux_lpadc_data_##n = {	\
585 		ADC_CONTEXT_INIT_TIMER(mcux_lpadc_data_##n, ctx),	\
586 		ADC_CONTEXT_INIT_LOCK(mcux_lpadc_data_##n, ctx),	\
587 		ADC_CONTEXT_INIT_SYNC(mcux_lpadc_data_##n, ctx),	\
588 	};														\
589 										\
590 	DEVICE_DT_INST_DEFINE(n,						\
591 		&mcux_lpadc_init, NULL, &mcux_lpadc_data_##n,			\
592 		&mcux_lpadc_config_##n, POST_KERNEL,				\
593 		CONFIG_ADC_INIT_PRIORITY,					\
594 		&mcux_lpadc_driver_api);							\
595 										\
596 	static void mcux_lpadc_config_func_##n(const struct device *dev)	\
597 	{									\
598 		IRQ_CONNECT(DT_INST_IRQN(n),					\
599 			DT_INST_IRQ(n, priority), mcux_lpadc_isr,	\
600 			DEVICE_DT_INST_GET(n), 0);				\
601 										\
602 		irq_enable(DT_INST_IRQN(n));					\
603 	}	\
604 										\
605 	BUILD_ASSERT((DT_INST_PROP_OR(n, power_level, 0) >= 0) && \
606 		(DT_INST_PROP_OR(n, power_level, 0) <= 3), "power_level: wrong value");
607 
608 DT_INST_FOREACH_STATUS_OKAY(LPADC_MCUX_INIT)
609