1 /*
2  * Copyright (c) 2022, Renesas Electronics Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT renesas_smartbond_gpio
8 
9 #include <zephyr/drivers/gpio/gpio_utils.h>
10 
11 #include <stdint.h>
12 #include <zephyr/drivers/gpio.h>
13 #include <zephyr/irq.h>
14 
15 #include <DA1469xAB.h>
16 #include <da1469x_pdc.h>
17 
18 #define GPIO_MODE_RESET		0x200
19 
20 #define GPIO_PUPD_INPUT		0
21 #define GPIO_PUPD_INPUT_PU	1
22 #define GPIO_PUPD_INPUT_PD	2
23 #define GPIO_PUPD_OUTPUT	3
24 
25 /* GPIO P0 and P1 share single GPIO and WKUP peripheral instance with separate
26  * set registers for P0 and P1 interleaved. The starting registers for direct
27  * data access, bit access, mode, latch and wake-up controller are defined in
28  * device tree.
29  */
30 
31 struct gpio_smartbond_data_regs {
32 	uint32_t data;
33 	uint32_t _reserved0;
34 	uint32_t set;
35 	uint32_t _reserved1;
36 	uint32_t reset;
37 };
38 
39 struct gpio_smartbond_latch_regs {
40 	uint32_t latch;
41 	uint32_t set;
42 	uint32_t reset;
43 };
44 
45 struct gpio_smartbond_wkup_regs {
46 	uint32_t select;
47 	uint32_t _reserved0[4];
48 	uint32_t pol;
49 	uint32_t _reserved1[4];
50 	uint32_t status;
51 	uint32_t _reserved2[2];
52 	uint32_t clear;
53 	uint32_t _reserved3[2];
54 	uint32_t sel;
55 };
56 
57 struct gpio_smartbond_data {
58 	/* gpio_driver_data needs to be first */
59 	struct gpio_driver_data common;
60 	/* Pins that are configured for both edges (handled by software) */
61 	gpio_port_pins_t both_edges_pins;
62 	sys_slist_t callbacks;
63 };
64 
65 struct gpio_smartbond_config {
66 	/* gpio_driver_config needs to be first */
67 	struct gpio_driver_config common;
68 	volatile struct gpio_smartbond_data_regs *data_regs;
69 	volatile uint32_t *mode_regs;
70 	volatile struct gpio_smartbond_latch_regs *latch_regs;
71 	volatile struct gpio_smartbond_wkup_regs *wkup_regs;
72 	/* Value of TRIG_SELECT for PDC_CTRLx_REG entry */
73 	uint8_t wkup_trig_select;
74 };
75 
gpio_smartbond_wkup_init(void)76 static void gpio_smartbond_wkup_init(void)
77 {
78 	static bool wkup_init;
79 
80 	/* Wakeup controller is shared for both GPIO ports and should
81 	 * be initialized only once.
82 	 */
83 	if (!wkup_init) {
84 		WAKEUP->WKUP_CTRL_REG = 0;
85 		WAKEUP->WKUP_CLEAR_P0_REG = 0xffffffff;
86 		WAKEUP->WKUP_CLEAR_P1_REG = 0xffffffff;
87 		WAKEUP->WKUP_SELECT_P0_REG = 0;
88 		WAKEUP->WKUP_SELECT_P1_REG = 0;
89 		WAKEUP->WKUP_SEL_GPIO_P0_REG = 0;
90 		WAKEUP->WKUP_SEL_GPIO_P1_REG = 0;
91 		WAKEUP->WKUP_RESET_IRQ_REG = 0;
92 
93 		CRG_TOP->CLK_TMR_REG |= CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk;
94 
95 		WAKEUP->WKUP_CTRL_REG = WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Msk;
96 
97 		wkup_init = true;
98 	}
99 }
100 
gpio_smartbond_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)101 static int gpio_smartbond_pin_configure(const struct device *dev,
102 				      gpio_pin_t pin, gpio_flags_t flags)
103 {
104 	const struct gpio_smartbond_config *config = dev->config;
105 
106 	if (flags == GPIO_DISCONNECTED) {
107 		/* Reset to default value */
108 		config->mode_regs[pin] = GPIO_MODE_RESET;
109 		return 0;
110 	}
111 
112 	if ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT)) {
113 		/* Simultaneous in/out is not supported */
114 		return -ENOTSUP;
115 	}
116 
117 	if (flags & GPIO_OUTPUT) {
118 		config->mode_regs[pin] = GPIO_PUPD_OUTPUT << GPIO_P0_00_MODE_REG_PUPD_Pos;
119 
120 		if (flags & GPIO_OUTPUT_INIT_LOW) {
121 			config->data_regs->reset = BIT(pin);
122 		} else if (flags & GPIO_OUTPUT_INIT_HIGH) {
123 			config->data_regs->set = BIT(pin);
124 		}
125 
126 		return 0;
127 	}
128 
129 	if (flags & GPIO_PULL_DOWN) {
130 		config->mode_regs[pin] = GPIO_PUPD_INPUT_PD << GPIO_P0_00_MODE_REG_PUPD_Pos;
131 	} else if (flags & GPIO_PULL_UP) {
132 		config->mode_regs[pin] = GPIO_PUPD_INPUT_PU << GPIO_P0_00_MODE_REG_PUPD_Pos;
133 	} else {
134 		config->mode_regs[pin] = GPIO_PUPD_INPUT << GPIO_P0_00_MODE_REG_PUPD_Pos;
135 	}
136 
137 	return 0;
138 }
139 
gpio_smartbond_port_get_raw(const struct device * dev,gpio_port_value_t * value)140 static int gpio_smartbond_port_get_raw(const struct device *dev,
141 				     gpio_port_value_t *value)
142 {
143 	const struct gpio_smartbond_config *config = dev->config;
144 
145 	*value = config->data_regs->data;
146 
147 	return 0;
148 }
149 
gpio_smartbond_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)150 static int gpio_smartbond_port_set_masked_raw(const struct device *dev,
151 					    gpio_port_pins_t mask,
152 					    gpio_port_value_t value)
153 {
154 	const struct gpio_smartbond_config *config = dev->config;
155 
156 	config->data_regs->data = value & mask;
157 
158 	return 0;
159 }
160 
gpio_smartbond_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)161 static int gpio_smartbond_port_set_bits_raw(const struct device *dev,
162 					  gpio_port_pins_t pins)
163 {
164 	const struct gpio_smartbond_config *config = dev->config;
165 
166 	config->data_regs->set = pins;
167 
168 	return 0;
169 }
170 
gpio_smartbond_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)171 static int gpio_smartbond_port_clear_bits_raw(const struct device *dev,
172 					    gpio_port_pins_t pins)
173 {
174 	const struct gpio_smartbond_config *config = dev->config;
175 
176 	config->data_regs->reset = pins;
177 
178 	return 0;
179 }
180 
gpio_smartbond_port_toggle_bits(const struct device * dev,gpio_port_pins_t mask)181 static int gpio_smartbond_port_toggle_bits(const struct device *dev,
182 					 gpio_port_pins_t mask)
183 {
184 	const struct gpio_smartbond_config *config = dev->config;
185 	volatile uint32_t *reg = &config->data_regs->data;
186 
187 	*reg = *reg ^ mask;
188 
189 	return 0;
190 }
191 
gpio_smartbond_arm_next_edge_interrupt(const struct device * dev,uint32_t pin_mask)192 static void gpio_smartbond_arm_next_edge_interrupt(const struct device *dev,
193 						   uint32_t pin_mask)
194 {
195 	const struct gpio_smartbond_config *config = dev->config;
196 	uint32_t pin_value;
197 
198 	do {
199 		pin_value = config->data_regs->data & pin_mask;
200 		if (pin_value) {
201 			config->wkup_regs->pol |= pin_mask;
202 		} else {
203 			config->wkup_regs->pol &= ~pin_mask;
204 		}
205 	} while (pin_value != (config->data_regs->data & pin_mask));
206 }
207 
gpio_smartbond_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)208 static int gpio_smartbond_pin_interrupt_configure(const struct device *dev,
209 						gpio_pin_t pin,
210 						enum gpio_int_mode mode,
211 						enum gpio_int_trig trig)
212 {
213 	const struct gpio_smartbond_config *config = dev->config;
214 	struct gpio_smartbond_data *data = dev->data;
215 	uint32_t pin_mask = BIT(pin);
216 #if CONFIG_PM
217 	int trig_select_id = (config->wkup_trig_select << 5) | pin;
218 	int pdc_ix;
219 #endif
220 
221 	/* Not supported by hardware */
222 	if (mode == GPIO_INT_MODE_LEVEL) {
223 		return -ENOTSUP;
224 	}
225 
226 #if CONFIG_PM
227 	pdc_ix = da1469x_pdc_find(trig_select_id, MCU_PDC_MASTER_M33, MCU_PDC_EN_XTAL);
228 #endif
229 	if (mode == GPIO_INT_MODE_DISABLED) {
230 		config->wkup_regs->sel &= ~pin_mask;
231 		config->wkup_regs->clear = pin_mask;
232 		data->both_edges_pins &= ~pin_mask;
233 #if CONFIG_PM
234 		da1469x_pdc_del(pdc_ix);
235 #endif
236 	} else {
237 		if (trig == GPIO_INT_TRIG_BOTH) {
238 			/* Not supported by hardware */
239 			data->both_edges_pins |= pin_mask;
240 			gpio_smartbond_arm_next_edge_interrupt(dev, pin_mask);
241 		} else if (trig == GPIO_INT_TRIG_HIGH) {
242 			config->wkup_regs->pol &= ~pin_mask;
243 		} else {
244 			config->wkup_regs->pol |= pin_mask;
245 		}
246 
247 		config->wkup_regs->sel |= pin_mask;
248 #if CONFIG_PM
249 		if (pdc_ix < 0) {
250 			pdc_ix = da1469x_pdc_add(trig_select_id, MCU_PDC_MASTER_M33,
251 						 MCU_PDC_EN_XTAL);
252 		}
253 		if (pdc_ix < 0) {
254 			return -ENOMEM;
255 		}
256 #endif
257 	}
258 
259 	return 0;
260 }
261 
gpio_smartbond_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)262 static int gpio_smartbond_manage_callback(const struct device *dev,
263 				       struct gpio_callback *callback, bool set)
264 {
265 	struct gpio_smartbond_data *data = dev->data;
266 
267 	return gpio_manage_callback(&data->callbacks, callback, set);
268 }
269 
gpio_smartbond_isr(const struct device * dev)270 static void gpio_smartbond_isr(const struct device *dev)
271 {
272 	const struct gpio_smartbond_config *config = dev->config;
273 	struct gpio_smartbond_data *data = dev->data;
274 	uint32_t stat;
275 	uint32_t two_edge_triggered;
276 
277 	WAKEUP->WKUP_RESET_IRQ_REG = WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Msk;
278 
279 	stat = config->wkup_regs->status;
280 
281 	two_edge_triggered = stat & data->both_edges_pins;
282 	while (two_edge_triggered) {
283 		int pos = find_lsb_set(two_edge_triggered) - 1;
284 
285 		two_edge_triggered &= ~BIT(pos);
286 		/* Re-arm for other edge */
287 		gpio_smartbond_arm_next_edge_interrupt(dev, BIT(pos));
288 	}
289 
290 	config->wkup_regs->clear = stat;
291 
292 	gpio_fire_callbacks(&data->callbacks, dev, stat);
293 }
294 
295 /* GPIO driver registration */
296 static const struct gpio_driver_api gpio_smartbond_drv_api_funcs = {
297 	.pin_configure = gpio_smartbond_pin_configure,
298 	.port_get_raw = gpio_smartbond_port_get_raw,
299 	.port_set_masked_raw = gpio_smartbond_port_set_masked_raw,
300 	.port_set_bits_raw = gpio_smartbond_port_set_bits_raw,
301 	.port_clear_bits_raw = gpio_smartbond_port_clear_bits_raw,
302 	.port_toggle_bits = gpio_smartbond_port_toggle_bits,
303 	.pin_interrupt_configure = gpio_smartbond_pin_interrupt_configure,
304 	.manage_callback = gpio_smartbond_manage_callback,
305 };
306 
307 #define GPIO_SMARTBOND_DEVICE(id)							\
308 	static const struct gpio_smartbond_config gpio_smartbond_p##id##_config = {	\
309 		.common = {								\
310 			.port_pin_mask =						\
311 			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),				\
312 		},									\
313 		.data_regs = (volatile struct gpio_smartbond_data_regs *)		\
314 						DT_INST_REG_ADDR_BY_NAME(id, data),	\
315 		.mode_regs = (volatile uint32_t *)DT_INST_REG_ADDR_BY_NAME(id, mode),	\
316 		.latch_regs = (volatile struct gpio_smartbond_latch_regs *)		\
317 						DT_INST_REG_ADDR_BY_NAME(id, latch),	\
318 		.wkup_regs = (volatile struct gpio_smartbond_wkup_regs *)		\
319 						DT_INST_REG_ADDR_BY_NAME(id, wkup),	\
320 		.wkup_trig_select = id,							\
321 	};										\
322 											\
323 	static struct gpio_smartbond_data gpio_smartbond_p##id##_data;			\
324 											\
325 	static int gpio_smartbond_##id##_init(const struct device *dev)			\
326 	{										\
327 		gpio_smartbond_wkup_init();						\
328 		IRQ_CONNECT(DT_INST_IRQN(id),						\
329 			    DT_INST_IRQ(id, priority),					\
330 			    gpio_smartbond_isr,						\
331 			    DEVICE_DT_INST_GET(id), 0);					\
332 		irq_enable(DT_INST_IRQN(id));						\
333 		return 0;								\
334 	}										\
335 											\
336 	DEVICE_DT_INST_DEFINE(id, gpio_smartbond_##id##_init,				\
337 			      NULL,							\
338 			      &gpio_smartbond_p##id##_data,				\
339 			      &gpio_smartbond_p##id##_config,				\
340 			      PRE_KERNEL_1,						\
341 			      CONFIG_GPIO_INIT_PRIORITY,				\
342 			      &gpio_smartbond_drv_api_funcs);
343 
344 DT_INST_FOREACH_STATUS_OKAY(GPIO_SMARTBOND_DEVICE)
345