2020#include <nrf/gpd.h>
2121#endif
2222
23+ #define GPIOTE_PHANDLE (id ) DT_INST_PHANDLE(id, gpiote_instance)
24+ #define GPIOTE_PROP (idx , prop ) DT_PROP(GPIOTE(idx), prop)
25+
26+ #define IS_NO_PORT_INSTANCE (id ) DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ||
27+ #define IS_FIXED_CH_INSTANCE (id ) DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ||
28+
29+ #if DT_INST_FOREACH_STATUS_OKAY (IS_NO_PORT_INSTANCE ) 0
30+ #define GPIOTE_NO_PORT_EVT_SUPPORT 1
31+ #endif
32+
33+ #if DT_INST_FOREACH_STATUS_OKAY (IS_FIXED_CH_INSTANCE ) 0
34+ #define GPIOTE_FIXED_CH_SUPPORT 1
35+ #endif
36+
37+ #if defined(GPIOTE_NO_PORT_EVT_SUPPORT ) || defined(GPIOTE_FIXED_CH_SUPPORT )
38+ #define GPIOTE_FEATURE_FLAG 1
39+ #define GPIOTE_FLAG_NO_PORT_EVT BIT(0)
40+ #define GPIOTE_FLAG_FIXED_CHAN BIT(1)
41+ #endif
42+
2343struct gpio_nrfx_data {
2444 /* gpio_driver_data needs to be first */
2545 struct gpio_driver_data common ;
@@ -33,6 +53,9 @@ struct gpio_nrfx_cfg {
3353 uint32_t edge_sense ;
3454 uint8_t port_num ;
3555 nrfx_gpiote_t gpiote ;
56+ #if defined(GPIOTE_FEATURE_FLAG )
57+ uint32_t flags ;
58+ #endif
3659#ifdef CONFIG_SOC_NRF54H20_GPD
3760 uint8_t pad_pd ;
3861#endif
@@ -180,6 +203,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
180203 abs_pin , & input_pin_config );
181204 if (err != NRFX_SUCCESS ) {
182205 ret = - EINVAL ;
206+
183207 goto end ;
184208 }
185209 }
@@ -211,13 +235,21 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
211235 }
212236
213237 if (IS_ENABLED (CONFIG_GPIO_NRFX_INTERRUPT ) && free_ch ) {
238+ #ifdef GPIOTE_FEATURE_FLAG
239+ /* Fixed channel was used, no need to free. */
240+ if (cfg -> flags & GPIOTE_FLAG_FIXED_CHAN ) {
241+ goto end ;
242+ }
243+ #endif
214244 err = nrfx_gpiote_channel_free (& cfg -> gpiote , ch );
215245 __ASSERT_NO_MSG (err == NRFX_SUCCESS );
216246 }
217247
218248end :
219249 gpio_nrfx_gpd_retain_set (port , BIT (pin ));
220- return pm_device_runtime_put (port );
250+ int pm_ret = pm_device_runtime_put (port );
251+
252+ return (ret != 0 ) ? ret : pm_ret ;
221253}
222254
223255#ifdef CONFIG_GPIO_GET_CONFIG
@@ -393,6 +425,37 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
393425 NRFX_GPIOTE_TRIGGER_LOTOHI ;
394426}
395427
428+ static nrfx_err_t chan_alloc (const struct gpio_nrfx_cfg * cfg , gpio_pin_t pin , uint8_t * ch )
429+ {
430+ #ifdef GPIOTE_FEATURE_FLAG
431+ if (cfg -> flags & GPIOTE_FLAG_FIXED_CHAN ) {
432+ /* Currently fixed channel relation is only present in one instance (GPIOTE0 on
433+ * cpurad). The rules are following:
434+ * - GPIOTE0 can only be used with P1 (pins 4-11) and P2 (pins (0-11))
435+ * - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1
436+ * - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0
437+ */
438+ nrfx_err_t err = NRFX_SUCCESS ;
439+
440+ if (cfg -> port_num == 1 ) {
441+ if (pin < 4 ) {
442+ err = NRFX_ERROR_INVALID_PARAM ;
443+ } else {
444+ * ch = pin - 4 ;
445+ }
446+ } else if (cfg -> port_num == 2 ) {
447+ * ch = pin & 0x7 ;
448+ } else {
449+ err = NRFX_ERROR_INVALID_PARAM ;
450+ }
451+
452+ return err ;
453+ }
454+ #endif
455+
456+ return nrfx_gpiote_channel_alloc (& cfg -> gpiote , ch );
457+ }
458+
396459static int gpio_nrfx_pin_interrupt_configure (const struct device * port ,
397460 gpio_pin_t pin ,
398461 enum gpio_int_mode mode ,
@@ -428,14 +491,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
428491 (nrf_gpio_pin_dir_get (abs_pin ) == NRF_GPIO_PIN_DIR_INPUT )) {
429492 err = nrfx_gpiote_channel_get (& cfg -> gpiote , abs_pin , & ch );
430493 if (err == NRFX_ERROR_INVALID_PARAM ) {
431- err = nrfx_gpiote_channel_alloc ( & cfg -> gpiote , & ch );
494+ err = chan_alloc ( cfg , pin , & ch );
432495 if (err != NRFX_SUCCESS ) {
433496 return - ENOMEM ;
434497 }
435498 }
436499
437500 trigger_config .p_in_channel = & ch ;
438501 } else {
502+ #ifdef GPIOTE_FEATURE_FLAG
503+ if (cfg -> flags & GPIOTE_FLAG_NO_PORT_EVT ) {
504+ return - ENOTSUP ;
505+ }
506+ #endif
439507 /* If edge mode with channel was previously used and we are changing to sense or
440508 * level triggered, we must free the channel.
441509 */
@@ -641,7 +709,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
641709#endif
642710};
643711
644- #define GPIOTE_PHANDLE (id ) DT_INST_PHANDLE(id, gpiote_instance)
645712#define GPIOTE_INST (id ) DT_PROP(GPIOTE_PHANDLE(id), instance)
646713
647714#define GPIOTE_INSTANCE (id ) \
@@ -668,30 +735,37 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
668735#define PAD_PD (inst )
669736#endif
670737
671- #define GPIO_NRF_DEVICE (id ) \
672- GPIOTE_CHECK(id); \
673- static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
674- .common = { \
675- .port_pin_mask = \
676- GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \
677- }, \
678- .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
679- .port_num = DT_INST_PROP(id, port), \
680- .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
681- .gpiote = GPIOTE_INSTANCE(id), \
682- PAD_PD(id) \
683- }; \
684- \
685- static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
686- \
687- PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
688- \
689- DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
690- PM_DEVICE_DT_INST_GET(id), \
691- &gpio_nrfx_p##id##_data, \
692- &gpio_nrfx_p##id##_cfg, \
693- PRE_KERNEL_1, \
694- CONFIG_GPIO_INIT_PRIORITY, \
738+ #define GPIO_NRF_DEVICE (id ) \
739+ GPIOTE_CHECK(id); \
740+ static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
741+ .common = { \
742+ .port_pin_mask = \
743+ GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \
744+ }, \
745+ .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
746+ .port_num = DT_INST_PROP(id, port), \
747+ .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
748+ .gpiote = GPIOTE_INSTANCE(id), \
749+ IF_ENABLED(GPIOTE_FEATURE_FLAG, \
750+ (.flags = \
751+ (DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ? \
752+ GPIOTE_FLAG_NO_PORT_EVT : 0) | \
753+ (DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ? \
754+ GPIOTE_FLAG_FIXED_CHAN : 0),) \
755+ ) \
756+ PAD_PD(id) \
757+ }; \
758+ \
759+ static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
760+ \
761+ PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
762+ \
763+ DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \
764+ PM_DEVICE_DT_INST_GET(id), \
765+ &gpio_nrfx_p##id##_data, \
766+ &gpio_nrfx_p##id##_cfg, \
767+ PRE_KERNEL_1, \
768+ CONFIG_GPIO_INIT_PRIORITY, \
695769 &gpio_nrfx_drv_api_funcs);
696770
697771DT_INST_FOREACH_STATUS_OKAY (GPIO_NRF_DEVICE )
0 commit comments