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_GPIO_RA_HAS_VBTICTLR
82 	if (config->vbatt_pins[0] != 0xFF) {
83 		uint32_t clear = 0;
84 
85 		for (int i = 0; config->vbatt_pins[i] != '\0'; i++) {
86 			if (config->vbatt_pins[i] == pin) {
87 				WRITE_BIT(clear, i, 1);
88 			}
89 		}
90 
91 		R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT);
92 
93 		R_SYSTEM->VBTICTLR &= (uint8_t)~clear;
94 
95 		R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT);
96 	}
97 #endif
98 
99 	pincfg.port_num = config->port_num;
100 	pincfg.pin_num = pin;
101 
102 	/* Initial pin settings when PFS is zeroed:
103 	 * - Low output, input mode
104 	 * - Pull-up disabled, CMOS output
105 	 * - Low drive strength
106 	 * - Not used for IRQ or analog
107 	 * - Configured as general I/O
108 	 */
109 	pfs_cfg = 0;
110 
111 	if ((flags & GPIO_OUTPUT) != 0U) {
112 		/* Set output pin initial value */
113 		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
114 			WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PODR_Pos, 1);
115 		}
116 
117 		WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PDR_Pos, 1);
118 	}
119 
120 	if ((flags & GPIO_LINE_OPEN_DRAIN) != 0) {
121 		WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_NCODR_Pos, 1);
122 	}
123 
124 	if ((flags & GPIO_PULL_UP) != 0) {
125 		WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PCR_Pos, 1);
126 	}
127 
128 #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
129 	if ((flags & GPIO_INT_ENABLE) != 0) {
130 		const struct gpio_ra_irq_info *irq_info = query_irq_info(dev, pin);
131 		int err = 0;
132 
133 		if (irq_info == NULL) {
134 			return -EINVAL;
135 		}
136 
137 		if (!device_is_ready(irq_info->port_irq)) {
138 			return -EWOULDBLOCK;
139 		}
140 
141 		struct gpio_ra_callback callback = {
142 			.port = (struct device *)dev,
143 			.port_num = config->port_num,
144 			.pin = pin,
145 			.mode = flags & (GPIO_INT_EDGE | GPIO_INT_DISABLE | GPIO_INT_ENABLE),
146 			.trigger = flags & (GPIO_INT_LOW_0 | GPIO_INT_HIGH_1),
147 			.isr = gpio_ra_callback_adapter,
148 		};
149 
150 		err = gpio_ra_interrupt_set(irq_info->port_irq, &callback);
151 		if (err < 0) {
152 			return err;
153 		}
154 
155 		WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_ISEL_Pos, 1);
156 	}
157 
158 	if ((flags & GPIO_INT_DISABLE) != 0) {
159 		const struct gpio_ra_irq_info *irq_info = query_irq_info(dev, pin);
160 
161 		if (irq_info == NULL) {
162 			return -EINVAL;
163 		}
164 
165 		if (!device_is_ready(irq_info->port_irq)) {
166 			return -EWOULDBLOCK;
167 		}
168 
169 		gpio_ra_interrupt_unset(irq_info->port_irq, config->port_num, pin);
170 		WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_ISEL_Pos, 0);
171 	}
172 #endif
173 
174 	pincfg.cfg =
175 		pfs_cfg | (((flags & RENESAS_GPIO_DS_MSK) >> 8) << R_PFS_PORT_PIN_PmnPFS_DSCR_Pos);
176 
177 	return pinctrl_configure_pins(&pincfg, 1, PINCTRL_REG_NONE);
178 }
179 
gpio_ra_pin_get_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t * flags)180 __maybe_unused static int gpio_ra_pin_get_config(const struct device *dev, gpio_pin_t pin,
181 						 gpio_flags_t *flags)
182 {
183 	const struct gpio_ra_config *config = dev->config;
184 	uint32_t pincfg;
185 
186 	if (pin >= RA_PINCTRL_PIN_NUM) {
187 		return -EINVAL;
188 	}
189 
190 	memset(flags, 0, sizeof(gpio_flags_t));
191 
192 	pincfg = R_PFS->PORT[config->port_num].PIN[pin].PmnPFS;
193 
194 	if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_PDR_Pos)) {
195 		*flags |= GPIO_OUTPUT;
196 	} else {
197 		*flags |= GPIO_INPUT;
198 	}
199 
200 	if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_NCODR_Pos)) {
201 		*flags |= GPIO_LINE_OPEN_DRAIN;
202 	}
203 
204 	if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_PCR_Pos)) {
205 		*flags |= GPIO_PULL_UP;
206 	}
207 
208 	return 0;
209 }
210 
gpio_ra_port_get_raw(const struct device * dev,uint32_t * value)211 static int gpio_ra_port_get_raw(const struct device *dev, uint32_t *value)
212 {
213 	const struct gpio_ra_config *config = dev->config;
214 	R_PORT0_Type *port = config->port;
215 
216 	*value = port->PIDR;
217 
218 	return 0;
219 }
220 
gpio_ra_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)221 static int gpio_ra_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
222 				       gpio_port_value_t value)
223 {
224 	const struct gpio_ra_config *config = dev->config;
225 	R_PORT0_Type *port = config->port;
226 
227 	port->PODR = ((port->PODR & ~mask) | (value & mask));
228 
229 	return 0;
230 }
231 
gpio_ra_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)232 static int gpio_ra_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
233 {
234 	const struct gpio_ra_config *config = dev->config;
235 	R_PORT0_Type *port = config->port;
236 
237 	port->PODR = (port->PODR | pins);
238 
239 	return 0;
240 }
241 
gpio_ra_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)242 static int gpio_ra_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
243 {
244 	const struct gpio_ra_config *config = dev->config;
245 	R_PORT0_Type *port = config->port;
246 
247 	port->PODR = (port->PODR & ~pins);
248 
249 	return 0;
250 }
251 
gpio_ra_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)252 static int gpio_ra_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
253 {
254 	const struct gpio_ra_config *config = dev->config;
255 	R_PORT0_Type *port = config->port;
256 
257 	port->PODR = (port->PODR ^ pins);
258 
259 	return 0;
260 }
261 
262 #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)263 static int gpio_ra_pin_interrupt_configure(const struct device *port, gpio_pin_t pin,
264 					   enum gpio_int_mode mode, enum gpio_int_trig trig)
265 {
266 	gpio_flags_t flags;
267 	int err;
268 
269 	err = gpio_ra_pin_get_config(port, pin, &flags);
270 	if (err) {
271 		return err;
272 	}
273 
274 	return gpio_ra_pin_configure(port, pin, (flags | mode | trig));
275 }
276 
gpio_ra_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)277 static int gpio_ra_manage_callback(const struct device *dev, struct gpio_callback *callback,
278 				   bool set)
279 {
280 	struct gpio_ra_data *data = dev->data;
281 
282 	return gpio_manage_callback(&data->callbacks, callback, set);
283 }
284 #endif
285 
286 static DEVICE_API(gpio, gpio_ra_drv_api_funcs) = {
287 	.pin_configure = gpio_ra_pin_configure,
288 #ifdef CONFIG_GPIO_GET_CONFIG
289 	.pin_get_config = gpio_ra_pin_get_config,
290 #endif
291 	.port_get_raw = gpio_ra_port_get_raw,
292 	.port_set_masked_raw = gpio_ra_port_set_masked_raw,
293 	.port_set_bits_raw = gpio_ra_port_set_bits_raw,
294 	.port_clear_bits_raw = gpio_ra_port_clear_bits_raw,
295 	.port_toggle_bits = gpio_ra_port_toggle_bits,
296 #if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT
297 	.pin_interrupt_configure = gpio_ra_pin_interrupt_configure,
298 	.manage_callback = gpio_ra_manage_callback,
299 #endif
300 };
301 
302 #define GPIO_RA_PINS_NAME(n, p, i) CONCAT(DT_STRING_TOKEN_BY_IDX(n, p, i), _pins)
303 
304 #define GPIO_RA_DECL_PINS(n, p, i)                                                                 \
305 	const uint8_t CONCAT(n, ___pins##i[]) = {                                                  \
306 		DT_FOREACH_PROP_ELEM_SEP(n, GPIO_RA_PINS_NAME(n, p, i), DT_PROP_BY_IDX, (,))};
307 
308 #define GPIO_RA_IRQ_INFO(n, p, i)                                                                  \
309 	{                                                                                          \
310 		.port_irq = DEVICE_DT_GET_OR_NULL(DT_PHANDLE_BY_IDX(n, port_irqs, i)),             \
311 		.pins = CONCAT(n, ___pins##i),                                                     \
312 		.num = ARRAY_SIZE(CONCAT(n, ___pins##i)),                                          \
313 	},
314 
315 #define DECL_PINS_PARAMETER(node)                                                                  \
316 	COND_CODE_1(DT_NODE_HAS_PROP(node, port_irq_names),                                        \
317 	(DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_DECL_PINS)), ())
318 #define IRQ_INFO_PARAMETER(node)                                                                   \
319 	COND_CODE_1(DT_NODE_HAS_PROP(node, port_irq_names),                                        \
320 	(DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_IRQ_INFO)), ())
321 
322 #define GPIO_DEVICE_INIT(node, port_number, suffix, addr)                                          \
323 	DECL_PINS_PARAMETER(node);                                                                 \
324 	struct gpio_ra_irq_info gpio_ra_irq_info_##suffix[] = {IRQ_INFO_PARAMETER(node)};          \
325 	static const struct gpio_ra_config gpio_ra_config_##suffix = {                             \
326 		.common =                                                                          \
327 			{                                                                          \
328 				.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_NGPIOS(16U),              \
329 			},                                                                         \
330 		.port_num = port_number,                                                           \
331 		.port = (R_PORT0_Type *)addr,                                                      \
332 		.vbatt_pins = DT_PROP_OR(DT_NODELABEL(ioport##suffix), vbatts_pins, {0xFF}),       \
333 		.irq_info = gpio_ra_irq_info_##suffix,                                             \
334 		.irq_info_size = DT_PROP_LEN_OR(DT_NODELABEL(ioport##suffix), port_irq_names, 0),  \
335 	};                                                                                         \
336 	static struct gpio_ra_data gpio_ra_data_##suffix;                                          \
337 	DEVICE_DT_DEFINE(node, NULL, NULL, &gpio_ra_data_##suffix, &gpio_ra_config_##suffix,       \
338 			 PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_ra_drv_api_funcs)
339 
340 #define GPIO_DEVICE_INIT_RA(suffix)                                                                \
341 	GPIO_DEVICE_INIT(DT_NODELABEL(ioport##suffix),                                             \
342 			 DT_PROP(DT_NODELABEL(ioport##suffix), port), suffix,                      \
343 			 DT_REG_ADDR(DT_NODELABEL(ioport##suffix)))
344 
345 #define GPIO_DEVICE_INIT_RA_IF_OKAY(suffix)                                                        \
346 	COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ioport##suffix)),                         \
347 		    (GPIO_DEVICE_INIT_RA(suffix)),                                                 \
348 		    ())
349 
350 GPIO_DEVICE_INIT_RA_IF_OKAY(0);
351 GPIO_DEVICE_INIT_RA_IF_OKAY(1);
352 GPIO_DEVICE_INIT_RA_IF_OKAY(2);
353 GPIO_DEVICE_INIT_RA_IF_OKAY(3);
354 GPIO_DEVICE_INIT_RA_IF_OKAY(4);
355 GPIO_DEVICE_INIT_RA_IF_OKAY(5);
356 GPIO_DEVICE_INIT_RA_IF_OKAY(6);
357 GPIO_DEVICE_INIT_RA_IF_OKAY(7);
358 GPIO_DEVICE_INIT_RA_IF_OKAY(8);
359 GPIO_DEVICE_INIT_RA_IF_OKAY(9);
360 GPIO_DEVICE_INIT_RA_IF_OKAY(a);
361 GPIO_DEVICE_INIT_RA_IF_OKAY(b);
362