1 /*
2 * Copyright 2022-2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_s32_gpio
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/gpio/gpio_utils.h>
12 #include <zephyr/drivers/pinctrl.h>
13 #include <zephyr/dt-bindings/gpio/nxp-s32-gpio.h>
14 #include <zephyr/logging/log.h>
15
16 LOG_MODULE_REGISTER(nxp_s32_gpio, CONFIG_GPIO_LOG_LEVEL);
17
18 #ifdef CONFIG_NXP_S32_EIRQ
19 #include <zephyr/drivers/interrupt_controller/intc_eirq_nxp_s32.h>
20 #endif
21 #ifdef CONFIG_NXP_S32_WKPU
22 #include <zephyr/drivers/interrupt_controller/intc_wkpu_nxp_s32.h>
23 #endif
24
25 /* SIUL2 Multiplexed Signal Configuration Register (offset from port base) */
26 #define SIUL2_MSCR(n) (0x4 * (n))
27 /* SIUL2 Parallel GPIO Pad Data Out (offset from gpio base) */
28 #define SIUL2_PGPDO 0
29 /* SIUL2 Parallel GPIO Pad Data In */
30 #define SIUL2_PGPDI 0x40
31
32 /* Handy accessors */
33 #define GPIO_READ(r) sys_read16(config->gpio_base + (r))
34 #define GPIO_WRITE(r, v) sys_write16((v), config->gpio_base + (r))
35 #define PORT_READ(p) sys_read32(config->port_base + SIUL2_MSCR(p))
36 #define PORT_WRITE(p, v) sys_write32((v), config->port_base + SIUL2_MSCR(p))
37
38 #if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU)
39 #define NXP_S32_GPIO_LINE_NOT_FOUND 0xff
40
41 struct gpio_nxp_s32_irq_map {
42 uint8_t pin;
43 uint8_t line;
44 } __packed;
45
46 struct gpio_nxp_s32_irq_config {
47 const struct device *ctrl;
48 uint8_t map_cnt;
49 struct gpio_nxp_s32_irq_map *map;
50 };
51 #endif
52
53 struct gpio_nxp_s32_config {
54 /* gpio_driver_config needs to be first */
55 struct gpio_driver_config common;
56 mem_addr_t gpio_base;
57 mem_addr_t port_base;
58 #ifdef CONFIG_NXP_S32_EIRQ
59 struct gpio_nxp_s32_irq_config *eirq_info;
60 #endif
61 #ifdef CONFIG_NXP_S32_WKPU
62 struct gpio_nxp_s32_irq_config *wkpu_info;
63 #endif
64 };
65
66 struct gpio_nxp_s32_data {
67 /* gpio_driver_data needs to be first */
68 struct gpio_driver_data common;
69
70 #if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU)
71 sys_slist_t callbacks;
72 #if defined(CONFIG_NXP_S32_WKPU)
73 uint32_t pin_wkpu_mask;
74 #endif /* defined(CONFIG_NXP_S32_WKPU) */
75 #endif
76 };
77
reverse_bits_16(uint16_t value)78 static ALWAYS_INLINE uint16_t reverse_bits_16(uint16_t value)
79 {
80 return (uint16_t)(__RBIT((uint32_t)value) >> 16);
81 }
82
nxp_s32_gpio_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)83 static int nxp_s32_gpio_configure(const struct device *dev, gpio_pin_t pin,
84 gpio_flags_t flags)
85 {
86 const struct gpio_nxp_s32_config *config = dev->config;
87 uint32_t mscr_val;
88 uint32_t pgpdo_val;
89
90 if ((flags & GPIO_SINGLE_ENDED) != 0) {
91 return -ENOTSUP;
92 }
93
94 #if defined(CONFIG_NXP_S32_WKPU)
95 struct gpio_nxp_s32_data *data = dev->data;
96
97 WRITE_BIT(data->pin_wkpu_mask, pin, (flags & NXP_S32_GPIO_INT_WKPU));
98 #else
99 if (flags & NXP_S32_GPIO_INT_WKPU) {
100 return -ENOTSUP;
101 }
102 #endif
103
104 mscr_val = PORT_READ(pin);
105 mscr_val &= ~(SIUL2_MSCR_SSS_MASK | SIUL2_MSCR_OBE_MASK | SIUL2_MSCR_IBE_MASK |
106 SIUL2_MSCR_PUE_MASK | SIUL2_MSCR_PUS_MASK);
107
108 if (flags & GPIO_OUTPUT) {
109 mscr_val |= SIUL2_MSCR_OBE(1U);
110
111 pgpdo_val = GPIO_READ(SIUL2_PGPDO);
112 if (flags & GPIO_OUTPUT_INIT_HIGH) {
113 pgpdo_val |= BIT(15 - pin);
114 } else if (flags & GPIO_OUTPUT_INIT_LOW) {
115 pgpdo_val &= ~BIT(15 - pin);
116 }
117 GPIO_WRITE(SIUL2_PGPDO, pgpdo_val);
118 }
119 if (flags & GPIO_INPUT) {
120 mscr_val |= SIUL2_MSCR_IBE(1U);
121 }
122 if (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) {
123 mscr_val |= SIUL2_MSCR_PUE(1U);
124 if (flags & GPIO_PULL_UP) {
125 mscr_val |= SIUL2_MSCR_PUS(1U);
126 }
127 }
128 PORT_WRITE(pin, mscr_val);
129
130 return 0;
131 }
132
nxp_s32_gpio_port_get_raw(const struct device * port,uint32_t * value)133 static int nxp_s32_gpio_port_get_raw(const struct device *port, uint32_t *value)
134 {
135 const struct gpio_nxp_s32_config *config = port->config;
136
137 *value = reverse_bits_16(GPIO_READ(SIUL2_PGPDI));
138
139 return 0;
140 }
141
nxp_s32_gpio_port_set_masked_raw(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t value)142 static int nxp_s32_gpio_port_set_masked_raw(const struct device *port,
143 gpio_port_pins_t mask,
144 gpio_port_value_t value)
145 {
146 const struct gpio_nxp_s32_config *config = port->config;
147 gpio_port_pins_t pins_value;
148
149 pins_value = reverse_bits_16(GPIO_READ(SIUL2_PGPDO));
150 pins_value = (pins_value & ~mask) | (mask & value);
151 GPIO_WRITE(SIUL2_PGPDO, reverse_bits_16(pins_value));
152
153 return 0;
154 }
155
nxp_s32_gpio_port_set_bits_raw(const struct device * port,gpio_port_pins_t pins)156 static int nxp_s32_gpio_port_set_bits_raw(const struct device *port,
157 gpio_port_pins_t pins)
158 {
159 const struct gpio_nxp_s32_config *config = port->config;
160 uint16_t reg_val;
161
162 reg_val = GPIO_READ(SIUL2_PGPDO);
163 reg_val |= reverse_bits_16(pins);
164 GPIO_WRITE(SIUL2_PGPDO, reg_val);
165
166 return 0;
167 }
168
nxp_s32_gpio_port_clear_bits_raw(const struct device * port,gpio_port_pins_t pins)169 static int nxp_s32_gpio_port_clear_bits_raw(const struct device *port,
170 gpio_port_pins_t pins)
171 {
172 const struct gpio_nxp_s32_config *config = port->config;
173 uint16_t reg_val;
174
175 reg_val = GPIO_READ(SIUL2_PGPDO);
176 reg_val &= ~reverse_bits_16(pins);
177 GPIO_WRITE(SIUL2_PGPDO, reg_val);
178
179 return 0;
180 }
181
nxp_s32_gpio_port_toggle_bits(const struct device * port,gpio_port_pins_t pins)182 static int nxp_s32_gpio_port_toggle_bits(const struct device *port,
183 gpio_port_pins_t pins)
184 {
185 const struct gpio_nxp_s32_config *config = port->config;
186 uint16_t reg_val;
187
188 reg_val = GPIO_READ(SIUL2_PGPDO);
189 reg_val ^= reverse_bits_16(pins);
190 GPIO_WRITE(SIUL2_PGPDO, reg_val);
191
192 return 0;
193 }
194
195 #if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU)
196
nxp_s32_gpio_pin_to_line(const struct gpio_nxp_s32_irq_config * irq_cfg,uint8_t pin)197 static uint8_t nxp_s32_gpio_pin_to_line(const struct gpio_nxp_s32_irq_config *irq_cfg,
198 uint8_t pin)
199 {
200 uint8_t i;
201
202 for (i = 0; i < irq_cfg->map_cnt; i++) {
203 if (irq_cfg->map[i].pin == pin) {
204 return irq_cfg->map[i].line;
205 }
206 }
207
208 return NXP_S32_GPIO_LINE_NOT_FOUND;
209 }
210
nxp_s32_gpio_isr(uint8_t pin,void * arg)211 static void nxp_s32_gpio_isr(uint8_t pin, void *arg)
212 {
213 const struct device *dev = (struct device *)arg;
214 struct gpio_nxp_s32_data *data = dev->data;
215
216 gpio_fire_callbacks(&data->callbacks, dev, BIT(pin));
217 }
218
219 #if defined(CONFIG_NXP_S32_EIRQ)
nxp_s32_gpio_eirq_get_trigger(enum eirq_nxp_s32_trigger * eirq_trigger,enum gpio_int_trig trigger)220 static int nxp_s32_gpio_eirq_get_trigger(enum eirq_nxp_s32_trigger *eirq_trigger,
221 enum gpio_int_trig trigger)
222 {
223 switch (trigger) {
224 case GPIO_INT_TRIG_LOW:
225 *eirq_trigger = EIRQ_NXP_S32_FALLING_EDGE;
226 break;
227 case GPIO_INT_TRIG_HIGH:
228 *eirq_trigger = EIRQ_NXP_S32_RISING_EDGE;
229 break;
230 case GPIO_INT_TRIG_BOTH:
231 *eirq_trigger = EIRQ_NXP_S32_BOTH_EDGES;
232 break;
233 default:
234 return -ENOTSUP;
235 }
236
237 return 0;
238 }
239
nxp_s32_gpio_config_eirq(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)240 static int nxp_s32_gpio_config_eirq(const struct device *dev,
241 gpio_pin_t pin,
242 enum gpio_int_mode mode,
243 enum gpio_int_trig trig)
244 {
245 const struct gpio_nxp_s32_config *config = dev->config;
246 const struct gpio_nxp_s32_irq_config *irq_cfg = config->eirq_info;
247 uint8_t irq_line;
248 enum eirq_nxp_s32_trigger eirq_trigger;
249
250 if (irq_cfg == NULL) {
251 LOG_ERR("external interrupt controller not available or enabled");
252 return -ENOTSUP;
253 }
254
255 if (mode == GPIO_INT_MODE_LEVEL) {
256 return -ENOTSUP;
257 }
258
259 irq_line = nxp_s32_gpio_pin_to_line(irq_cfg, pin);
260 if (irq_line == NXP_S32_GPIO_LINE_NOT_FOUND) {
261 if (mode == GPIO_INT_MODE_DISABLED) {
262 return 0;
263 }
264 LOG_ERR("pin %d cannot be used for external interrupt", pin);
265 return -ENOTSUP;
266 }
267
268 if (mode == GPIO_INT_MODE_DISABLED) {
269 eirq_nxp_s32_disable_interrupt(irq_cfg->ctrl, irq_line);
270 eirq_nxp_s32_unset_callback(irq_cfg->ctrl, irq_line);
271 } else {
272 if (nxp_s32_gpio_eirq_get_trigger(&eirq_trigger, trig)) {
273 return -ENOTSUP;
274 }
275 if (eirq_nxp_s32_set_callback(irq_cfg->ctrl, irq_line, pin,
276 nxp_s32_gpio_isr, (void *)dev)) {
277 LOG_ERR("pin %d is already in use", pin);
278 return -EBUSY;
279 }
280 eirq_nxp_s32_enable_interrupt(irq_cfg->ctrl, irq_line, eirq_trigger);
281 }
282
283 return 0;
284 }
285 #endif /* CONFIG_NXP_S32_EIRQ */
286
287 #if defined(CONFIG_NXP_S32_WKPU)
nxp_s32_gpio_wkpu_get_trigger(enum wkpu_nxp_s32_trigger * wkpu_trigger,enum gpio_int_trig trigger)288 static int nxp_s32_gpio_wkpu_get_trigger(enum wkpu_nxp_s32_trigger *wkpu_trigger,
289 enum gpio_int_trig trigger)
290 {
291 switch (trigger) {
292 case GPIO_INT_TRIG_LOW:
293 *wkpu_trigger = WKPU_NXP_S32_FALLING_EDGE;
294 break;
295 case GPIO_INT_TRIG_HIGH:
296 *wkpu_trigger = WKPU_NXP_S32_RISING_EDGE;
297 break;
298 case GPIO_INT_TRIG_BOTH:
299 *wkpu_trigger = WKPU_NXP_S32_BOTH_EDGES;
300 break;
301 default:
302 return -ENOTSUP;
303 }
304
305 return 0;
306 }
307
nxp_s32_gpio_config_wkpu(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)308 static int nxp_s32_gpio_config_wkpu(const struct device *dev,
309 gpio_pin_t pin,
310 enum gpio_int_mode mode,
311 enum gpio_int_trig trig)
312 {
313 const struct gpio_nxp_s32_config *config = dev->config;
314 const struct gpio_nxp_s32_irq_config *irq_cfg = config->wkpu_info;
315 uint8_t irq_line;
316 enum wkpu_nxp_s32_trigger wkpu_trigger;
317
318 if (irq_cfg == NULL) {
319 LOG_ERR("WKPU controller not available or enabled");
320 return -ENOTSUP;
321 }
322
323 if (mode == GPIO_INT_MODE_LEVEL) {
324 return -ENOTSUP;
325 }
326
327 irq_line = nxp_s32_gpio_pin_to_line(irq_cfg, pin);
328 if (irq_line == NXP_S32_GPIO_LINE_NOT_FOUND) {
329 if (mode == GPIO_INT_MODE_DISABLED) {
330 return 0;
331 }
332 LOG_ERR("pin %d cannot be used for external interrupt", pin);
333 return -ENOTSUP;
334 }
335
336 if (mode == GPIO_INT_MODE_DISABLED) {
337 wkpu_nxp_s32_disable_interrupt(irq_cfg->ctrl, irq_line);
338 wkpu_nxp_s32_unset_callback(irq_cfg->ctrl, irq_line);
339 } else {
340 if (nxp_s32_gpio_wkpu_get_trigger(&wkpu_trigger, trig)) {
341 return -ENOTSUP;
342 }
343 if (wkpu_nxp_s32_set_callback(irq_cfg->ctrl, irq_line, pin,
344 nxp_s32_gpio_isr, (void *)dev)) {
345 LOG_ERR("pin %d is already in use", pin);
346 return -EBUSY;
347 }
348 wkpu_nxp_s32_enable_interrupt(irq_cfg->ctrl, irq_line, wkpu_trigger);
349 }
350
351 return 0;
352 }
353 #endif /* CONFIG_NXP_S32_WKPU */
354
nxp_s32_gpio_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)355 static int nxp_s32_gpio_pin_interrupt_configure(const struct device *dev,
356 gpio_pin_t pin,
357 enum gpio_int_mode mode,
358 enum gpio_int_trig trig)
359 {
360 #if defined(CONFIG_NXP_S32_WKPU)
361 struct gpio_nxp_s32_data *data = dev->data;
362
363 if (data->pin_wkpu_mask & BIT(pin)) {
364 return nxp_s32_gpio_config_wkpu(dev, pin, mode, trig);
365 }
366 #endif
367
368 #if defined(CONFIG_NXP_S32_EIRQ)
369 return nxp_s32_gpio_config_eirq(dev, pin, mode, trig);
370 #endif
371 }
372
nxp_s32_gpio_manage_callback(const struct device * dev,struct gpio_callback * cb,bool set)373 static int nxp_s32_gpio_manage_callback(const struct device *dev,
374 struct gpio_callback *cb, bool set)
375 {
376 struct gpio_nxp_s32_data *data = dev->data;
377
378 return gpio_manage_callback(&data->callbacks, cb, set);
379 }
380 #endif /* defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU) */
381
382 #ifdef CONFIG_GPIO_GET_CONFIG
nxp_s32_gpio_pin_get_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t * out_flags)383 static int nxp_s32_gpio_pin_get_config(const struct device *dev,
384 gpio_pin_t pin,
385 gpio_flags_t *out_flags)
386 {
387 const struct gpio_nxp_s32_config *config = dev->config;
388 uint16_t pins_output;
389 uint32_t mscr_val;
390 gpio_flags_t flags = 0;
391
392 mscr_val = PORT_READ(pin);
393 if ((mscr_val & SIUL2_MSCR_IBE_MASK) != 0) {
394 flags |= GPIO_INPUT;
395 }
396
397 if ((mscr_val & SIUL2_MSCR_OBE_MASK) != 0) {
398 flags |= GPIO_OUTPUT;
399
400 pins_output = GPIO_READ(SIUL2_PGPDO);
401 if ((pins_output & BIT(15 - pin)) != 0) {
402 flags |= GPIO_OUTPUT_HIGH;
403 } else {
404 flags |= GPIO_OUTPUT_LOW;
405 }
406
407 #if defined(SIUL2_MSCR_ODE_MASK)
408 if ((mscr_val & SIUL2_MSCR_ODE_MASK) != 0) {
409 flags |= GPIO_OPEN_DRAIN;
410 }
411 #endif /* SIUL2_MSCR_ODE_MASK */
412 }
413
414 if ((mscr_val & SIUL2_MSCR_PUE_MASK) != 0) {
415 if ((mscr_val & SIUL2_MSCR_PUS_MASK) != 0) {
416 flags |= GPIO_PULL_UP;
417 } else {
418 flags |= GPIO_PULL_DOWN;
419 }
420 }
421
422 *out_flags = flags;
423
424 return 0;
425 }
426 #endif /* CONFIG_GPIO_GET_CONFIG */
427
428 #ifdef CONFIG_GPIO_GET_DIRECTION
nxp_s32_gpio_port_get_direction(const struct device * dev,gpio_port_pins_t map,gpio_port_pins_t * inputs,gpio_port_pins_t * outputs)429 static int nxp_s32_gpio_port_get_direction(const struct device *dev,
430 gpio_port_pins_t map,
431 gpio_port_pins_t *inputs,
432 gpio_port_pins_t *outputs)
433 {
434 const struct gpio_nxp_s32_config *config = dev->config;
435 gpio_port_pins_t ip = 0;
436 gpio_port_pins_t op = 0;
437 uint32_t pin;
438
439 map &= config->common.port_pin_mask;
440
441 if (inputs != NULL) {
442 while (map) {
443 pin = find_lsb_set(map) - 1;
444 ip |= (!!(PORT_READ(pin) & SIUL2_MSCR_IBE_MASK)) * BIT(pin);
445 map &= ~BIT(pin);
446 }
447
448 *inputs = ip;
449 }
450
451 if (outputs != NULL) {
452 while (map) {
453 pin = find_lsb_set(map) - 1;
454 op |= (!!(PORT_READ(pin) & SIUL2_MSCR_OBE_MASK)) * BIT(pin);
455 map &= ~BIT(pin);
456 }
457
458 *outputs = op;
459 }
460
461 return 0;
462 }
463 #endif /* CONFIG_GPIO_GET_DIRECTION */
464
465 static DEVICE_API(gpio, gpio_nxp_s32_driver_api) = {
466 .pin_configure = nxp_s32_gpio_configure,
467 .port_get_raw = nxp_s32_gpio_port_get_raw,
468 .port_set_masked_raw = nxp_s32_gpio_port_set_masked_raw,
469 .port_set_bits_raw = nxp_s32_gpio_port_set_bits_raw,
470 .port_clear_bits_raw = nxp_s32_gpio_port_clear_bits_raw,
471 .port_toggle_bits = nxp_s32_gpio_port_toggle_bits,
472 #if defined(CONFIG_NXP_S32_EIRQ) || defined(CONFIG_NXP_S32_WKPU)
473 .pin_interrupt_configure = nxp_s32_gpio_pin_interrupt_configure,
474 .manage_callback = nxp_s32_gpio_manage_callback,
475 #endif
476 #ifdef CONFIG_GPIO_GET_CONFIG
477 .pin_get_config = nxp_s32_gpio_pin_get_config,
478 #endif
479 #ifdef CONFIG_GPIO_GET_DIRECTION
480 .port_get_direction = nxp_s32_gpio_port_get_direction,
481 #endif
482 };
483
484 /* Calculate the port pin mask based on ngpios and gpio-reserved-ranges node
485 * properties. Multiple reserved ranges are not supported.
486 *
487 * For example, for the following gpio node definition:
488 *
489 * gpioo: gpio@40521716 {
490 * ...
491 * ngpios = <14>;
492 * gpio-reserved-ranges = <0 10>;
493 * };
494 *
495 * the generated mask will be will be 0x3C00.
496 */
497 #define GPIO_NXP_S32_RESERVED_PIN_MASK(n) \
498 (GENMASK(DT_INST_PROP_BY_IDX(n, gpio_reserved_ranges, 0) + \
499 DT_INST_PROP_BY_IDX(n, gpio_reserved_ranges, 1) - 1, \
500 DT_INST_PROP_BY_IDX(n, gpio_reserved_ranges, 0) \
501 ))
502
503 #define GPIO_NXP_S32_PORT_PIN_MASK(n) \
504 COND_CODE_1(DT_INST_NODE_HAS_PROP(n, gpio_reserved_ranges), \
505 (GPIO_PORT_PIN_MASK_FROM_DT_INST(n) \
506 & ~(GPIO_NXP_S32_RESERVED_PIN_MASK(n))), \
507 (GPIO_PORT_PIN_MASK_FROM_DT_INST(n)))
508
509 #ifdef CONFIG_NXP_S32_EIRQ
510 #define GPIO_NXP_S32_EIRQ_NODE(n) \
511 DT_INST_PHANDLE(n, interrupt_parent)
512
513 #define GPIO_NXP_S32_EIRQ_PIN_LINE(idx, n) \
514 DT_INST_IRQ_BY_IDX(n, idx, gpio_pin), \
515 DT_INST_IRQ_BY_IDX(n, idx, eirq_line) \
516
517 #define GPIO_NXP_S32_SET_EIRQ_INFO(n) \
518 BUILD_ASSERT((DT_NODE_HAS_PROP(DT_DRV_INST(n), interrupt_parent) == \
519 DT_NODE_HAS_PROP(DT_DRV_INST(n), interrupts)), \
520 "interrupts and interrupt-parent must be set when " \
521 "using external interrupts"); \
522 IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(GPIO_NXP_S32_EIRQ_NODE(n)), ( \
523 static uint8_t gpio_nxp_s32_eirq_data_##n[] = { \
524 LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \
525 GPIO_NXP_S32_EIRQ_PIN_LINE, (,), n) \
526 }; \
527 static struct gpio_nxp_s32_irq_config gpio_nxp_s32_eirq_##n = { \
528 .ctrl = DEVICE_DT_GET(GPIO_NXP_S32_EIRQ_NODE(n)), \
529 .map_cnt = DT_NUM_IRQS(DT_DRV_INST(n)), \
530 .map = (struct gpio_nxp_s32_irq_map *) \
531 gpio_nxp_s32_eirq_data_##n, \
532 }; \
533 ))
534
535 #define GPIO_NXP_S32_GET_EIRQ_INFO(n) \
536 .eirq_info = UTIL_AND(DT_NODE_HAS_STATUS_OKAY(GPIO_NXP_S32_EIRQ_NODE(n)),\
537 &gpio_nxp_s32_eirq_##n),
538 #else
539 #define GPIO_NXP_S32_SET_EIRQ_INFO(n)
540 #define GPIO_NXP_S32_GET_EIRQ_INFO(n)
541 #endif /* CONFIG_NXP_S32_EIRQ */
542
543 #ifdef CONFIG_NXP_S32_WKPU
544 #define GPIO_NXP_S32_WKPU_NODE(n) DT_INST_PHANDLE(n, nxp_wkpu)
545
546 #define GPIO_NXP_S32_SET_WKPU_INFO(n) \
547 BUILD_ASSERT((DT_INST_NODE_HAS_PROP(n, nxp_wkpu) == \
548 DT_INST_NODE_HAS_PROP(n, nxp_wkpu_interrupts)), \
549 "nxp,wkpu and nxp,wkpu-interrupts must be provided"); \
550 IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(GPIO_NXP_S32_WKPU_NODE(n)), ( \
551 static uint8_t gpio_nxp_s32_wkpu_data_##n[] = \
552 DT_INST_PROP(n, nxp_wkpu_interrupts); \
553 static struct gpio_nxp_s32_irq_config gpio_nxp_s32_wkpu_##n = { \
554 .ctrl = DEVICE_DT_GET(GPIO_NXP_S32_WKPU_NODE(n)), \
555 .map_cnt = sizeof(gpio_nxp_s32_wkpu_data_##n) / \
556 sizeof(struct gpio_nxp_s32_irq_map), \
557 .map = (struct gpio_nxp_s32_irq_map *) \
558 gpio_nxp_s32_wkpu_data_##n, \
559 }; \
560 ))
561
562 #define GPIO_NXP_S32_GET_WKPU_INFO(n) \
563 .wkpu_info = UTIL_AND(DT_NODE_HAS_STATUS_OKAY(GPIO_NXP_S32_WKPU_NODE(n)),\
564 &gpio_nxp_s32_wkpu_##n)
565 #else
566 #define GPIO_NXP_S32_SET_WKPU_INFO(n)
567 #define GPIO_NXP_S32_GET_WKPU_INFO(n)
568 #endif /* CONFIG_NXP_S32_WKPU */
569
570 #define GPIO_NXP_S32_DEVICE_INIT(n) \
571 GPIO_NXP_S32_SET_EIRQ_INFO(n) \
572 GPIO_NXP_S32_SET_WKPU_INFO(n) \
573 static const struct gpio_nxp_s32_config gpio_nxp_s32_config_##n = { \
574 .common = { \
575 .port_pin_mask = GPIO_NXP_S32_PORT_PIN_MASK(n), \
576 }, \
577 .gpio_base = DT_INST_REG_ADDR_BY_NAME(n, pgpdo), \
578 .port_base = DT_INST_REG_ADDR_BY_NAME(n, mscr), \
579 GPIO_NXP_S32_GET_EIRQ_INFO(n) \
580 GPIO_NXP_S32_GET_WKPU_INFO(n) \
581 }; \
582 static struct gpio_nxp_s32_data gpio_nxp_s32_data_##n; \
583 static int gpio_nxp_s32_init_##n(const struct device *dev) \
584 { \
585 return 0; \
586 } \
587 DEVICE_DT_INST_DEFINE(n, \
588 gpio_nxp_s32_init_##n, \
589 NULL, \
590 &gpio_nxp_s32_data_##n, \
591 &gpio_nxp_s32_config_##n, \
592 POST_KERNEL, \
593 CONFIG_GPIO_INIT_PRIORITY, \
594 &gpio_nxp_s32_driver_api);
595
596 DT_INST_FOREACH_STATUS_OKAY(GPIO_NXP_S32_DEVICE_INIT)
597