Skip to content

Commit 31f3cc0

Browse files
committed
drivers: gpio: nrf: align to nrfx_gpiote extracted control block
Align GPIOTE shim to changes in nrfx instantiation. Signed-off-by: Nikodem Kastelik <nikodem.kastelik@nordicsemi.no>
1 parent 019e3de commit 31f3cc0

File tree

2 files changed

+129
-61
lines changed

2 files changed

+129
-61
lines changed

drivers/gpio/gpio_nrfx.c

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <nrfx_gpiote.h>
1010
#include <string.h>
1111
#include <zephyr/drivers/gpio.h>
12+
#include <zephyr/drivers/gpio/gpio_nrf.h>
1213
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
1314
#include <zephyr/irq.h>
1415
#include <zephyr/pm/device.h>
@@ -42,19 +43,28 @@
4243
#define GPIOTE_FLAG_FIXED_CHAN BIT(1)
4344
#endif
4445

46+
#define GPIOTE_INST_ENUM(i) DT_CAT3(NRFX_GPIOTE, i, _INST_IDX)
47+
#define GPIOTE_INST_ENUM_NODE(node_id) GPIOTE_INST_ENUM(DT_PROP(node_id, instance))
48+
49+
#define GPIOTE_NRFX_INST_DEF(index, reg) [index] = NRFX_GPIOTE_INSTANCE(reg),
50+
#define GPIOTE_NRFX_INST(node_id) \
51+
GPIOTE_NRFX_INST_DEF(GPIOTE_INST_ENUM_NODE(node_id), DT_REG_ADDR(node_id))
52+
4553
struct gpio_nrfx_data {
4654
/* gpio_driver_data needs to be first */
4755
struct gpio_driver_data common;
56+
nrfx_gpiote_t *gpiote;
4857
sys_slist_t callbacks;
4958
};
5059

5160
struct gpio_nrfx_cfg {
5261
/* gpio_driver_config needs to be first */
5362
struct gpio_driver_config common;
63+
void (*irq_connect)(void);
5464
NRF_GPIO_Type *port;
5565
uint32_t edge_sense;
5666
uint8_t port_num;
57-
nrfx_gpiote_t gpiote;
67+
uint8_t gpiote_num;
5868
#if GPIO_HAS_PAD_GROUP
5969
const struct device *pad_group;
6070
#endif
@@ -63,6 +73,19 @@ struct gpio_nrfx_cfg {
6373
#endif
6474
};
6575

76+
static nrfx_gpiote_t gpiote_nrfx[] = {
77+
DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_NRFX_INST)
78+
};
79+
80+
void * gpio_nrf_gpiote_by_idx_get(uint8_t idx)
81+
{
82+
if (idx >= ARRAY_SIZE(gpiote_nrfx)) {
83+
return NULL;
84+
}
85+
86+
return &gpiote_nrfx[idx];
87+
}
88+
6689
static inline struct gpio_nrfx_data *get_port_data(const struct device *port)
6790
{
6891
return port->data;
@@ -73,9 +96,9 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port
7396
return port->config;
7497
}
7598

76-
static bool has_gpiote(const struct gpio_nrfx_cfg *cfg)
99+
static bool has_gpiote(const struct gpio_nrfx_data *data)
77100
{
78-
return cfg->gpiote.p_reg != NULL;
101+
return data->gpiote != NULL;
79102
}
80103

81104
static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
@@ -93,10 +116,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
93116
gpio_flags_t flags)
94117
{
95118
int ret = 0;
96-
nrfx_err_t err = NRFX_SUCCESS;
119+
int err = 0;
97120
uint8_t ch;
98121
bool free_ch = false;
99122
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
123+
struct gpio_nrfx_data *data = get_port_data(port);
100124
nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
101125
nrf_gpio_pin_pull_t pull = get_pull(flags);
102126
nrf_gpio_pin_drive_t drive;
@@ -142,7 +166,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
142166
nrf_gpio_port_out_clear(cfg->port, BIT(pin));
143167
}
144168

145-
if (!has_gpiote(cfg)) {
169+
if (!has_gpiote(data)) {
146170
nrf_gpio_pin_dir_t dir = (flags & GPIO_OUTPUT)
147171
? NRF_GPIO_PIN_DIR_OUTPUT
148172
: NRF_GPIO_PIN_DIR_INPUT;
@@ -159,13 +183,13 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
159183
* to be freed when the pin is reconfigured or disconnected.
160184
*/
161185
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
162-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
163-
free_ch = (err == NRFX_SUCCESS);
186+
err = nrfx_gpiote_channel_get(data->gpiote, abs_pin, &ch);
187+
free_ch = (err == 0);
164188
}
165189

166190
if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
167191
/* Ignore the error code. The pin may not have been used. */
168-
(void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin);
192+
(void)nrfx_gpiote_pin_uninit(data->gpiote, abs_pin);
169193
} else {
170194
/* Remove previously configured trigger when pin is reconfigured. */
171195
if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
@@ -176,11 +200,9 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
176200
.p_trigger_config = &trigger_config,
177201
};
178202

