14
14
15
15
#include <zephyr/drivers/gpio/gpio_utils.h>
16
16
17
+ #ifdef CONFIG_SOC_NRF54H20_GPD
18
+ #include <nrf/gpd.h>
19
+ #endif
20
+
17
21
struct gpio_nrfx_data {
18
22
/* gpio_driver_data needs to be first */
19
23
struct gpio_driver_data common ;
@@ -27,6 +31,9 @@ struct gpio_nrfx_cfg {
27
31
uint32_t edge_sense ;
28
32
uint8_t port_num ;
29
33
nrfx_gpiote_t gpiote ;
34
+ #ifdef CONFIG_SOC_NRF54H20_GPD
35
+ uint8_t pad_pd ;
36
+ #endif
30
37
};
31
38
32
39
static inline struct gpio_nrfx_data * get_port_data (const struct device * port )
@@ -55,9 +62,59 @@ static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
55
62
return NRF_GPIO_PIN_NOPULL ;
56
63
}
57
64
65
+ static int gpio_nrfx_gpd_retain_set (const struct device * port , uint32_t mask , gpio_flags_t flags )
66
+ {
67
+ #ifdef CONFIG_SOC_NRF54H20_GPD
68
+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
69
+
70
+ if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
71
+ int ret ;
72
+
73
+ if (flags & GPIO_OUTPUT ) {
74
+ cfg -> port -> RETAINSET = mask ;
75
+ }
76
+
77
+ ret = nrf_gpd_release (NRF_GPD_FAST_ACTIVE1 );
78
+ if (ret < 0 ) {
79
+ return ret ;
80
+ }
81
+ }
82
+ #else
83
+ ARG_UNUSED (port );
84
+ ARG_UNUSED (mask );
85
+ ARG_UNUSED (flags );
86
+ #endif
87
+
88
+ return 0 ;
89
+ }
90
+
91
+ static int gpio_nrfx_gpd_retain_clear (const struct device * port , uint32_t mask )
92
+ {
93
+ #ifdef CONFIG_SOC_NRF54H20_GPD
94
+ const struct gpio_nrfx_cfg * cfg = get_port_cfg (port );
95
+
96
+ if (cfg -> pad_pd == NRF_GPD_FAST_ACTIVE1 ) {
97
+ int ret ;
98
+
99
+ ret = nrf_gpd_request (NRF_GPD_FAST_ACTIVE1 );
100
+ if (ret < 0 ) {
101
+ return ret ;
102
+ }
103
+
104
+ cfg -> port -> RETAINCLR = mask ;
105
+ }
106
+ #else
107
+ ARG_UNUSED (port );
108
+ ARG_UNUSED (mask );
109
+ #endif
110
+
111
+ return 0 ;
112
+ }
113
+
58
114
static int gpio_nrfx_pin_configure (const struct device * port , gpio_pin_t pin ,
59
115
gpio_flags_t flags )
60
116
{
117
+ int ret = 0 ;
61
118
nrfx_err_t err = NRFX_SUCCESS ;
62
119
uint8_t ch ;
63
120
bool free_ch = false;
@@ -95,6 +152,11 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
95
152
return - EINVAL ;
96
153
}
97
154
155
+ ret = gpio_nrfx_gpd_retain_clear (port , BIT (pin ));
156
+ if (ret < 0 ) {
157
+ return ret ;
158
+ }
159
+
98
160
if (flags & GPIO_OUTPUT_INIT_HIGH ) {
99
161
nrf_gpio_port_out_set (cfg -> port , BIT (pin ));
100
162
} else if (flags & GPIO_OUTPUT_INIT_LOW ) {
@@ -110,7 +172,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
110
172
: NRF_GPIO_PIN_INPUT_DISCONNECT ;
111
173
112
174
nrf_gpio_reconfigure (abs_pin , & dir , & input , & pull , & drive , NULL );
113
- return 0 ;
175
+
176
+ goto end ;
114
177
}
115
178
116
179
/* Get the GPIOTE channel associated with this pin, if any. It needs
@@ -137,7 +200,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
137
200
err = nrfx_gpiote_input_configure (& cfg -> gpiote ,
138
201
abs_pin , & input_pin_config );
139
202
if (err != NRFX_SUCCESS ) {
140
- return - EINVAL ;
203
+ ret = - EINVAL ;
204
+ goto end ;
141
205
}
142
206
}
143
207
@@ -162,7 +226,8 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
162
226
}
163
227
164
228
if (err != NRFX_SUCCESS ) {
165
- return - EINVAL ;
229
+ ret = - EINVAL ;
230
+ goto end ;
166
231
}
167
232
}
168
233
@@ -171,7 +236,9 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
171
236
__ASSERT_NO_MSG (err == NRFX_SUCCESS );
172
237
}
173
238
174
- return 0 ;
239
+ end :
240
+ (void )gpio_nrfx_gpd_retain_set (port , BIT (pin ), flags );
241
+ return ret ;
175
242
}
176
243
177
244
static int gpio_nrfx_port_get_raw (const struct device * port ,
@@ -189,34 +256,52 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
189
256
gpio_port_value_t value )
190
257
{
191
258
NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
259
+ int ret ;
192
260
193
261
const uint32_t set_mask = value & mask ;
194
262
const uint32_t clear_mask = (~set_mask ) & mask ;
195
263
264
+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
265
+ if (ret < 0 ) {
266
+ return ret ;
267
+ }
268
+
196
269
nrf_gpio_port_out_set (reg , set_mask );
197
270
nrf_gpio_port_out_clear (reg , clear_mask );
198
271
199
- return 0 ;
272
+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
200
273
}
201
274
202
275
static int gpio_nrfx_port_set_bits_raw (const struct device * port ,
203
276
gpio_port_pins_t mask )
204
277
{
205
278
NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
279
+ int ret ;
280
+
281
+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
282
+ if (ret < 0 ) {
283
+ return ret ;
284
+ }
206
285
207
286
nrf_gpio_port_out_set (reg , mask );
208
287
209
- return 0 ;
288
+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
210
289
}
211
290
212
291
static int gpio_nrfx_port_clear_bits_raw (const struct device * port ,
213
292
gpio_port_pins_t mask )
214
293
{
215
294
NRF_GPIO_Type * reg = get_port_cfg (port )-> port ;
295
+ int ret ;
296
+
297
+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
298
+ if (ret < 0 ) {
299
+ return ret ;
300
+ }
216
301
217
302
nrf_gpio_port_out_clear (reg , mask );
218
303
219
- return 0 ;
304
+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
220
305
}
221
306
222
307
static int gpio_nrfx_port_toggle_bits (const struct device * port ,
@@ -226,11 +311,17 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
226
311
const uint32_t value = nrf_gpio_port_out_read (reg ) ^ mask ;
227
312
const uint32_t set_mask = value & mask ;
228
313
const uint32_t clear_mask = (~value ) & mask ;
314
+ int ret ;
315
+
316
+ ret = gpio_nrfx_gpd_retain_clear (port , mask );
317
+ if (ret < 0 ) {
318
+ return ret ;
319
+ }
229
320
230
321
nrf_gpio_port_out_set (reg , set_mask );
231
322
nrf_gpio_port_out_clear (reg , clear_mask );
232
323
233
- return 0 ;
324
+ return gpio_nrfx_gpd_retain_set ( port , mask , GPIO_OUTPUT ) ;
234
325
}
235
326
236
327
#ifdef CONFIG_GPIO_NRFX_INTERRUPT
@@ -450,6 +541,14 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
450
541
"Please enable GPIOTE instance for used GPIO port!")), \
451
542
())
452
543
544
+ #ifdef CONFIG_SOC_NRF54H20_GPD
545
+ #define PAD_PD (inst ) \
546
+ .pad_pd = DT_INST_PHA_BY_NAME_OR(inst, power_domains, pad, id, \
547
+ NRF_GPD_SLOW_MAIN),
548
+ #else
549
+ #define PAD_PD (inst )
550
+ #endif
551
+
453
552
#define GPIO_NRF_DEVICE (id ) \
454
553
GPIOTE_CHECK(id); \
455
554
static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \
@@ -461,6 +560,7 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
461
560
.port_num = DT_INST_PROP(id, port), \
462
561
.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \
463
562
.gpiote = GPIOTE_INSTANCE(id), \
563
+ PAD_PD(id) \
464
564
}; \
465
565
\
466
566
static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \
0 commit comments