From ed365be9e9c0b94817d207d0a3a6a6be32ca7106 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Wed, 29 Oct 2025 19:16:54 +0100 Subject: [PATCH 1/5] soc: nordic: common: add nrfx gpiote instantiation component GPIOTE driver instances are no longer defined within nrfx. Add a component supplementing missing functionality, as GPIOTE driver instances are often shared across the system. Signed-off-by: Nikodem Kastelik --- soc/nordic/common/CMakeLists.txt | 1 + soc/nordic/common/gpiote_nrfx.c | 15 +++++++++++++++ soc/nordic/common/gpiote_nrfx.h | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 soc/nordic/common/gpiote_nrfx.c create mode 100644 soc/nordic/common/gpiote_nrfx.h diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index 8bee4d7542a02..0c277eda79ee3 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -41,3 +41,4 @@ endif() zephyr_library_sources_ifdef(CONFIG_NRF_SYS_EVENT nrf_sys_event.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF_FORCE_CONSTLAT nrf_constlat.c) zephyr_library_sources_ifdef(CONFIG_MRAM_LATENCY mram_latency.c) +zephyr_library_sources(gpiote_nrfx.c) diff --git a/soc/nordic/common/gpiote_nrfx.c b/soc/nordic/common/gpiote_nrfx.c new file mode 100644 index 0000000000000..93c111c00a47a --- /dev/null +++ b/soc/nordic/common/gpiote_nrfx.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "gpiote_nrfx.h" + +#define GPIOTE_NRFX_INST_DEF(instname, reg) \ + nrfx_gpiote_t instname = NRFX_GPIOTE_INSTANCE(reg); +#define GPIOTE_NRFX_INST_DEFINE(node_id) \ + GPIOTE_NRFX_INST_DEF(GPIOTE_NRFX_INST_BY_NODE(node_id), DT_REG_ADDR(node_id)) + +DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_NRFX_INST_DEFINE) diff --git a/soc/nordic/common/gpiote_nrfx.h b/soc/nordic/common/gpiote_nrfx.h new file mode 100644 index 0000000000000..7785eea5ea829 --- /dev/null +++ b/soc/nordic/common/gpiote_nrfx.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_NORDIC_COMMON_GPIOTE_NRFX_H_ +#define SOC_NORDIC_COMMON_GPIOTE_NRFX_H_ + +#include + +#define GPIOTE_NRFX_INST_BY_REG_CONCAT(reg) g_nrfx_gpiote##reg +#define GPIOTE_NRFX_INST_BY_REG(reg) GPIOTE_NRFX_INST_BY_REG_CONCAT(reg) +#define GPIOTE_NRFX_INST_BY_NODE(node) GPIOTE_NRFX_INST_BY_REG(DT_REG_ADDR(node)) + +#define GPIOTE_NRFX_INST_DECL(instname) \ + extern nrfx_gpiote_t instname; +#define GPIOTE_NRFX_INST_DECLARE(node_id) \ + GPIOTE_NRFX_INST_DECL(GPIOTE_NRFX_INST_BY_NODE(node_id)) + +DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_NRFX_INST_DECLARE) + +#endif /* SOC_NORDIC_COMMON_GPIOTE_NRFX_H_ */ From f6402907d454f64ae949a61a80ad007bada50625 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Wed, 15 Oct 2025 22:06:41 +0200 Subject: [PATCH 2/5] drivers: gpio: nrf: align to nrfx_gpiote extracted control block Align GPIOTE shim to changes in nrfx instantiation. Signed-off-by: Nikodem Kastelik --- drivers/gpio/gpio_nrfx.c | 120 +++++++++++++------------ include/zephyr/drivers/gpio/gpio_nrf.h | 27 ++++++ 2 files changed, 91 insertions(+), 56 deletions(-) create mode 100644 include/zephyr/drivers/gpio/gpio_nrf.h diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index fcf0b2f8d27c9..844f590059ca4 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -7,8 +7,10 @@ #define DT_DRV_COMPAT nordic_nrf_gpio #include +#include #include #include +#include #include #include #include @@ -45,9 +47,9 @@ struct gpio_nrfx_cfg { /* gpio_driver_config needs to be first */ struct gpio_driver_config common; NRF_GPIO_Type *port; + nrfx_gpiote_t *gpiote; uint32_t edge_sense; uint8_t port_num; - nrfx_gpiote_t gpiote; #if defined(GPIOTE_FEATURE_FLAG) uint32_t flags; #endif @@ -63,9 +65,16 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port return port->config; } +void * gpio_nrf_gpiote_by_port_get(const struct device *port) +{ + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); + + return cfg->gpiote; +} + static bool has_gpiote(const struct gpio_nrfx_cfg *cfg) { - return cfg->gpiote.p_reg != NULL; + return cfg->gpiote != NULL; } #if NRF_GPIO_HAS_RETENTION_SETCLEAR @@ -111,7 +120,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) { int ret = 0; - nrfx_err_t err = NRFX_SUCCESS; + int err = 0; uint8_t ch; bool free_ch = false; 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, * to be freed when the pin is reconfigured or disconnected. */ if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); - free_ch = (err == NRFX_SUCCESS); + err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch); + free_ch = (err == 0); } if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { /* Ignore the error code. The pin may not have been used. */ - (void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin); + (void)nrfx_gpiote_pin_uninit(cfg->gpiote, abs_pin); } else { /* Remove previously configured trigger when pin is reconfigured. */ 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, .p_trigger_config = &trigger_config, }; - err = nrfx_gpiote_input_configure(&cfg->gpiote, + err = nrfx_gpiote_input_configure(cfg->gpiote, abs_pin, &input_pin_config); - if (err != NRFX_SUCCESS) { - ret = -EINVAL; - + if (err < 0) { goto end; } } @@ -208,7 +215,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, .pull = pull, }; - err = nrfx_gpiote_output_configure(&cfg->gpiote, + err = nrfx_gpiote_output_configure(cfg->gpiote, abs_pin, &output_config, NULL); port_retain_set(cfg, BIT(pin)); @@ -217,12 +224,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, .p_pull_config = &pull, }; - err = nrfx_gpiote_input_configure(&cfg->gpiote, + err = nrfx_gpiote_input_configure(cfg->gpiote, abs_pin, &input_pin_config); } - if (err != NRFX_SUCCESS) { - ret = -EINVAL; + if (err < 0) { goto end; } } @@ -234,8 +240,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, goto end; } #endif - err = nrfx_gpiote_channel_free(&cfg->gpiote, ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + err = nrfx_gpiote_channel_free(cfg->gpiote, ch); + __ASSERT_NO_MSG(err == 0); } end: @@ -391,7 +397,7 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode, NRFX_GPIOTE_TRIGGER_LOTOHI; } -static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch) +static int chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch) { #ifdef GPIOTE_FEATURE_FLAG 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 * - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1 * - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0 */ - nrfx_err_t err = NRFX_SUCCESS; + int err = 0; if (cfg->port_num == 1) { if (pin < 4) { - err = NRFX_ERROR_INVALID_PARAM; + err = -EINVAL; } else { *ch = pin - 4; } } else if (cfg->port_num == 2) { *ch = pin & 0x7; } else { - err = NRFX_ERROR_INVALID_PARAM; + err = -EINVAL; } return err; } #endif - return nrfx_gpiote_channel_alloc(&cfg->gpiote, ch); + return nrfx_gpiote_channel_alloc(cfg->gpiote, ch); } static int gpio_nrfx_pin_interrupt_configure(const struct device *port, @@ -429,7 +435,7 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, { const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); - nrfx_err_t err; + int err; uint8_t ch; if (!has_gpiote(cfg)) { @@ -437,7 +443,7 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, } if (mode == GPIO_INT_MODE_DISABLED) { - nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin); + nrfx_gpiote_trigger_disable(cfg->gpiote, abs_pin); return 0; } @@ -455,11 +461,11 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, if (!(BIT(pin) & cfg->edge_sense) && (mode == GPIO_INT_MODE_EDGE) && (nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) { - err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); - if (err == NRFX_ERROR_INVALID_PARAM) { + err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch); + if (err == -EINVAL) { err = chan_alloc(cfg, pin, &ch); - if (err != NRFX_SUCCESS) { - return -ENOMEM; + if (err < 0) { + return err; } } @@ -473,19 +479,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, /* If edge mode with channel was previously used and we are changing to sense or * level triggered, we must free the channel. */ - err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); - if (err == NRFX_SUCCESS) { - err = nrfx_gpiote_channel_free(&cfg->gpiote, ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + err = nrfx_gpiote_channel_get(cfg->gpiote, abs_pin, &ch); + if (err == 0) { + err = nrfx_gpiote_channel_free(cfg->gpiote, ch); + __ASSERT_NO_MSG(err == 0); } } - err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config); - if (err != NRFX_SUCCESS) { - return -EINVAL; + err = nrfx_gpiote_input_configure(cfg->gpiote, abs_pin, &input_pin_config); + if (err < 0) { + return err; } - nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true); + nrfx_gpiote_trigger_enable(cfg->gpiote, abs_pin, true); return 0; } @@ -574,9 +580,12 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, } #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ -#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ - IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \ - NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0); +#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ + IRQ_CONNECT(DT_IRQN(node_id), \ + DT_IRQ(node_id, priority), \ + nrfx_gpiote_irq_handler, \ + &GPIOTE_NRFX_INST_BY_NODE(node_id), \ + 0); static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action action) { @@ -588,23 +597,23 @@ static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action ac static int gpio_nrfx_init(const struct device *port) { const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); - nrfx_err_t err; + int err; if (!has_gpiote(cfg)) { goto pm_init; } - if (nrfx_gpiote_init_check(&cfg->gpiote)) { + if (nrfx_gpiote_init_check(cfg->gpiote)) { goto pm_init; } - err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/); - if (err != NRFX_SUCCESS) { + err = nrfx_gpiote_init(cfg->gpiote, 0 /*not used*/); + if (err != 0) { return -EIO; } #ifdef CONFIG_GPIO_NRFX_INTERRUPT - nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL); + nrfx_gpiote_global_callback_set(cfg->gpiote, nrfx_gpio_handler, NULL); DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT); #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ @@ -631,35 +640,36 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = { #endif }; -#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance) - -#define GPIOTE_INSTANCE(id) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ - (NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \ - ({ .p_reg = NULL })) - /* Device instantiation is done with node labels because 'port_num' is * the peripheral number by SoC numbering. We therefore cannot use * DT_INST APIs here without wider changes. */ +#define HAS_GPIOTE(id) DT_INST_NODE_HAS_PROP(id, gpiote_instance) + #define GPIOTE_CHECK(id) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ - (BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \ + COND_CODE_1(HAS_GPIOTE(id), \ + (BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \ "Please enable GPIOTE instance for used GPIO port!")), \ ()) +#define GPIOTE_REF(id) \ + COND_CODE_1(HAS_GPIOTE(id), \ + (&GPIOTE_NRFX_INST_BY_NODE(GPIOTE_PHANDLE(id))), \ + (NULL)) + #define GPIO_NRF_DEVICE(id) \ GPIOTE_CHECK(id); \ + static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \ static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \ .common = { \ .port_pin_mask = \ GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \ }, \ .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \ - .port_num = DT_INST_PROP(id, port), \ + .gpiote = GPIOTE_REF(id), \ .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \ - .gpiote = GPIOTE_INSTANCE(id), \ + .port_num = DT_INST_PROP(id, port), \ IF_ENABLED(GPIOTE_FEATURE_FLAG, \ (.flags = \ (DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ? \ @@ -669,8 +679,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = { ) \ }; \ \ - static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \ - \ PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \ \ DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \ diff --git a/include/zephyr/drivers/gpio/gpio_nrf.h b/include/zephyr/drivers/gpio/gpio_nrf.h new file mode 100644 index 0000000000000..8802e8a1702ec --- /dev/null +++ b/include/zephyr/drivers/gpio/gpio_nrf.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H +#define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Get pointer to GPIOTE driver instance + * associated with specified port device node. + * + * @param port Pointer to port device node. + * + * @return Pointer to GPIOTE driver instance. NULL if not found. + */ +void * gpio_nrf_gpiote_by_port_get(const struct device *port); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H */ From e4e2668b4b1af4308c422271d4a4368faf7d8a22 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Tue, 28 Oct 2025 18:14:07 +0100 Subject: [PATCH 3/5] drivers: spi: nrf: align to nrfx_gpiote with extracted control block GPIOTE driver instances are no longer defined within nrfx. Signed-off-by: Nikodem Kastelik --- drivers/spi/spi_nrfx_common.c | 14 +++++++------- drivers/spi/spi_nrfx_common.h | 16 +++++++++------- drivers/spi/spi_nrfx_spi.c | 8 ++++---- drivers/spi/spi_nrfx_spim.c | 20 +++++++++++--------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/spi/spi_nrfx_common.c b/drivers/spi/spi_nrfx_common.c index 04a11c2367a92..17fd3f52ba33f 100644 --- a/drivers/spi/spi_nrfx_common.c +++ b/drivers/spi/spi_nrfx_common.c @@ -7,7 +7,7 @@ #include "spi_nrfx_common.h" #include -int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) +int spi_nrfx_wake_init(nrfx_gpiote_t *gpiote, uint32_t wake_pin) { nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN; uint8_t ch; @@ -20,23 +20,23 @@ int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) .p_trigger_config = &trigger_config, .p_handler_config = NULL, }; - nrfx_err_t res; + int res; res = nrfx_gpiote_channel_alloc(gpiote, &ch); - if (res != NRFX_SUCCESS) { - return -ENODEV; + if (res < 0) { + return res; } res = nrfx_gpiote_input_configure(gpiote, wake_pin, &input_config); - if (res != NRFX_SUCCESS) { + if (res < 0) { nrfx_gpiote_channel_free(gpiote, ch); - return -EIO; + return res; } return 0; } -int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) +int spi_nrfx_wake_request(nrfx_gpiote_t *gpiote, uint32_t wake_pin) { nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(gpiote, wake_pin); uint32_t start_cycles; diff --git a/drivers/spi/spi_nrfx_common.h b/drivers/spi/spi_nrfx_common.h index 0cf17e2a0356d..9a08944107833 100644 --- a/drivers/spi/spi_nrfx_common.h +++ b/drivers/spi/spi_nrfx_common.h @@ -9,16 +9,18 @@ #include #include +#include +#include #define WAKE_PIN_NOT_USED UINT32_MAX -#define WAKE_GPIOTE_INSTANCE(node_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, wake_gpios), \ - (NRFX_GPIOTE_INSTANCE( \ - NRF_DT_GPIOTE_INST(node_id, wake_gpios))), \ - ({0})) +#define WAKE_GPIOTE_NODE(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, wake_gpios), \ + (&GPIOTE_NRFX_INST_BY_NODE(DT_PHANDLE(DT_PHANDLE(node_id, wake_gpios), \ + gpiote_instance))), \ + (NULL)) -int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); -int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); +int spi_nrfx_wake_init(nrfx_gpiote_t *gpiote, uint32_t wake_pin); +int spi_nrfx_wake_request(nrfx_gpiote_t *gpiote, uint32_t wake_pin); #endif /* ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ */ diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index 7608f3ab9487b..b32a80edb917b 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -31,8 +31,8 @@ struct spi_nrfx_config { nrfx_spi_config_t def_config; void (*irq_connect)(void); const struct pinctrl_dev_config *pcfg; + nrfx_gpiote_t *wake_gpiote; uint32_t wake_pin; - nrfx_gpiote_t wake_gpiote; }; static void event_handler(const nrfx_spi_evt_t *p_event, void *p_context); @@ -241,7 +241,7 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + error = spi_nrfx_wake_request(dev_config->wake_gpiote, dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); @@ -395,7 +395,7 @@ static int spi_nrfx_init(const struct device *dev) } if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); + err = spi_nrfx_wake_init(dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -458,9 +458,9 @@ static int spi_nrfx_init(const struct device *dev) }, \ .irq_connect = irq_connect##idx, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPI(idx)), \ + .wake_gpiote = WAKE_GPIOTE_NODE(SPI(idx)), \ .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPI(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ - .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPI(idx)), \ }; \ BUILD_ASSERT(!DT_NODE_HAS_PROP(SPI(idx), wake_gpios) || \ !(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index b58b51d62408b..21da1f4558ccf 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -81,8 +81,8 @@ struct spi_nrfx_config { #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 bool anomaly_58_workaround; #endif + nrfx_gpiote_t *wake_gpiote; uint32_t wake_pin; - nrfx_gpiote_t wake_gpiote; void *mem_reg; }; @@ -510,7 +510,7 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + error = spi_nrfx_wake_request(dev_config->wake_gpiote, dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); @@ -683,7 +683,7 @@ static int spi_nrfx_init(const struct device *dev) (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); + err = spi_nrfx_wake_init(dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -782,17 +782,19 @@ static int spi_nrfx_deinit(const struct device *dev) .orc = SPIM_PROP(idx, overrun_character), \ SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ }, \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIM(idx)), \ - .max_chunk_len = BIT_MASK(SPIM_PROP(idx, easydma_maxcnt_bits)),\ + .irq_connect = irq_connect##inst, \ + .max_chunk_len = BIT_MASK( \ + DT_INST_PROP(inst, easydma_maxcnt_bits)), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ COND_CODE_1(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58, \ (.anomaly_58_workaround = \ SPIM_PROP(idx, anomaly_58_workaround),), \ ()) \ - .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \ + .wake_gpiote = WAKE_GPIOTE_NODE(DT_DRV_INST(inst)), \ + .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(DT_DRV_INST(inst), \ + wake_gpios, \ WAKE_PIN_NOT_USED), \ - .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ - .mem_reg = DMM_DEV_TO_REG(SPIM(idx)), \ + .mem_reg = DMM_DEV_TO_REG(DT_DRV_INST(inst)), \ }; \ BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ From b4fed27c54129396083f095ec93e758b57ab0659 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Wed, 29 Oct 2025 19:15:51 +0100 Subject: [PATCH 4/5] drivers: pwm: pwm_nrf_sw: align to nrfx_gpiote with extracted cb GPIOTE driver instances are no longer defined within nrfx. Signed-off-by: Nikodem Kastelik --- drivers/pwm/pwm_nrf_sw.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/pwm/pwm_nrf_sw.c b/drivers/pwm/pwm_nrf_sw.c index e4cc7ecb42b94..9ba01a796c53c 100644 --- a/drivers/pwm/pwm_nrf_sw.c +++ b/drivers/pwm/pwm_nrf_sw.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -62,7 +63,7 @@ struct pwm_config { NRF_RTC_Type *rtc; NRF_TIMER_Type *timer; }; - nrfx_gpiote_t gpiote[PWM_0_MAP_SIZE]; + nrfx_gpiote_t * gpiote[PWM_0_MAP_SIZE]; uint8_t psel_ch[PWM_0_MAP_SIZE]; uint8_t initially_inverted; uint8_t map_size; @@ -163,7 +164,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, } } - gpiote = config->gpiote[channel].p_reg; + gpiote = config->gpiote[channel]->p_reg; psel_ch = config->psel_ch[channel]; gpiote_ch = data->gpiote_ch[channel]; ppi_chs = data->ppi_ch[channel]; @@ -351,7 +352,7 @@ static int pwm_nrf_sw_init(const struct device *dev) NRF_RTC_Type *rtc = pwm_config_rtc(config); for (uint32_t i = 0; i < config->map_size; i++) { - nrfx_err_t err; + int err; /* Allocate resources. */ for (uint32_t j = 0; j < PPI_PER_CH; j++) { @@ -365,14 +366,14 @@ static int pwm_nrf_sw_init(const struct device *dev) } } - err = nrfx_gpiote_channel_alloc(&config->gpiote[i], + err = nrfx_gpiote_channel_alloc(config->gpiote[i], &data->gpiote_ch[i]); - if (err != NRFX_SUCCESS) { + if (err < 0) { /* Do not free allocated resource. It is a fatal condition, * system requires reconfiguration. */ LOG_ERR("Failed to allocate GPIOTE channel"); - return -ENOMEM; + return err; } /* Set initial state of the output pins. */ @@ -410,7 +411,8 @@ static int pwm_nrf_sw_init(const struct device *dev) ? BIT(_idx) : 0) | #define GPIOTE_AND_COMMA(_node_id, _prop, _idx) \ - NRFX_GPIOTE_INSTANCE(NRF_DT_GPIOTE_INST_BY_IDX(_node_id, _prop, _idx)), + &GPIOTE_NRFX_INST_BY_NODE(DT_PHANDLE(DT_GPIO_CTLR_BY_IDX(_node_id, _prop, _idx), \ + gpiote_instance)) static const struct pwm_config pwm_nrf_sw_0_config = { COND_CODE_1(USE_RTC, (.rtc), (.timer)) = GENERATOR_ADDR, From 916f9664e0a8ae301bbcf43cdef0eee5e01b4231 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Wed, 29 Oct 2025 20:22:07 +0100 Subject: [PATCH 5/5] drivers: display: nrf_led_matrix: align to nrfx_gpiote with extracted cb GPIOTE driver instances are no longer defined within nrfx. Signed-off-by: Nikodem Kastelik --- drivers/display/display_nrf_led_matrix.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/display/display_nrf_led_matrix.c b/drivers/display/display_nrf_led_matrix.c index 79ae6652807a7..bda0ef40a0b5e 100644 --- a/drivers/display/display_nrf_led_matrix.c +++ b/drivers/display/display_nrf_led_matrix.c @@ -13,10 +13,10 @@ #include #endif #include +#include #ifdef PPI_PRESENT #include #endif -#include #include #include LOG_MODULE_REGISTER(nrf_led_matrix, CONFIG_DISPLAY_LOG_LEVEL); @@ -91,7 +91,7 @@ struct display_drv_config { #if USE_PWM NRF_PWM_Type *pwm; #else - nrfx_gpiote_t gpiote; + nrfx_gpiote_t *gpiote; #endif uint8_t rows[ROW_COUNT]; uint8_t cols[COL_COUNT]; @@ -327,7 +327,7 @@ static void prepare_pixel_pulse(const struct device *dev, /* First timer channel is used for timing the period of pulses. */ nrf_timer_cc_set(dev_config->timer, 1 + channel_idx, pulse); - dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; + dev_config->gpiote->p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; #endif /* USE_PWM */ } @@ -357,7 +357,7 @@ static void timer_irq_handler(void *arg) } #else for (int i = 0; i < GROUP_SIZE; ++i) { - dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0; + dev_config->gpiote->p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0; } #endif @@ -437,7 +437,7 @@ static int instance_init(const struct device *dev) nrf_pwm_loop_set(dev_config->pwm, 0); nrf_pwm_shorts_set(dev_config->pwm, NRF_PWM_SHORT_SEQEND0_STOP_MASK); #else - nrfx_err_t err; + int err; nrf_ppi_channel_t ppi_ch; for (int i = 0; i < GROUP_SIZE; ++i) { @@ -453,20 +453,20 @@ static int instance_init(const struct device *dev) return -ENOMEM; } - err = nrfx_gpiote_channel_alloc(&dev_config->gpiote, gpiote_ch); - if (err != NRFX_SUCCESS) { + err = nrfx_gpiote_channel_alloc(dev_config->gpiote, gpiote_ch); + if (err < 0) { LOG_ERR("Failed to allocate GPIOTE channel."); /* Do not bother with freeing resources allocated * so far. The application needs to be reconfigured * anyway. */ - return -ENOMEM; + return err; } nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, nrf_timer_event_address_get(dev_config->timer, nrf_timer_compare_event_get(1 + i)), - nrf_gpiote_event_address_get(dev_config->gpiote.p_reg, + nrf_gpiote_event_address_get(dev_config->gpiote->p_reg, nrf_gpiote_out_task_get(*gpiote_ch))); nrf_ppi_channel_enable(NRF_PPI, ppi_ch); } @@ -537,13 +537,15 @@ DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, CHECK_GPIOTE_INST) [GET_DT_ROW_IDX(idx) * COL_COUNT + \ GET_DT_COL_IDX(idx)] = idx, +//NRFX_GPIOTE_INSTANCE(NRF_DT_GPIOTE_INST_BY_IDX(MATRIX_NODE, col_gpios, 0)), + static const struct display_drv_config instance_config = { .timer = (NRF_TIMER_Type *)DT_REG_ADDR(TIMER_NODE), #if USE_PWM .pwm = (NRF_PWM_Type *)DT_REG_ADDR(PWM_NODE), #else - .gpiote = NRFX_GPIOTE_INSTANCE( - NRF_DT_GPIOTE_INST_BY_IDX(MATRIX_NODE, col_gpios, 0)), + .gpiote = &GPIOTE_NRFX_INST_BY_NODE( \ + DT_PHANDLE(DT_GPIO_CTLR_BY_IDX(MATRIX_NODE, col_gpios, 0), gpiote_instance)), #endif .rows = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, row_gpios, GET_PIN_INFO) }, .cols = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, GET_PIN_INFO) },