179-
err = nrfx_gpiote_input_configure(&cfg->gpiote,
203+
err = nrfx_gpiote_input_configure(data->gpiote,
180204
abs_pin, &input_pin_config);
181-
if (err != NRFX_SUCCESS) {
182-
ret = -EINVAL;
183-
205+
if (err < 0) {
184206
goto end;
185207
}
186208
}
@@ -194,19 +216,18 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
194216
.pull = pull,
195217
};
196218

197-
err = nrfx_gpiote_output_configure(&cfg->gpiote,
219+
err = nrfx_gpiote_output_configure(data->gpiote,
198220
abs_pin, &output_config, NULL);
199221
} else {
200222
nrfx_gpiote_input_pin_config_t input_pin_config = {
201223
.p_pull_config = &pull,
202224
};
203225

204-
err = nrfx_gpiote_input_configure(&cfg->gpiote,
226+
err = nrfx_gpiote_input_configure(data->gpiote,
205227
abs_pin, &input_pin_config);
206228
}
207229

208-
if (err != NRFX_SUCCESS) {
209-
ret = -EINVAL;
230+
if (err < 0) {
210231
goto end;
211232
}
212233
}
@@ -218,8 +239,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
218239
goto end;
219240
}
220241
#endif
221-
err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
222-
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
242+
err = nrfx_gpiote_channel_free(data->gpiote, ch);
243+
__ASSERT_NO_MSG(err == 0);
223244
}
224245

225246
end:
@@ -393,7 +414,7 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
393414
NRFX_GPIOTE_TRIGGER_LOTOHI;
394415
}
395416

396-
static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch)
417+
static int chan_alloc(struct gpio_nrfx_data *data, gpio_pin_t pin, uint8_t *ch)
397418
{
398419
#ifdef GPIOTE_FEATURE_FLAG
399420
if (cfg->flags & GPIOTE_FLAG_FIXED_CHAN) {
@@ -403,25 +424,25 @@ static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, ui
403424
* - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1
404425
* - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0
405426
*/
406-
nrfx_err_t err = NRFX_SUCCESS;
427+
int err = 0;
407428

408429
if (cfg->port_num == 1) {
409430
if (pin < 4) {
410-
err = NRFX_ERROR_INVALID_PARAM;
431+
err = -EINVAL;
411432
} else {
412433
*ch = pin - 4;
413434
}
414435
} else if (cfg->port_num == 2) {
415436
*ch = pin & 0x7;
416437
} else {
417-
err = NRFX_ERROR_INVALID_PARAM;
438+
err = -EINVAL;
418439
}
419440

420441
return err;
421442
}
422443
#endif
423444

424-
return nrfx_gpiote_channel_alloc(&cfg->gpiote, ch);
445+
return nrfx_gpiote_channel_alloc(data->gpiote, ch);
425446
}
426447

