1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_ra_gpio_ioport
8
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/pinctrl.h>
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>
13 #include <zephyr/drivers/gpio/gpio_utils.h>
14 #include <soc.h>
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
22 struct gpio_ra_config {
23 struct gpio_driver_config common;
24 uint8_t port_num;
25 R_PORT0_Type *port;
26 const struct gpio_ra_irq_info *irq_info;
27 const size_t irq_info_size;
28 gpio_pin_t vbatt_pins[];
29 };
30
31 struct gpio_ra_data {
32 struct gpio_driver_data common;
33 sys_slist_t callbacks;
34 };
35
36 #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
query_irq_info(const struct device * dev,uint32_t pin)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
gpio_ra_callback_adapter(const struct device * dev,gpio_pin_t pin)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
gpio_ra_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)62 static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
63 {
64 const struct gpio_ra_config *config = dev->config;
65
66 struct ra_pinctrl_soc_pin pincfg;
67 uint32_t pfs_cfg;
68
69 if (((flags & GPIO_INPUT) != 0U) && ((flags & GPIO_OUTPUT) != 0U)) {
70 return -ENOTSUP;
71 }
72
73 if ((flags & GPIO_PULL_DOWN) != 0U) {
74 return -ENOTSUP;
75 }
76
77 if (!IS_ENABLED(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT) && ((flags & GPIO_INT_ENABLE) != 0)) {
78 return -ENOTSUP;
79 }
80
81 if (config->vbatt_pins[0] != 0xFF) {
82 uint32_t clear = 0;
83
84 for (int i = 0; config->vbatt_pins[i] != '\0'; i++) {
85 if (config->vbatt_pins[i] == pin) {
86 WRITE_BIT(clear, i, 1);
87 }
88 }
89
90 R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT);
91
92 R_SYSTEM->VBTICTLR &= (uint8_t)~clear;
93
94 R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT);
95 }
96
97 pincfg.port_num = config->port_num;
98 pincfg.pin_num = pin;
99
100 /* Initial pin settings when PFS is zeroed:
101 * - Low output, input mode
102 * - Pull-up disabled, CMOS output
103 * - Low drive strength
104 * - Not used for IRQ or analog
105 * - Configured as general I/O
106 */
107 pfs_cfg = 0;
108
109 if ((flags & GPIO_OUTPUT) != 0U) {
110 /* Set output pin initial value */
111 if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
112 WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PODR_Pos, 1);
113 }
114
115 WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PDR_Pos, 1);
116 }
117
118 if ((flags & GPIO_LINE_OPEN_DRAIN) != 0) {
119 WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_NCODR_Pos, 1);
120 }
121
122 if ((flags & GPIO_PULL_UP) != 0) {
123 WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PCR_Pos, 1);
124 }
125
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);
174
175 return pinctrl_configure_pins(&pincfg, 1, PINCTRL_REG_NONE);
176 }
177
gpio_ra_port_get_raw(const struct device * dev,uint32_t * value)178 static int gpio_ra_port_get_raw(const struct device *dev, uint32_t *value)
179 {
180 const struct gpio_ra_config *config = dev->config;
181 R_PORT0_Type *port = config->port;
182
183 *value = port->PIDR;
184
185 return 0;
186 }
187
gpio_ra_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)188 static int gpio_ra_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
189 gpio_port_value_t value)
190 {
191 const struct gpio_ra_config *config = dev->config;
192 R_PORT0_Type *port = config->port;
193
194 port->PODR = ((port->PODR & ~mask) | (value & mask));
195
196 return 0;
197 }
198
gpio_ra_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)199 static int gpio_ra_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
200 {
201 const struct gpio_ra_config *config = dev->config;
202 R_PORT0_Type *port = config->port;
203
204 port->PODR = (port->PODR | pins);
205
206 return 0;
207 }
208
gpio_ra_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)209 static int gpio_ra_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
210 {
211 const struct gpio_ra_config *config = dev->config;
212 R_PORT0_Type *port = config->port;
213
214 port->PODR = (port->PODR & ~pins);
215
216 return 0;
217 }
218
gpio_ra_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)219 static int gpio_ra_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
220 {
221 const struct gpio_ra_config *config = dev->config;
222 R_PORT0_Type *port = config->port;
223
224 port->PODR = (port->PODR ^ pins);
225
226 return 0;
227 }
228
229 #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
gpio_ra_pin_interrupt_configure(const struct device * port,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)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
gpio_ra_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)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
245 static DEVICE_API(gpio, gpio_ra_drv_api_funcs) = {
246 .pin_configure = gpio_ra_pin_configure,
247 .port_get_raw = gpio_ra_port_get_raw,
248 .port_set_masked_raw = gpio_ra_port_set_masked_raw,
249 .port_set_bits_raw = gpio_ra_port_set_bits_raw,
250 .port_clear_bits_raw = gpio_ra_port_clear_bits_raw,
251 .port_toggle_bits = gpio_ra_port_toggle_bits,
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
256 };
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
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)}; \
275 static const struct gpio_ra_config gpio_ra_config_##suffix = { \
276 .common = \
277 { \
278 .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_NGPIOS(16U), \
279 }, \
280 .port_num = port_number, \
281 .port = (R_PORT0_Type *)addr, \
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), \
285 }; \
286 static struct gpio_ra_data gpio_ra_data_##suffix; \
287 DEVICE_DT_DEFINE(node, NULL, NULL, &gpio_ra_data_##suffix, &gpio_ra_config_##suffix, \
288 PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_ra_drv_api_funcs)
289
290 #define GPIO_DEVICE_INIT_RA(suffix) \
291 GPIO_DEVICE_INIT(DT_NODELABEL(ioport##suffix), \
292 DT_PROP(DT_NODELABEL(ioport##suffix), port), suffix, \
293 DT_REG_ADDR(DT_NODELABEL(ioport##suffix)))
294
295 #define GPIO_DEVICE_INIT_RA_IF_OKAY(suffix) \
296 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ioport##suffix)), \
297 (GPIO_DEVICE_INIT_RA(suffix)), \
298 ())
299
300 GPIO_DEVICE_INIT_RA_IF_OKAY(0);
301 GPIO_DEVICE_INIT_RA_IF_OKAY(1);
302 GPIO_DEVICE_INIT_RA_IF_OKAY(2);
303 GPIO_DEVICE_INIT_RA_IF_OKAY(3);
304 GPIO_DEVICE_INIT_RA_IF_OKAY(4);
305 GPIO_DEVICE_INIT_RA_IF_OKAY(5);
306 GPIO_DEVICE_INIT_RA_IF_OKAY(6);
307 GPIO_DEVICE_INIT_RA_IF_OKAY(7);
308 GPIO_DEVICE_INIT_RA_IF_OKAY(8);
309 GPIO_DEVICE_INIT_RA_IF_OKAY(9);
310 GPIO_DEVICE_INIT_RA_IF_OKAY(a);
311 GPIO_DEVICE_INIT_RA_IF_OKAY(b);
312