9
9
#include <zephyr/drivers/gpio.h>
10
10
#include <zephyr/drivers/pinctrl.h>
11
11
#include <zephyr/dt-bindings/gpio/renesas-ra-gpio-ioport.h>
12
+ #include <zephyr/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.h>
12
13
#include <zephyr/drivers/gpio/gpio_utils.h>
13
- #include <zephyr/irq.h>
14
14
#include <soc.h>
15
15
16
+ struct gpio_ra_irq_info {
17
+ const struct device * port_irq ;
18
+ const uint8_t * const pins ;
19
+ size_t num ;
20
+ };
21
+
16
22
struct gpio_ra_config {
17
23
struct gpio_driver_config common ;
18
24
uint8_t port_num ;
19
25
R_PORT0_Type * port ;
26
+ const struct gpio_ra_irq_info * irq_info ;
27
+ const size_t irq_info_size ;
20
28
gpio_pin_t vbatt_pins [];
21
29
};
22
30
23
31
struct gpio_ra_data {
24
32
struct gpio_driver_data common ;
33
+ sys_slist_t callbacks ;
25
34
};
26
35
36
+ #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
37
+ static const struct gpio_ra_irq_info * query_irq_info (const struct device * dev , uint32_t pin )
38
+ {
39
+ const struct gpio_ra_config * config = dev -> config ;
40
+
41
+ for (int i = 0 ; i < config -> irq_info_size ; i ++ ) {
42
+ const struct gpio_ra_irq_info * info = & config -> irq_info [i ];
43
+
44
+ for (int j = 0 ; j < info -> num ; j ++ ) {
45
+ if (info -> pins [j ] == pin ) {
46
+ return info ;
47
+ }
48
+ }
49
+ }
50
+
51
+ return NULL ;
52
+ }
53
+
54
+ static void gpio_ra_callback_adapter (const struct device * dev , gpio_pin_t pin )
55
+ {
56
+ struct gpio_ra_data * data = dev -> data ;
57
+
58
+ gpio_fire_callbacks (& data -> callbacks , dev , BIT (pin ));
59
+ }
60
+ #endif
61
+
27
62
static int gpio_ra_pin_configure (const struct device * dev , gpio_pin_t pin , gpio_flags_t flags )
28
63
{
29
64
const struct gpio_ra_config * config = dev -> config ;
@@ -39,7 +74,7 @@ static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
39
74
return - ENOTSUP ;
40
75
}
41
76
42
- if (( flags & GPIO_INT_ENABLE ) != 0 ) {
77
+ if (! IS_ENABLED ( CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT ) && (( flags & GPIO_INT_ENABLE ) != 0 ) ) {
43
78
return - ENOTSUP ;
44
79
}
45
80
@@ -88,8 +123,54 @@ static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
88
123
WRITE_BIT (pfs_cfg , R_PFS_PORT_PIN_PmnPFS_PCR_Pos , 1 );
89
124
}
90
125
91
- pincfg .cfg = pfs_cfg |
92
- (((flags & RENESAS_GPIO_DS_MSK ) >> 8 ) << R_PFS_PORT_PIN_PmnPFS_DSCR_Pos );
126
+ #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
127
+ if ((flags & GPIO_INT_ENABLE ) != 0 ) {
128
+ const struct gpio_ra_irq_info * irq_info = query_irq_info (dev , pin );
129
+ int err = 0 ;
130
+
131
+ if (irq_info == NULL ) {
132
+ return - EINVAL ;
133
+ }
134
+
135
+ if (!device_is_ready (irq_info -> port_irq )) {
136
+ return - EWOULDBLOCK ;
137
+ }
138
+
139
+ struct gpio_ra_callback callback = {
140
+ .port = (struct device * )dev ,
141
+ .port_num = config -> port_num ,
142
+ .pin = pin ,
143
+ .mode = flags & (GPIO_INT_EDGE | GPIO_INT_DISABLE | GPIO_INT_ENABLE ),
144
+ .trigger = flags & (GPIO_INT_LOW_0 | GPIO_INT_HIGH_1 ),
145
+ .isr = gpio_ra_callback_adapter ,
146
+ };
147
+
148
+ err = gpio_ra_interrupt_set (irq_info -> port_irq , & callback );
149
+ if (err < 0 ) {
150
+ return err ;
151
+ }
152
+
153
+ WRITE_BIT (pfs_cfg , R_PFS_PORT_PIN_PmnPFS_ISEL_Pos , 1 );
154
+ }
155
+
156
+ if ((flags & GPIO_INT_DISABLE ) != 0 ) {
157
+ const struct gpio_ra_irq_info * irq_info = query_irq_info (dev , pin );
158
+
159
+ if (irq_info == NULL ) {
160
+ return - EINVAL ;
161
+ }
162
+
163
+ if (!device_is_ready (irq_info -> port_irq )) {
164
+ return - EWOULDBLOCK ;
165
+ }
166
+
167
+ gpio_ra_interrupt_unset (irq_info -> port_irq , config -> port_num , pin );
168
+ WRITE_BIT (pfs_cfg , R_PFS_PORT_PIN_PmnPFS_ISEL_Pos , 0 );
169
+ }
170
+ #endif
171
+
172
+ pincfg .cfg =
173
+ pfs_cfg | (((flags & RENESAS_GPIO_DS_MSK ) >> 8 ) << R_PFS_PORT_PIN_PmnPFS_DSCR_Pos );
93
174
94
175
return pinctrl_configure_pins (& pincfg , 1 , PINCTRL_REG_NONE );
95
176
}
@@ -145,18 +226,52 @@ static int gpio_ra_port_toggle_bits(const struct device *dev, gpio_port_pins_t p
145
226
return 0 ;
146
227
}
147
228
229
+ #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
230
+ static int gpio_ra_pin_interrupt_configure (const struct device * port , gpio_pin_t pin ,
231
+ enum gpio_int_mode mode , enum gpio_int_trig trig )
232
+ {
233
+ return gpio_ra_pin_configure (port , pin , (mode | trig ));
234
+ }
235
+
236
+ static int gpio_ra_manage_callback (const struct device * dev , struct gpio_callback * callback ,
237
+ bool set )
238
+ {
239
+ struct gpio_ra_data * data = dev -> data ;
240
+
241
+ return gpio_manage_callback (& data -> callbacks , callback , set );
242
+ }
243
+ #endif
244
+
148
245
static DEVICE_API (gpio , gpio_ra_drv_api_funcs ) = {
149
246
.pin_configure = gpio_ra_pin_configure ,
150
247
.port_get_raw = gpio_ra_port_get_raw ,
151
248
.port_set_masked_raw = gpio_ra_port_set_masked_raw ,
152
249
.port_set_bits_raw = gpio_ra_port_set_bits_raw ,
153
250
.port_clear_bits_raw = gpio_ra_port_clear_bits_raw ,
154
251
.port_toggle_bits = gpio_ra_port_toggle_bits ,
155
- .pin_interrupt_configure = NULL ,
156
- .manage_callback = NULL ,
252
+ #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
253
+ .pin_interrupt_configure = gpio_ra_pin_interrupt_configure ,
254
+ .manage_callback = gpio_ra_manage_callback ,
255
+ #endif
157
256
};
158
257
258
+ #define GPIO_RA_PINS_NAME (n , p , i ) CONCAT(DT_STRING_TOKEN_BY_IDX(n, p, i), _pins)
259
+
260
+ #define GPIO_RA_DECL_PINS (n , p , i ) \
261
+ const uint8_t CONCAT(n, ___pins##i[]) = { \
262
+ DT_FOREACH_PROP_ELEM_SEP(n, GPIO_RA_PINS_NAME(n, p, i), DT_PROP_BY_IDX, (,))};
263
+
264
+ #define GPIO_RA_IRQ_INFO (n , p , i ) \
265
+ { \
266
+ .port_irq = DEVICE_DT_GET_OR_NULL(DT_PHANDLE_BY_IDX(n, port_irqs, i)), \
267
+ .pins = CONCAT(n, ___pins##i), \
268
+ .num = ARRAY_SIZE(CONCAT(n, ___pins##i)), \
269
+ },
270
+
159
271
#define GPIO_DEVICE_INIT (node , port_number , suffix , addr ) \
272
+ DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_DECL_PINS); \
273
+ struct gpio_ra_irq_info gpio_ra_irq_info_##suffix[] = { \
274
+ DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_IRQ_INFO)}; \
160
275
static const struct gpio_ra_config gpio_ra_config_##suffix = { \
161
276
.common = \
162
277
{ \
@@ -165,6 +280,8 @@ static DEVICE_API(gpio, gpio_ra_drv_api_funcs) = {
165
280
.port_num = port_number, \
166
281
.port = (R_PORT0_Type *)addr, \
167
282
.vbatt_pins = DT_PROP_OR(DT_NODELABEL(ioport##suffix), vbatts_pins, {0xFF}), \
283
+ .irq_info = gpio_ra_irq_info_##suffix, \
284
+ .irq_info_size = DT_PROP_LEN_OR(DT_NODELABEL(ioport##suffix), port_irq_names, 0), \
168
285
}; \
169
286
static struct gpio_ra_data gpio_ra_data_##suffix; \
170
287
DEVICE_DT_DEFINE(node, NULL, NULL, &gpio_ra_data_##suffix, &gpio_ra_config_##suffix, \
0 commit comments