Skip to content

Commit 9153990

Browse files
nika-nordicjaz1-nordic
authored andcommitted
[nrf fromlist] drivers: gpio: nrf: align to nrfx_gpiote extracted control block
Align GPIOTE shim to changes in nrfx instantiation. Upstream PR #: 98527 Signed-off-by: Nikodem Kastelik <[email protected]>
1 parent 89d7056 commit 9153990

File tree

2 files changed

+91
-56
lines changed

2 files changed

+91
-56
lines changed

drivers/gpio/gpio_nrfx.c

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
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+
6675
static 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

241247
end:
@@ -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

425431
static 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

581590
static 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
588597
static 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, \
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H
8+
#define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
/** @brief Get pointer to GPIOTE driver instance
15+
* associated with specified port device node.
16+
*
17+
* @param port Pointer to port device node.
18+
*
19+
* @return Pointer to GPIOTE driver instance. NULL if not found.
20+
*/
21+
void * gpio_nrf_gpiote_by_port_get(const struct device *port);
22+
23+
#ifdef __cplusplus
24+
}
25+
#endif
26+
27+
#endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_NRF_H */

0 commit comments

Comments
 (0)