1 /*
2 * Copyright (c) 2020 Vestas Wind Systems A/S
3 * Copyright 2022, 2024 NXP
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT nxp_kinetis_acmp
9
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/sensor.h>
12 #include <zephyr/drivers/sensor/mcux_acmp.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/kernel.h>
15 #include <fsl_acmp.h>
16 #include <zephyr/drivers/pinctrl.h>
17 #include <zephyr/irq.h>
18
19 LOG_MODULE_REGISTER(mcux_acmp, CONFIG_SENSOR_LOG_LEVEL);
20
21 #define MCUX_ACMP_DAC_LEVELS 256
22 #define MCUX_ACMP_INPUT_CHANNELS 8
23
24 /*
25 * Ensure the underlying MCUX definitions match the driver shim
26 * assumptions. This saves us from converting between integers and
27 * MCUX enumerations for sensor attributes.
28 */
29 #if MCUX_ACMP_HAS_OFFSET
30 BUILD_ASSERT(kACMP_OffsetLevel0 == 0);
31 BUILD_ASSERT(kACMP_OffsetLevel1 == 1);
32 #endif /* MCUX_ACMP_HAS_OFFSET */
33 BUILD_ASSERT(kACMP_HysteresisLevel0 == 0);
34 BUILD_ASSERT(kACMP_HysteresisLevel1 == 1);
35 BUILD_ASSERT(kACMP_HysteresisLevel2 == 2);
36 BUILD_ASSERT(kACMP_HysteresisLevel3 == 3);
37 BUILD_ASSERT(kACMP_VrefSourceVin1 == 0);
38 BUILD_ASSERT(kACMP_VrefSourceVin2 == 1);
39 #if MCUX_ACMP_HAS_INPSEL || MCUX_ACMP_HAS_INNSEL
40 BUILD_ASSERT(kACMP_PortInputFromDAC == 0);
41 BUILD_ASSERT(kACMP_PortInputFromMux == 1);
42 #endif /* MCUX_ACMP_HAS_INPSEL || MCUX_ACMP_HAS_INNSEL */
43
44 /*
45 * prop New property name
46 * depr Deprecated property name
47 */
48 #define MCUX_ACMP_DT_INST_PROP(inst, prop, depr) \
49 COND_CODE_1( \
50 DT_INST_NODE_HAS_PROP(inst, prop), \
51 (DT_INST_PROP(inst, prop)), \
52 (DT_INST_PROP(inst, depr)) \
53 )
54
55 /*
56 * prop New property name
57 * depr Deprecated property name
58 */
59 #define MCUX_ACMP_DT_INST_PROP_OR(inst, prop, depr, default_value) \
60 COND_CODE_1( \
61 DT_INST_NODE_HAS_PROP(inst, prop) || DT_INST_NODE_HAS_PROP(inst, depr), \
62 (MCUX_ACMP_DT_INST_PROP(inst, prop, depr)), \
63 (default_value) \
64 )
65
66 #define MCUX_ACMP_DT_INST_ENABLE_SAMPLE(inst) \
67 MCUX_ACMP_DT_INST_PROP(inst, filter_enable_sample, nxp_enable_sample)
68
69 #define MCUX_ACMP_DT_INST_FILTER_COUNT(inst) \
70 MCUX_ACMP_DT_INST_PROP_OR(inst, filter_count, nxp_filter_count, 0)
71
72 #define MCUX_ACMP_DT_INST_FILTER_PERIOD(inst) \
73 MCUX_ACMP_DT_INST_PROP_OR(inst, filter_period, nxp_filter_period, 0)
74
75 #define MCUX_ACMP_DT_INST_HIGH_SPEED(inst) \
76 MCUX_ACMP_DT_INST_PROP(inst, enable_high_speed_mode, nxp_high_speed_mode)
77
78 #define MCUX_ACMP_DT_INST_USE_UNFILTERED_MODE(inst) \
79 MCUX_ACMP_DT_INST_PROP(inst, use_unfiltered_output, nxp_use_unfiltered_output)
80
81 #define MCUX_ACMP_DT_INST_USE_ENABLE_PIN_OUT(inst) \
82 MCUX_ACMP_DT_INST_PROP(inst, enable_pin_out, nxp_enable_output_pin)
83
84 #define MCUX_ACMP_DT_INST_ENABLE_WINDOW_MODE(inst) \
85 MCUX_ACMP_DT_INST_PROP(inst, enable_window_mode, nxp_window_mode)
86
87 struct mcux_acmp_config {
88 CMP_Type *base;
89 acmp_filter_config_t filter;
90 const struct pinctrl_dev_config *pincfg;
91 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
92 void (*irq_config_func)(const struct device *dev);
93 #endif /* CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
94 bool high_speed : 1;
95 bool unfiltered : 1;
96 bool output : 1;
97 bool window : 1;
98 };
99
100 struct mcux_acmp_data {
101 acmp_config_t config;
102 acmp_channel_config_t channels;
103 acmp_dac_config_t dac;
104 #if MCUX_ACMP_HAS_DISCRETE_MODE
105 acmp_discrete_mode_config_t discrete_config;
106 #endif
107 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
108 const struct device *dev;
109 sensor_trigger_handler_t rising_handler;
110 const struct sensor_trigger *rising_trigger;
111 sensor_trigger_handler_t falling_handler;
112 const struct sensor_trigger *falling_trigger;
113 struct k_work work;
114 volatile uint32_t status;
115 #endif /* CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
116 bool cout;
117 };
118
mcux_acmp_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)119 static int mcux_acmp_attr_set(const struct device *dev,
120 enum sensor_channel chan,
121 enum sensor_attribute attr,
122 const struct sensor_value *val)
123 {
124 const struct mcux_acmp_config *config = dev->config;
125 struct mcux_acmp_data *data = dev->data;
126 int32_t val1;
127
128 __ASSERT_NO_MSG(val != NULL);
129
130 if ((int16_t)chan != SENSOR_CHAN_MCUX_ACMP_OUTPUT) {
131 return -ENOTSUP;
132 }
133
134 if (val->val2 != 0) {
135 return -EINVAL;
136 }
137 val1 = val->val1;
138
139 switch ((int16_t)attr) {
140 #if MCUX_ACMP_HAS_OFFSET
141 case SENSOR_ATTR_MCUX_ACMP_OFFSET_LEVEL:
142 if (val1 >= kACMP_OffsetLevel0 &&
143 val1 <= kACMP_OffsetLevel1) {
144 LOG_DBG("offset = %d", val1);
145 data->config.offsetMode = val1;
146 ACMP_Init(config->base, &data->config);
147 ACMP_Enable(config->base, true);
148 } else {
149 return -EINVAL;
150 }
151 break;
152 #endif /* MCUX_ACMP_HAS_OFFSET */
153 #if MCUX_ACMP_HAS_HYSTCTR
154 case SENSOR_ATTR_MCUX_ACMP_HYSTERESIS_LEVEL:
155 if (val1 >= kACMP_HysteresisLevel0 &&
156 val1 <= kACMP_HysteresisLevel3) {
157 LOG_DBG("hysteresis = %d", val1);
158 data->config.hysteresisMode = val1;
159 ACMP_Init(config->base, &data->config);
160 ACMP_Enable(config->base, true);
161 } else {
162 return -EINVAL;
163 }
164 break;
165 #endif /* MCUX_ACMP_HAS_HYSTCTR */
166 case SENSOR_ATTR_MCUX_ACMP_DAC_VOLTAGE_REFERENCE:
167 if (val1 >= kACMP_VrefSourceVin1 &&
168 val1 <= kACMP_VrefSourceVin2) {
169 LOG_DBG("vref = %d", val1);
170 data->dac.referenceVoltageSource = val1;
171 ACMP_SetDACConfig(config->base, &data->dac);
172 } else {
173 return -EINVAL;
174 }
175 break;
176 case SENSOR_ATTR_MCUX_ACMP_DAC_VALUE:
177 if (val1 >= 0 && val1 < MCUX_ACMP_DAC_LEVELS) {
178 LOG_DBG("dac = %d", val1);
179 data->dac.DACValue = val1;
180 ACMP_SetDACConfig(config->base, &data->dac);
181 } else {
182 return -EINVAL;
183 }
184 break;
185 #if MCUX_ACMP_HAS_INPSEL
186 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_PORT_INPUT:
187 if (val1 >= kACMP_PortInputFromDAC &&
188 val1 <= kACMP_PortInputFromMux) {
189 LOG_DBG("pport = %d", val1);
190 data->channels.positivePortInput = val1;
191 ACMP_SetChannelConfig(config->base, &data->channels);
192 } else {
193 return -EINVAL;
194 }
195 break;
196 #endif /* MCUX_ACMP_HAS_INPSEL */
197 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_MUX_INPUT:
198 if (val1 >= 0 && val1 < MCUX_ACMP_INPUT_CHANNELS) {
199 LOG_DBG("pmux = %d", val1);
200 data->channels.plusMuxInput = val1;
201 ACMP_SetChannelConfig(config->base, &data->channels);
202 } else {
203 return -EINVAL;
204 }
205 break;
206 #if MCUX_ACMP_HAS_INNSEL
207 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_PORT_INPUT:
208 if (val1 >= kACMP_PortInputFromDAC &&
209 val1 <= kACMP_PortInputFromMux) {
210 LOG_DBG("nport = %d", val1);
211 data->channels.negativePortInput = val1;
212 ACMP_SetChannelConfig(config->base, &data->channels);
213 } else {
214 return -EINVAL;
215 }
216 break;
217 #endif /* MCUX_ACMP_HAS_INNSEL */
218 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_MUX_INPUT:
219 if (val1 >= 0 && val1 < MCUX_ACMP_INPUT_CHANNELS) {
220 LOG_DBG("nmux = %d", val1);
221 data->channels.minusMuxInput = val1;
222 ACMP_SetChannelConfig(config->base, &data->channels);
223 } else {
224 return -EINVAL;
225 }
226 break;
227 #if MCUX_ACMP_HAS_DISCRETE_MODE
228 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_DISCRETE_MODE:
229 if (val1 <= 1 && val1 >= 0) {
230 LOG_DBG("pdiscrete = %d", val1);
231 data->discrete_config.enablePositiveChannelDiscreteMode = val1;
232 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
233 } else {
234 return -EINVAL;
235 }
236 break;
237 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_DISCRETE_MODE:
238 if (val1 <= 1 && val1 >= 0) {
239 LOG_DBG("ndiscrete = %d", val1);
240 data->discrete_config.enableNegativeChannelDiscreteMode = val1;
241 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
242 } else {
243 return -EINVAL;
244 }
245 break;
246 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_CLOCK:
247 if (val1 <= kACMP_DiscreteClockFast && val1 >= kACMP_DiscreteClockSlow) {
248 LOG_DBG("discreteClk = %d", val1);
249 data->discrete_config.clockSource = val1;
250 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
251 } else {
252 return -EINVAL;
253 }
254 break;
255 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_ENABLE_RESISTOR_DIVIDER:
256 if (val1 <= 1 && val1 >= 0) {
257 LOG_DBG("discreteClk = %d", val1);
258 data->discrete_config.enableResistorDivider = val1;
259 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
260 } else {
261 return -EINVAL;
262 }
263 break;
264 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_SAMPLE_TIME:
265 if (val1 <= kACMP_DiscreteSampleTimeAs256T &&
266 val1 >= kACMP_DiscreteSampleTimeAs1T) {
267 LOG_DBG("discrete sampleTime = %d", val1);
268 data->discrete_config.sampleTime = val1;
269 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
270 } else {
271 return -EINVAL;
272 }
273 break;
274 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE1_TIME:
275 if (val1 <= kACMP_DiscretePhaseTimeAlt7 && val1 >= kACMP_DiscretePhaseTimeAlt0) {
276 LOG_DBG("discrete phase1Time = %d", val1);
277 data->discrete_config.phase1Time = val1;
278 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
279 } else {
280 return -EINVAL;
281 }
282 break;
283 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE2_TIME:
284 if (val1 <= kACMP_DiscretePhaseTimeAlt7 && val1 >= kACMP_DiscretePhaseTimeAlt0) {
285 LOG_DBG("discrete phase2Time = %d", val1);
286 data->discrete_config.phase2Time = val1;
287 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
288 } else {
289 return -EINVAL;
290 }
291 break;
292 #endif /* MCUX_ACMP_HAS_DISCRETE_MODE */
293 default:
294 return -ENOTSUP;
295 }
296
297 return 0;
298 }
299
mcux_acmp_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)300 static int mcux_acmp_attr_get(const struct device *dev,
301 enum sensor_channel chan,
302 enum sensor_attribute attr,
303 struct sensor_value *val)
304 {
305 struct mcux_acmp_data *data = dev->data;
306
307 __ASSERT_NO_MSG(val != NULL);
308
309 if ((int16_t)chan != SENSOR_CHAN_MCUX_ACMP_OUTPUT) {
310 return -ENOTSUP;
311 }
312
313 switch ((int16_t)attr) {
314 #if MCUX_ACMP_HAS_OFFSET
315 case SENSOR_ATTR_MCUX_ACMP_OFFSET_LEVEL:
316 val->val1 = data->config.offsetMode;
317 break;
318 #endif /* MCUX_ACMP_HAS_OFFSET */
319 #if MCUX_ACMP_HAS_HYSTCTR
320 case SENSOR_ATTR_MCUX_ACMP_HYSTERESIS_LEVEL:
321 val->val1 = data->config.hysteresisMode;
322 break;
323 #endif /* MCUX_ACMP_HAS_HYSTCTR */
324 case SENSOR_ATTR_MCUX_ACMP_DAC_VOLTAGE_REFERENCE:
325 val->val1 = data->dac.referenceVoltageSource;
326 break;
327 case SENSOR_ATTR_MCUX_ACMP_DAC_VALUE:
328 val->val1 = data->dac.DACValue;
329 break;
330 #if MCUX_ACMP_HAS_INPSEL
331 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_PORT_INPUT:
332 val->val1 = data->channels.positivePortInput;
333 break;
334 #endif /* MCUX_ACMP_HAS_INPSEL */
335 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_MUX_INPUT:
336 val->val1 = data->channels.plusMuxInput;
337 break;
338 #if MCUX_ACMP_HAS_INNSEL
339 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_PORT_INPUT:
340 val->val1 = data->channels.negativePortInput;
341 break;
342 #endif /* MCUX_ACMP_HAS_INNSEL */
343 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_MUX_INPUT:
344 val->val1 = data->channels.minusMuxInput;
345 break;
346 #if MCUX_ACMP_HAS_DISCRETE_MODE
347 case SENSOR_ATTR_MCUX_ACMP_POSITIVE_DISCRETE_MODE:
348 val->val1 = data->discrete_config.enablePositiveChannelDiscreteMode;
349 break;
350 case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_DISCRETE_MODE:
351 val->val1 = data->discrete_config.enableNegativeChannelDiscreteMode;
352 break;
353 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_CLOCK:
354 val->val1 = data->discrete_config.clockSource;
355 break;
356 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_ENABLE_RESISTOR_DIVIDER:
357 val->val1 = data->discrete_config.enableResistorDivider;
358 break;
359 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_SAMPLE_TIME:
360 val->val1 = data->discrete_config.sampleTime;
361 break;
362 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE1_TIME:
363 val->val1 = data->discrete_config.phase1Time;
364 break;
365 case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE2_TIME:
366 val->val1 = data->discrete_config.phase2Time;
367 break;
368 #endif /* MCUX_ACMP_HAS_DISCRETE_MODE */
369 default:
370 return -ENOTSUP;
371 }
372
373 val->val2 = 0;
374
375 return 0;
376 }
377
mcux_acmp_sample_fetch(const struct device * dev,enum sensor_channel chan)378 static int mcux_acmp_sample_fetch(const struct device *dev,
379 enum sensor_channel chan)
380 {
381 const struct mcux_acmp_config *config = dev->config;
382 struct mcux_acmp_data *data = dev->data;
383 uint32_t status;
384
385 __ASSERT_NO_MSG(val != NULL);
386
387 if (chan != SENSOR_CHAN_ALL &&
388 (int16_t)chan != SENSOR_CHAN_MCUX_ACMP_OUTPUT) {
389 return -ENOTSUP;
390 }
391
392 status = ACMP_GetStatusFlags(config->base);
393 data->cout = status & kACMP_OutputAssertEventFlag;
394
395 return 0;
396 }
397
mcux_acmp_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)398 static int mcux_acmp_channel_get(const struct device *dev,
399 enum sensor_channel chan,
400 struct sensor_value *val)
401 {
402 struct mcux_acmp_data *data = dev->data;
403
404 __ASSERT_NO_MSG(val != NULL);
405
406 if ((int16_t)chan != SENSOR_CHAN_MCUX_ACMP_OUTPUT) {
407 return -ENOTSUP;
408 }
409
410 val->val1 = data->cout ? 1 : 0;
411 val->val2 = 0;
412
413 return 0;
414 }
415
416 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
mcux_acmp_trigger_set(const struct device * dev,const struct sensor_trigger * trig,sensor_trigger_handler_t handler)417 static int mcux_acmp_trigger_set(const struct device *dev,
418 const struct sensor_trigger *trig,
419 sensor_trigger_handler_t handler)
420 {
421 struct mcux_acmp_data *data = dev->data;
422
423 __ASSERT_NO_MSG(trig != NULL);
424
425 if ((int16_t)trig->chan != SENSOR_CHAN_MCUX_ACMP_OUTPUT) {
426 return -ENOTSUP;
427 }
428
429 switch ((int16_t)trig->type) {
430 case SENSOR_TRIG_MCUX_ACMP_OUTPUT_RISING:
431 data->rising_handler = handler;
432 data->rising_trigger = trig;
433 break;
434 case SENSOR_TRIG_MCUX_ACMP_OUTPUT_FALLING:
435 data->falling_handler = handler;
436 data->falling_trigger = trig;
437 break;
438 default:
439 return -ENOTSUP;
440 }
441
442 return 0;
443 }
444
mcux_acmp_trigger_work_handler(struct k_work * item)445 static void mcux_acmp_trigger_work_handler(struct k_work *item)
446 {
447 const struct sensor_trigger *trigger;
448 struct mcux_acmp_data *data =
449 CONTAINER_OF(item, struct mcux_acmp_data, work);
450 sensor_trigger_handler_t handler = NULL;
451
452 if (data->status & kACMP_OutputRisingEventFlag) {
453 handler = data->rising_handler;
454 trigger = data->rising_trigger;
455 } else if (data->status & kACMP_OutputFallingEventFlag) {
456 handler = data->falling_handler;
457 trigger = data->falling_trigger;
458 }
459
460 if (handler) {
461 handler(data->dev, trigger);
462 }
463 }
464
mcux_acmp_isr(const struct device * dev)465 static void mcux_acmp_isr(const struct device *dev)
466 {
467 const struct mcux_acmp_config *config = dev->config;
468 struct mcux_acmp_data *data = dev->data;
469
470 data->status = ACMP_GetStatusFlags(config->base);
471 ACMP_ClearStatusFlags(config->base, data->status);
472
473 LOG_DBG("isr status = 0x%08x", data->status);
474
475 k_work_submit(&data->work);
476 }
477 #endif /* CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
478
mcux_acmp_init(const struct device * dev)479 static int mcux_acmp_init(const struct device *dev)
480 {
481 const struct mcux_acmp_config *config = dev->config;
482 struct mcux_acmp_data *data = dev->data;
483 int err;
484
485 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
486 if (err) {
487 return err;
488 }
489
490 ACMP_GetDefaultConfig(&data->config);
491 data->config.enableHighSpeed = config->high_speed;
492 data->config.useUnfilteredOutput = config->unfiltered;
493 data->config.enablePinOut = config->output;
494 ACMP_Init(config->base, &data->config);
495
496 #if MCUX_ACMP_HAS_DISCRETE_MODE
497 ACMP_GetDefaultDiscreteModeConfig(&data->discrete_config);
498 ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config);
499 #endif
500
501 ACMP_EnableWindowMode(config->base, config->window);
502 ACMP_SetFilterConfig(config->base, &config->filter);
503 ACMP_SetChannelConfig(config->base, &data->channels);
504
505 /* Disable DAC */
506 ACMP_SetDACConfig(config->base, NULL);
507
508 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
509 data->dev = dev;
510 k_work_init(&data->work, mcux_acmp_trigger_work_handler);
511
512 config->irq_config_func(dev);
513 ACMP_EnableInterrupts(config->base,
514 kACMP_OutputRisingInterruptEnable |
515 kACMP_OutputFallingInterruptEnable);
516 #endif /* CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
517
518 ACMP_Enable(config->base, true);
519
520 return 0;
521 }
522
523 static DEVICE_API(sensor, mcux_acmp_driver_api) = {
524 .attr_set = mcux_acmp_attr_set,
525 .attr_get = mcux_acmp_attr_get,
526 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
527 .trigger_set = mcux_acmp_trigger_set,
528 #endif /* CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
529 .sample_fetch = mcux_acmp_sample_fetch,
530 .channel_get = mcux_acmp_channel_get,
531 };
532
533 #define MCUX_ACMP_DECLARE_CONFIG(n, config_func_init) \
534 static const struct mcux_acmp_config mcux_acmp_config_##n = { \
535 .base = (CMP_Type *)DT_INST_REG_ADDR(n), \
536 .filter = { \
537 .enableSample = MCUX_ACMP_DT_INST_ENABLE_SAMPLE(n), \
538 .filterCount = MCUX_ACMP_DT_INST_FILTER_COUNT(n), \
539 .filterPeriod = MCUX_ACMP_DT_INST_FILTER_PERIOD(n), \
540 }, \
541 .high_speed = MCUX_ACMP_DT_INST_HIGH_SPEED(n), \
542 .unfiltered = MCUX_ACMP_DT_INST_USE_UNFILTERED_MODE(n), \
543 .output = MCUX_ACMP_DT_INST_USE_ENABLE_PIN_OUT(n), \
544 .window = MCUX_ACMP_DT_INST_ENABLE_WINDOW_MODE(n), \
545 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
546 config_func_init \
547 }
548
549 #ifdef CONFIG_SENSOR_MCUX_ACMP_TRIGGER
550 #define MCUX_ACMP_CONFIG_FUNC(n) \
551 static void mcux_acmp_config_func_##n(const struct device *dev) \
552 { \
553 IRQ_CONNECT(DT_INST_IRQN(n), \
554 DT_INST_IRQ(n, priority), \
555 mcux_acmp_isr, \
556 DEVICE_DT_INST_GET(n), 0); \
557 irq_enable(DT_INST_IRQN(n)); \
558 }
559 #define MCUX_ACMP_CONFIG_FUNC_INIT(n) \
560 .irq_config_func = mcux_acmp_config_func_##n
561 #define MCUX_ACMP_INIT_CONFIG(n) \
562 MCUX_ACMP_DECLARE_CONFIG(n, MCUX_ACMP_CONFIG_FUNC_INIT(n))
563 #else /* !CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
564 #define MCUX_ACMP_CONFIG_FUNC(n)
565 #define MCUX_ACMP_CONFIG_FUNC_INIT
566 #define MCUX_ACMP_INIT_CONFIG(n) \
567 MCUX_ACMP_DECLARE_CONFIG(n, MCUX_ACMP_CONFIG_FUNC_INIT)
568 #endif /* !CONFIG_SENSOR_MCUX_ACMP_TRIGGER */
569
570 #define MCUX_ACMP_INIT(n) \
571 static struct mcux_acmp_data mcux_acmp_data_##n; \
572 \
573 static const struct mcux_acmp_config mcux_acmp_config_##n; \
574 \
575 PINCTRL_DT_INST_DEFINE(n); \
576 \
577 SENSOR_DEVICE_DT_INST_DEFINE(n, &mcux_acmp_init, \
578 NULL, \
579 &mcux_acmp_data_##n, \
580 &mcux_acmp_config_##n, POST_KERNEL, \
581 CONFIG_SENSOR_INIT_PRIORITY, \
582 &mcux_acmp_driver_api); \
583 MCUX_ACMP_CONFIG_FUNC(n) \
584 MCUX_ACMP_INIT_CONFIG(n);
585
586 DT_INST_FOREACH_STATUS_OKAY(MCUX_ACMP_INIT)
587