77#define DT_DRV_COMPAT nordic_nrf_gpio
88
99#include <nrfx_gpiote.h>
10+ #include <gpiote_nrfx.h>
1011#include <string.h>
1112#include <zephyr/drivers/gpio.h>
13+ #include <zephyr/drivers/gpio/gpio_nrf.h>
1214#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
1315#include <zephyr/irq.h>
1416#include <zephyr/pm/device.h>
@@ -45,9 +47,9 @@ struct gpio_nrfx_cfg {
4547 /* gpio_driver_config needs to be first */
4648 struct gpio_driver_config common ;
4749 NRF_GPIO_Type * port ;
50+ nrfx_gpiote_t * gpiote ;
4851 uint32_t edge_sense ;
4952 uint8_t port_num ;
50- nrfx_gpiote_t gpiote ;
5153#if defined(GPIOTE_FEATURE_FLAG )
5254 uint32_t flags ;
5355#endif
@@ -63,9 +65,16 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port
6365 return port -> config ;
6466}
6567
68+ void * gpio_nrf_gpiote_by_port_get (const struct device * port )
69+ {
70+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
71+
72+ return cfg -> gpiote ;
73+ }
74+
6675static bool has_gpiote (const struct gpio_nrfx_cfg * cfg )
6776{
68- return cfg -> gpiote . p_reg != NULL ;
77+ return cfg -> gpiote != NULL ;
6978}
7079
7180#if NRF_GPIO_HAS_RETENTION_SETCLEAR
@@ -111,7 +120,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
111120 gpio_flags_t flags )
112121{
113122 int ret = 0 ;
114- nrfx_err_t err = NRFX_SUCCESS ;
123+ int err = 0 ;
115124 uint8_t ch ;
116125 bool free_ch = false;
117126 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
@@ -173,13 +182,13 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
173182 * to be freed when the pin is reconfigured or disconnected.
174183 */
175184 if (IS_ENABLED (CONFIG_GPIO_NRFX_INTERRUPT )) {
176- err = nrfx_gpiote_channel_get (& cfg -> gpiote , abs_pin , & ch );
177- free_ch = (err == NRFX_SUCCESS );
185+ err = nrfx_gpiote_channel_get (cfg -> gpiote , abs_pin , & ch );
186+ free_ch = (err == 0 );
178187 }
179188
180189 if ((flags & (GPIO_INPUT | GPIO_OUTPUT )) == GPIO_DISCONNECTED ) {
181190 /* Ignore the error code. The pin may not have been used. */
182- (void )nrfx_gpiote_pin_uninit (& cfg -> gpiote , abs_pin );
191+ (void )nrfx_gpiote_pin_uninit (cfg -> gpiote , abs_pin );
183192 } else {
184193 /* Remove previously configured trigger when pin is reconfigured. */
185194 if (IS_ENABLED (CONFIG_GPIO_NRFX_INTERRUPT )) {
@@ -190,11 +199,9 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
190199 .p_trigger_config = & trigger_config ,
191200 };
192201
193- err = nrfx_gpiote_input_configure (& cfg -> gpiote ,
202+ err = nrfx_gpiote_input_configure (cfg -> gpiote ,
194203 abs_pin , & input_pin_config );
195- if (err != NRFX_SUCCESS ) {
196- ret = - EINVAL ;
197-
204+ if (err < 0 ) {
198205 goto end ;
199206 }
200207 }
@@ -208,7 +215,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
208215 .pull = pull ,
209216 };
210217
211- err = nrfx_gpiote_output_configure (& cfg -> gpiote ,
218+ err = nrfx_gpiote_output_configure (cfg -> gpiote ,
212219 abs_pin , & output_config , NULL );
213220
214221 port_retain_set (cfg , BIT (pin ));
@@ -217,12 +224,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
217224 .p_pull_config = & pull ,
218225 };
219226
220- err = nrfx_gpiote_input_configure (& cfg -> gpiote ,
227+ err = nrfx_gpiote_input_configure (cfg -> gpiote ,
221228 abs_pin , & input_pin_config );
222229 }
223230
224- if (err != NRFX_SUCCESS ) {
225- ret = - EINVAL ;
231+ if (err < 0 ) {
226232 goto end ;
227233 }
228234 }
@@ -234,8 +240,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
234240 goto end ;
235241 }
236242#endif
237- err = nrfx_gpiote_channel_free (& cfg -> gpiote , ch );
238- __ASSERT_NO_MSG (err == NRFX_SUCCESS );
243+ err = nrfx_gpiote_channel_free (cfg -> gpiote , ch );
244+ __ASSERT_NO_MSG (err == 0 );
239245 }
240246
241247end :
@@ -391,7 +397,7 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
391397 NRFX_GPIOTE_TRIGGER_LOTOHI ;
392398}
393399
394- static nrfx_err_t chan_alloc (const struct gpio_nrfx_cfg * cfg , gpio_pin_t pin , uint8_t * ch )
400+ static int chan_alloc (const struct gpio_nrfx_cfg * cfg , gpio_pin_t pin , uint8_t * ch )
395401{
396402#ifdef GPIOTE_FEATURE_FLAG
397403 if (cfg -> flags & GPIOTE_FLAG_FIXED_CHAN ) {
@@ -401,25 +407,25 @@ static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, ui
401407 * - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1
402408 * - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0
403409 */
404- nrfx_err_t err = NRFX_SUCCESS ;
410+ int err = 0 ;
405411
406412 if (cfg -> port_num == 1 ) {
407413 if (pin < 4 ) {
408- err = NRFX_ERROR_INVALID_PARAM ;
414+ err = - EINVAL ;
409415 } else {
410416 * ch = pin - 4 ;
411417 }
412418 } else if (cfg -> port_num == 2 ) {
413419 * ch = pin & 0x7 ;
414420 } else {
415- err = NRFX_ERROR_INVALID_PARAM ;
421+ err = - EINVAL ;
416422 }
417423
418424 return err ;
419425 }
420426#endif
421427
422- return nrfx_gpiote_channel_alloc (& cfg -> gpiote , ch );
428+ return nrfx_gpiote_channel_alloc (cfg -> gpiote , ch );
423429}
424430
425431static int gpio_nrfx_pin_interrupt_configure (const struct device * port ,
@@ -429,15 +435,15 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
429435{
430436 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
431437 uint32_t abs_pin = NRF_GPIO_PIN_MAP (cfg -> port_num , pin );
432- nrfx_err_t err ;
438+ int err ;
433439 uint8_t ch ;
434440
435441 if (!has_gpiote (cfg )) {
436442 return - ENOTSUP ;
437443 }
438444
439445 if (mode == GPIO_INT_MODE_DISABLED ) {
440- nrfx_gpiote_trigger_disable (& cfg -> gpiote , abs_pin );
446+ nrfx_gpiote_trigger_disable (cfg -> gpiote , abs_pin );
441447
442448 return 0 ;
443449 }
@@ -455,11 +461,11 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
455461 if (!(BIT (pin ) & cfg -> edge_sense ) &&
456462 (mode == GPIO_INT_MODE_EDGE ) &&
457463 (nrf_gpio_pin_dir_get (abs_pin ) == NRF_GPIO_PIN_DIR_INPUT )) {
458- err = nrfx_gpiote_channel_get (& cfg -> gpiote , abs_pin , & ch );
459- if (err == NRFX_ERROR_INVALID_PARAM ) {
464+ err = nrfx_gpiote_channel_get (cfg -> gpiote , abs_pin , & ch );
465+ if (err == - EINVAL ) {
460466 err = chan_alloc (cfg , pin , & ch );
461- if (err != NRFX_SUCCESS ) {
462- return - ENOMEM ;
467+ if (err < 0 ) {
468+ return err ;
463469 }
464470 }
465471
@@ -473,19 +479,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
473479 /* If edge mode with channel was previously used and we are changing to sense or
474480 * level triggered, we must free the channel.
475481 */
476- err = nrfx_gpiote_channel_get (& cfg -> gpiote , abs_pin , & ch );
477- if (err == NRFX_SUCCESS ) {
478- err = nrfx_gpiote_channel_free (& cfg -> gpiote , ch );
479- __ASSERT_NO_MSG (err == NRFX_SUCCESS );
482+ err = nrfx_gpiote_channel_get (cfg -> gpiote , abs_pin , & ch );
483+ if (err == 0 ) {
484+ err = nrfx_gpiote_channel_free (cfg -> gpiote , ch );
485+ __ASSERT_NO_MSG (err == 0 );
480486 }
481487 }
482488
483- err = nrfx_gpiote_input_configure (& cfg -> gpiote , abs_pin , & input_pin_config );
484- if (err != NRFX_SUCCESS ) {
485- return - EINVAL ;
489+ err = nrfx_gpiote_input_configure (cfg -> gpiote , abs_pin , & input_pin_config );
490+ if (err < 0 ) {
491+ return err ;
486492 }
487493
488- nrfx_gpiote_trigger_enable (& cfg -> gpiote , abs_pin , true);
494+ nrfx_gpiote_trigger_enable (cfg -> gpiote , abs_pin , true);
489495
490496 return 0 ;
491497}
@@ -574,9 +580,12 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
574580}
575581#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
576582
577- #define GPIOTE_IRQ_HANDLER_CONNECT (node_id ) \
578- IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
579- NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
583+ #define GPIOTE_IRQ_HANDLER_CONNECT (node_id ) \
584+ IRQ_CONNECT(DT_IRQN(node_id), \
585+ DT_IRQ(node_id, priority), \
586+ nrfx_gpiote_irq_handler, \
587+ &GPIOTE_NRFX_INST_BY_NODE(node_id), \
588+ 0);
580589
581590static int gpio_nrfx_pm_hook (const struct device * port , enum pm_device_action action )
582591{
@@ -588,23 +597,23 @@ static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action ac
588597static int gpio_nrfx_init (const struct device * port )
589598{
590599 const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
591- nrfx_err_t err ;
600+ int err ;
592601
593602 if (!has_gpiote (cfg )) {
594603 goto pm_init ;
595604 }
596605
597- if (nrfx_gpiote_init_check (& cfg -> gpiote )) {
606+ if (nrfx_gpiote_init_check (cfg -> gpiote )) {
598607 goto pm_init ;
599608 }
600609
601- err = nrfx_gpiote_init (& cfg -> gpiote , 0 /*not used*/ );
602- if (err != NRFX_SUCCESS ) {
610+ err = nrfx_gpiote_init (cfg -> gpiote , 0 /*not used*/ );
611+ if (err != 0 ) {
603612 return - EIO ;
604613 }
605614
606615#ifdef CONFIG_GPIO_NRFX_INTERRUPT
607- nrfx_gpiote_global_callback_set (& cfg -> gpiote , nrfx_gpio_handler , NULL );
616+ nrfx_gpiote_global_callback_set (cfg -> gpiote , nrfx_gpio_handler , NULL );
608617 DT_FOREACH_STATUS_OKAY (nordic_nrf_gpiote , GPIOTE_IRQ_HANDLER_CONNECT );
609618#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
610619
@@ -631,35 +640,36 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
631640#endif
632641};
633642
634- #define GPIOTE_INST (id ) DT_PROP(GPIOTE_PHANDLE(id), instance)
635-
636- #define GPIOTE_INSTANCE (id ) \
637- COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \
638- (NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \
639- ({ .p_reg = NULL }))
640-
641643/* Device instantiation is done with node labels because 'port_num' is
642644 * the peripheral number by SoC numbering. We therefore cannot use
643645 * DT_INST APIs here without wider changes.
644646 */
645647
648+ #define HAS_GPIOTE (id ) DT_INST_NODE_HAS_PROP(id, gpiote_instance)
649+
646650#define GPIOTE_CHECK (id ) \
647- COND_CODE_1(DT_INST_NODE_HAS_PROP (id, gpiote_instance), \
648- (BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
651+ COND_CODE_1(HAS_GPIOTE (id), \
652+ (BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
649653 "Please enable GPIOTE instance for used GPIO port!")), \
650654 ())
651655
656+ #define GPIOTE_REF (id ) \
657+ COND_CODE_1(HAS_GPIOTE(id), \
658+ (&GPIOTE_NRFX_INST_BY_NODE(GPIOTE_PHANDLE(id))), \
659+ (NULL))
660+
652661#define GPIO_NRF_DEVICE (id ) \
653662 GPIOTE_CHECK(id); \
663+ static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
654664 static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
655665 .common = { \
656666 .port_pin_mask = \
657667 GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \
658668 }, \
659669 .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
660- .port_num = DT_INST_PROP (id, port), \
670+ .gpiote = GPIOTE_REF (id), \
661671 .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
662- .gpiote = GPIOTE_INSTANCE (id), \
672+ .port_num = DT_INST_PROP (id, port), \
663673 IF_ENABLED(GPIOTE_FEATURE_FLAG, \
664674 (.flags = \
665675 (DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ? \
@@ -669,8 +679,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
669679 ) \
670680 }; \
671681 \
672- static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
673- \
674682 PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
675683 \
676684 DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
0 commit comments