427448
static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
@@ -430,16 +451,17 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
430451
enum gpio_int_trig trig)
431452
{
432453
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
454+
struct gpio_nrfx_data *data = get_port_data(port);
433455
uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
434-
nrfx_err_t err;
456+
int err;
435457
uint8_t ch;
436458

437-
if (!has_gpiote(cfg)) {
459+
if (!has_gpiote(data)) {
438460
return -ENOTSUP;
439461
}
440462

441463
if (mode == GPIO_INT_MODE_DISABLED) {
442-
nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin);
464+
nrfx_gpiote_trigger_disable(data->gpiote, abs_pin);
443465

444466
return 0;
445467
}
@@ -457,11 +479,11 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
457479
if (!(BIT(pin) & cfg->edge_sense) &&
458480
(mode == GPIO_INT_MODE_EDGE) &&
459481
(nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) {
460-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
461-
if (err == NRFX_ERROR_INVALID_PARAM) {
462-
err = chan_alloc(cfg, pin, &ch);
463-
if (err != NRFX_SUCCESS) {
464-
return -ENOMEM;
482+
err = nrfx_gpiote_channel_get(data->gpiote, abs_pin, &ch);
483+
if (err == -EINVAL) {
484+
err = chan_alloc(data, pin, &ch);
485+
if (err < 0) {
486+
return err;
465487
}
466488
}
467489

@@ -475,19 +497,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
475497
/* If edge mode with channel was previously used and we are changing to sense or
476498
* level triggered, we must free the channel.
477499
*/
478-
err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
479-
if (err == NRFX_SUCCESS) {
480-
err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
481-
__ASSERT_NO_MSG(err == NRFX_SUCCESS);
500+
err = nrfx_gpiote_channel_get(data->gpiote, abs_pin, &ch);
501+
if (err == 0) {
502+
err = nrfx_gpiote_channel_free(data->gpiote, ch);
503+
__ASSERT_NO_MSG(err == 0);
482504
}
483505
}
484506

485-
err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config);
486-
if (err != NRFX_SUCCESS) {
487-
return -EINVAL;
507+
err = nrfx_gpiote_input_configure(data->gpiote, abs_pin, &input_pin_config);
508+
if (err < 0) {
509+
return err;
488510
}
489511

490-
nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true);
512+
nrfx_gpiote_trigger_enable(data->gpiote, abs_pin, true);
491513

492514
return 0;
493515
}
@@ -577,8 +599,8 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
577599
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
578600

579601
#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \
580-
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \
581-
NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0);
602+
IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_gpiote_irq_handler, \
603+
, 0);
582604

583605
static int gpio_nrfx_pm_suspend(const struct device *port)
584606
{
@@ -626,24 +648,27 @@ static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action ac
626648
static int gpio_nrfx_init(const struct device *port)
627649
{
628650
const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
629-
nrfx_err_t err;
651+
struct gpio_nrfx_data *data = get_port_data(port);
652+
int err;
630653

631-
if (!has_gpiote(cfg)) {
654+
data->gpiote = gpio_nrf_gpiote_by_idx_get(cfg->gpiote_num);
655+
656+
if (!has_gpiote(data)) {
632657
goto pm_init;
633658
}
634659

635-
if (nrfx_gpiote_init_check(&cfg->gpiote)) {
660+
if (nrfx_gpiote_init_check(data->gpiote)) {
636661
goto pm_init;
637662
}
638663

639-
err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/);
640-
if (err != NRFX_SUCCESS) {
664+
err = nrfx_gpiote_init(data->gpiote, 0 /*not used*/);
665+
if (err != 0) {
641666
return -EIO;
642667
}
643668

644669
#ifdef CONFIG_GPIO_NRFX_INTERRUPT
645-
nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL);
646-
DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT);
670+
nrfx_gpiote_global_callback_set(data->gpiote, nrfx_gpio_handler, NULL);
671+
get_port_cfg(port)->irq_connect();
647672
#endif /* CONFIG_GPIO_NRFX_INTERRUPT */
648673

649674
pm_init:
@@ -669,42 +694,55 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
669694
#endif
670695
};
671696

672-
#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance)
673-
674-
#define GPIOTE_INSTANCE(id) \
675-
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \
676-
(NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \
677-
({ .p_reg = NULL }))
678-
679697
/* Device instantiation is done with node labels because 'port_num' is
680698
* the peripheral number by SoC numbering. We therefore cannot use
681699
* DT_INST APIs here without wider changes.
682700
*/
683701

702+
#define HAS_GPIOTE(id) DT_INST_NODE_HAS_PROP(id, gpiote_instance)
703+
684704
#define GPIOTE_CHECK(id) \
685-
COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \
686-
(BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
705+
COND_CODE_1(HAS_GPIOTE(id), \
706+
(BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(GPIOTE_PHANDLE(id)), \
687707
"Please enable GPIOTE instance for used GPIO port!")), \
688708
())
689709

710+
#define GPIOTE_IRQ(id) \
711+
COND_CODE_1(HAS_GPIOTE(id), \
712+
(static void irq_connect##id(void) \
713+
{ \
714+
IRQ_CONNECT(DT_IRQN(GPIOTE_PHANDLE(id)), \
715+
DT_IRQ(GPIOTE_PHANDLE(id), priority), \
716+
nrfx_gpiote_irq_handler, &gpio_nrfx_p##id##_data.gpiote, 0); \
717+
}),())
718+
690719
#if GPIO_HAS_PAD_GROUP
691720
#define GPIO_NRF_PAD_GROUP_INIT(id) \
692721
.pad_group = DEVICE_DT_GET(DT_INST_CHILD(id, pad_group)),
693722
#else
694723
#define GPIO_NRF_PAD_GROUP_INIT(id)
695724
#endif
696725

726+
#define GPIOTE_IDX(id ) \
727+
COND_CODE_1(HAS_GPIOTE(id), \
728+
(GPIOTE_INST_ENUM_NODE(GPIOTE_PHANDLE(id))), \
729+
(GPIO_NRF_GPIOTE_IDX_INVALID))
730+
697731
#define GPIO_NRF_DEVICE(id) \
698732
GPIOTE_CHECK(id); \
733+
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
734+
GPIOTE_IRQ(id) \
699735
static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
700736
.common = { \
701737
.port_pin_mask = \
702738
GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \
703739
}, \
740+
.irq_connect = \
741+
COND_CODE_1(HAS_GPIOTE(id), (irq_connect##id), (NULL)), \
704742
.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \
705-
.port_num = DT_INST_PROP(id, port), \
706743
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
707-
.gpiote = GPIOTE_INSTANCE(id), \
744+
.port_num = DT_INST_PROP(id, port), \
745+
.gpiote_num = GPIOTE_IDX(id), \
708746
GPIO_NRF_PAD_GROUP_INIT(id) \
709747
IF_ENABLED(GPIOTE_FEATURE_FLAG, \
710748
(.flags = \
@@ -715,8 +753,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
715753
) \
716754
}; \
717755
\
718-
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
719-
\
720756
PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook); \
721757
\
722758
DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init, \

0 commit comments

Comments
 (0)