17
17
18
18
#include <zephyr/drivers/gpio/gpio_utils.h>
19
19
20
+ #if defined(CONFIG_PM ) || defined(CONFIG_POWEROFF )
21
+ #if defined(CONFIG_SOC_FAMILY_MCXN ) || defined(CONFIG_SOC_FAMILY_MCXA ) || \
22
+ defined(CONFIG_SOC_FAMILY_MCXW )
23
+ #include <fsl_wuu.h>
24
+ #endif
25
+ #endif
26
+
20
27
#if defined(CONFIG_PINCTRL_NXP_IOCON )
21
28
#include <fsl_iopctl.h>
22
29
/* Use IOCON to configure electrical characteristic, set PORT_Type as void. */
@@ -30,6 +37,12 @@ struct gpio_mcux_config {
30
37
PORT_Type * port_base ;
31
38
unsigned int flags ;
32
39
uint32_t port_no ;
40
+ #if defined(CONFIG_PM ) || defined(CONFIG_POWEROFF )
41
+ bool wakeup_source ;
42
+ uint8_t wakeup_pin ;
43
+ uint8_t wuu_index ; /* Index used to configure wakeup unit (wuu). */
44
+ uint8_t wakeup_signal_edge ;
45
+ #endif
33
46
};
34
47
35
48
struct gpio_mcux_data {
@@ -200,6 +213,31 @@ static int gpio_mcux_port_configure(const struct device *dev, gpio_pin_t pin, gp
200
213
/* Accessing by pin, we only need to write one PCR register. */
201
214
port_base -> PCR [pin ] = (port_base -> PCR [pin ] & ~mask ) | pcr ;
202
215
216
+
217
+ #if defined(CONFIG_PM ) || defined(CONFIG_POWEROFF )
218
+ #if defined(CONFIG_SOC_FAMILY_MCXN ) || defined(CONFIG_SOC_FAMILY_MCXA ) || \
219
+ defined(CONFIG_SOC_FAMILY_MCXW )
220
+ if ((config -> wakeup_source ) && (config -> wakeup_pin == pin )) {
221
+ wuu_external_wakeup_pin_config_t wakeup_pin_config ;
222
+
223
+ wakeup_pin_config .edge = config -> wakeup_signal_edge ;
224
+ wakeup_pin_config .event = kWUU_ExternalPinInterrupt ;
225
+ wakeup_pin_config .mode = kWUU_ExternalPinActiveAlways ;
226
+
227
+ /* We get pin index here not WUU input index. */
228
+ if (WUU_GetExternalWakeUpPinsFlag (WUU0 ) == BIT (config -> wuu_index )) {
229
+ WUU_ClearExternalWakeUpPinsFlag (WUU0 , BIT (config -> wuu_index ));
230
+ }
231
+
232
+ WUU_SetExternalWakeUpPinsConfig (WUU0 , config -> wuu_index , & wakeup_pin_config );
233
+ }
234
+ #elif
235
+ /* Other platforms may also use gpio as the wakeup source, but the wakeup source
236
+ * management is not done using WUU.
237
+ */
238
+ #endif
239
+ #endif
240
+
203
241
return 0 ;
204
242
}
205
243
#endif /* defined(CONFIG_PINCTRL_NXP_IOCON) */
@@ -405,6 +443,21 @@ static void gpio_mcux_port_isr(const struct device *dev)
405
443
ARG_UNUSED (config );
406
444
#endif /* !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) */
407
445
446
+ #if defined(CONFIG_PM ) || defined(CONFIG_POWEROFF )
447
+ #if defined(CONFIG_SOC_FAMILY_MCXN ) || defined(CONFIG_SOC_FAMILY_MCXA ) || \
448
+ defined(CONFIG_SOC_FAMILY_MCXW )
449
+ if (config -> wakeup_source ) {
450
+ if (WUU_GetExternalWakeUpPinsFlag (WUU0 ) == BIT (config -> wuu_index )) {
451
+ WUU_ClearExternalWakeUpPinsFlag (WUU0 , BIT (config -> wuu_index ));
452
+ }
453
+ }
454
+ #elif
455
+ /* Other platforms may also use gpio as the wakeup source, but the wakeup source
456
+ * management is not done using WUU.
457
+ */
458
+ #endif
459
+ #endif
460
+
408
461
gpio_fire_callbacks (& data -> callbacks , dev , int_status );
409
462
}
410
463
@@ -423,18 +476,18 @@ static void gpio_mcux_shared_cluster_isr(const struct device *ports[])
423
476
424
477
#define CLUSTER_ARRAY_ELEMENT (node_id ) DEVICE_DT_GET(node_id),
425
478
426
- #define GPIO_MCUX_CLUSTER_INIT (node_id ) \
427
- const struct device *shared_array##node_id[DT_CHILD_NUM_STATUS_OKAY(node_id) + 1] = { \
428
- DT_FOREACH_CHILD_STATUS_OKAY(node_id, CLUSTER_ARRAY_ELEMENT) NULL}; \
429
- \
430
- static int gpio_mcux_shared_interrupt_init##node_id(void) \
431
- { \
432
- IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), \
433
- gpio_mcux_shared_cluster_isr, shared_array##node_id, 0); \
434
- irq_enable(DT_IRQN(node_id)); \
435
- \
436
- return 0; \
437
- } \
479
+ #define GPIO_MCUX_CLUSTER_INIT (node_id ) \
480
+ const struct device *shared_array##node_id[DT_CHILD_NUM_STATUS_OKAY(node_id) + 1] = { \
481
+ DT_FOREACH_CHILD_STATUS_OKAY(node_id, CLUSTER_ARRAY_ELEMENT) NULL}; \
482
+ \
483
+ static int gpio_mcux_shared_interrupt_init##node_id(void) \
484
+ { \
485
+ IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), \
486
+ gpio_mcux_shared_cluster_isr, shared_array##node_id, 0); \
487
+ irq_enable(DT_IRQN(node_id)); \
488
+ \
489
+ return 0; \
490
+ } \
438
491
SYS_INIT(gpio_mcux_shared_interrupt_init##node_id, POST_KERNEL, 0);
439
492
440
493
DT_FOREACH_STATUS_OKAY (nxp_gpio_cluster , GPIO_MCUX_CLUSTER_INIT )
@@ -479,44 +532,61 @@ static DEVICE_API(gpio, gpio_mcux_driver_api) = {
479
532
#endif /* CONFIG_GPIO_GET_DIRECTION */
480
533
};
481
534
482
- #define GPIO_MCUX_IRQ_INIT (n ) \
483
- do { \
484
- IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_mcux_port_isr, \
485
- DEVICE_DT_INST_GET(n), 0); \
486
- \
487
- irq_enable(DT_INST_IRQN(n)); \
535
+
536
+
537
+ #if defined(CONFIG_PM ) || defined(CONFIG_POWEROFF )
538
+ #define GPIO_ENABLED_WAKEUP_FUNCTION (n ) \
539
+ .wakeup_source = DT_INST_PROP_OR(n, wakeup_source, 0), \
540
+ IF_ENABLED(DT_INST_PROP(n, wakeup_source), \
541
+ (.wakeup_signal_edge = DT_INST_PROP(n, wakeup_signal_edge),)) \
542
+ IF_ENABLED(DT_INST_PROP(n, wakeup_source), \
543
+ (.wakeup_pin = DT_PROP_BY_IDX(DT_DRV_INST(n), wakeup_line, 0),)) \
544
+ IF_ENABLED(DT_INST_PROP(n, wakeup_source), \
545
+ (.wuu_index = DT_PROP_BY_IDX(DT_DRV_INST(n), wakeup_line, 1),)) \
546
+
547
+ #else
548
+ #define GPIO_ENABLED_WAKEUP_FUNCTION (n )
549
+ #endif
550
+
551
+ #define GPIO_MCUX_IRQ_INIT (n ) \
552
+ do { \
553
+ IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_mcux_port_isr, \
554
+ DEVICE_DT_INST_GET(n), 0); \
555
+ \
556
+ irq_enable(DT_INST_IRQN(n)); \
488
557
} while (false)
489
558
490
559
#define GPIO_PORT_BASE_ADDR (n ) DT_REG_ADDR(DT_INST_PHANDLE(n, nxp_kinetis_port))
491
- #define GPIO_PORT_NUMBER (n ) COND_CODE_1(DT_INST_NODE_HAS_PROP(n, gpio_port_offest), \
560
+ #define GPIO_PORT_NUMBER (n ) COND_CODE_1(DT_INST_NODE_HAS_PROP(n, gpio_port_offest), \
492
561
(DT_INST_PROP(n, gpio_port_offest) + n), (n)) \
493
562
494
- #define GPIO_DEVICE_INIT_MCUX (n ) \
495
- static int gpio_mcux_port##n##_init(const struct device *dev); \
496
- \
497
- static const struct gpio_mcux_config gpio_mcux_port##n##_config = { \
498
- .common = \
499
- { \
500
- .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
501
- }, \
502
- .gpio_base = (GPIO_Type *)DT_INST_REG_ADDR(n), \
503
- .port_base = (PORT_Type *)GPIO_PORT_BASE_ADDR(n), \
504
- .flags = UTIL_AND(UTIL_OR(DT_INST_IRQ_HAS_IDX(n, 0), GPIO_HAS_SHARED_IRQ), \
505
- GPIO_INT_ENABLE), \
506
- .port_no = GPIO_PORT_NUMBER(n), \
507
- }; \
508
- \
509
- static struct gpio_mcux_data gpio_mcux_port##n##_data; \
510
- \
511
- DEVICE_DT_INST_DEFINE(n, gpio_mcux_port##n##_init, NULL, &gpio_mcux_port##n##_data, \
512
- &gpio_mcux_port##n##_config, POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \
513
- &gpio_mcux_driver_api); \
514
- \
515
- static int gpio_mcux_port##n##_init(const struct device *dev) \
516
- { \
517
- IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \
518
- (GPIO_MCUX_IRQ_INIT(n);)) \
519
- return 0; \
563
+ #define GPIO_DEVICE_INIT_MCUX (n ) \
564
+ static int gpio_mcux_port##n##_init(const struct device *dev); \
565
+ \
566
+ static const struct gpio_mcux_config gpio_mcux_port##n##_config = { \
567
+ .common = \
568
+ { \
569
+ .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
570
+ }, \
571
+ .gpio_base = (GPIO_Type *)DT_INST_REG_ADDR(n), \
572
+ .port_base = (PORT_Type *)GPIO_PORT_BASE_ADDR(n), \
573
+ .flags = UTIL_AND(UTIL_OR(DT_INST_IRQ_HAS_IDX(n, 0), GPIO_HAS_SHARED_IRQ), \
574
+ GPIO_INT_ENABLE), \
575
+ .port_no = GPIO_PORT_NUMBER(n), \
576
+ GPIO_ENABLED_WAKEUP_FUNCTION(n) \
577
+ }; \
578
+ \
579
+ static struct gpio_mcux_data gpio_mcux_port##n##_data; \
580
+ \
581
+ DEVICE_DT_INST_DEFINE(n, gpio_mcux_port##n##_init, NULL, &gpio_mcux_port##n##_data, \
582
+ &gpio_mcux_port##n##_config, POST_KERNEL, \
583
+ CONFIG_GPIO_INIT_PRIORITY, &gpio_mcux_driver_api); \
584
+ \
585
+ static int gpio_mcux_port##n##_init(const struct device *dev) \
586
+ { \
587
+ IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \
588
+ (GPIO_MCUX_IRQ_INIT(n);)) \
589
+ return 0; \
520
590
}
521
591
522
592
DT_INST_FOREACH_STATUS_OKAY (GPIO_DEVICE_INIT_MCUX )
0 commit comments