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 #include <zephyr/pm/device.h>
15 
16 #include <DA1469xAB.h>
17 #include <da1469x_pdc.h>
18 #include <da1469x_pd.h>
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 #if CONFIG_PM_DEVICE
64 	/*
65 	 * Saved state consist of:
66 	 * 1 word for GPIO output port state
67 	 * GPIOx_NGPIOS words for each pin mode
68 	 */
69 	uint32_t *gpio_saved_state;
70 #endif
71 };
72 
73 struct gpio_smartbond_config {
74 	/* gpio_driver_config needs to be first */
75 	struct gpio_driver_config common;
76 	volatile struct gpio_smartbond_data_regs *data_regs;
77 	volatile uint32_t *mode_regs;
78 	volatile struct gpio_smartbond_latch_regs *latch_regs;
79 	volatile struct gpio_smartbond_wkup_regs *wkup_regs;
80 	/* Value of TRIG_SELECT for PDC_CTRLx_REG entry */
81 	uint8_t wkup_trig_select;
82 #if CONFIG_PM_DEVICE
83 	uint8_t ngpios;
84 #endif
85 };
86 
gpio_smartbond_wkup_init(void)87 static void gpio_smartbond_wkup_init(void)
88 {
89 	static bool wkup_init;
90 
91 	/* Wakeup controller is shared for both GPIO ports and should
92 	 * be initialized only once.
93 	 */
94 	if (!wkup_init) {
95 		WAKEUP->WKUP_CTRL_REG = 0;
96 		WAKEUP->WKUP_CLEAR_P0_REG = 0xffffffff;
97 		WAKEUP->WKUP_CLEAR_P1_REG = 0xffffffff;
98 		WAKEUP->WKUP_SELECT_P0_REG = 0;
99 		WAKEUP->WKUP_SELECT_P1_REG = 0;
100 		WAKEUP->WKUP_SEL_GPIO_P0_REG = 0;
101 		WAKEUP->WKUP_SEL_GPIO_P1_REG = 0;
102 		WAKEUP->WKUP_RESET_IRQ_REG = 0;
103 
104 		CRG_TOP->CLK_TMR_REG |= CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk;
105 
106 		WAKEUP->WKUP_CTRL_REG = WAKEUP_WKUP_CTRL_REG_WKUP_ENABLE_IRQ_Msk;
107 
108 		wkup_init = true;
109 	}
110 }
111 
gpio_smartbond_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)112 static int gpio_smartbond_pin_configure(const struct device *dev,
113 				      gpio_pin_t pin, gpio_flags_t flags)
114 {
115 	const struct gpio_smartbond_config *config = dev->config;
116 
117 	if (flags == GPIO_DISCONNECTED) {
118 		/* Set pin as input with no resistors selected */
119 		config->mode_regs[pin] = GPIO_PUPD_INPUT << GPIO_P0_00_MODE_REG_PUPD_Pos;
120 		return 0;
121 	}
122 
123 	if ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT)) {
124 		/* Simultaneous in/out is not supported */
125 		return -ENOTSUP;
126 	}
127 
128 	if (flags & GPIO_OUTPUT) {
129 		config->mode_regs[pin] = GPIO_PUPD_OUTPUT << GPIO_P0_00_MODE_REG_PUPD_Pos;
130 
131 		if (flags & GPIO_OUTPUT_INIT_LOW) {
132 			config->data_regs->reset = BIT(pin);
133 		} else if (flags & GPIO_OUTPUT_INIT_HIGH) {
134 			config->data_regs->set = BIT(pin);
135 		}
136 
137 		return 0;
138 	}
139 
140 	if (flags & GPIO_PULL_DOWN) {
141 		config->mode_regs[pin] = GPIO_PUPD_INPUT_PD << GPIO_P0_00_MODE_REG_PUPD_Pos;
142 	} else if (flags & GPIO_PULL_UP) {
143 		config->mode_regs[pin] = GPIO_PUPD_INPUT_PU << GPIO_P0_00_MODE_REG_PUPD_Pos;
144 	} else {
145 		config->mode_regs[pin] = GPIO_PUPD_INPUT << GPIO_P0_00_MODE_REG_PUPD_Pos;
146 	}
147 
148 	return 0;
149 }
150 
gpio_smartbond_port_get_raw(const struct device * dev,gpio_port_value_t * value)151 static int gpio_smartbond_port_get_raw(const struct device *dev,
152 				     gpio_port_value_t *value)
153 {
154 	const struct gpio_smartbond_config *config = dev->config;
155 
156 	*value = config->data_regs->data;
157 
158 	return 0;
159 }
160 
gpio_smartbond_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)161 static int gpio_smartbond_port_set_masked_raw(const struct device *dev,
162 					    gpio_port_pins_t mask,
163 					    gpio_port_value_t value)
164 {
165 	const struct gpio_smartbond_config *config = dev->config;
166 
167 	config->data_regs->set = value & mask;
168 	config->data_regs->reset = ~value & mask;
169 
170 	return 0;
171 }
172 
gpio_smartbond_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)173 static int gpio_smartbond_port_set_bits_raw(const struct device *dev,
174 					  gpio_port_pins_t pins)
175 {
176 	const struct gpio_smartbond_config *config = dev->config;
177 
178 	config->data_regs->set = pins;
179 
180 	return 0;
181 }
182 
gpio_smartbond_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)183 static int gpio_smartbond_port_clear_bits_raw(const struct device *dev,
184 					    gpio_port_pins_t pins)
185 {
186 	const struct gpio_smartbond_config *config = dev->config;
187 
188 	config->data_regs->reset = pins;
189 
190 	return 0;
191 }
192 
gpio_smartbond_port_toggle_bits(const struct device * dev,gpio_port_pins_t mask)193 static int gpio_smartbond_port_toggle_bits(const struct device *dev,
194 					 gpio_port_pins_t mask)
195 {
196 	const struct gpio_smartbond_config *config = dev->config;
197 	volatile uint32_t *reg = &config->data_regs->data;
198 
199 	*reg = *reg ^ mask;
200 
201 	return 0;
202 }
203 
gpio_smartbond_arm_next_edge_interrupt(const struct device * dev,uint32_t pin_mask)204 static void gpio_smartbond_arm_next_edge_interrupt(const struct device *dev,
205 						   uint32_t pin_mask)
206 {
207 	const struct gpio_smartbond_config *config = dev->config;
208 	uint32_t pin_value;
209 
210 	do {
211 		pin_value = config->data_regs->data & pin_mask;
212 		if (pin_value) {
213 			config->wkup_regs->pol |= pin_mask;
214 		} else {
215 			config->wkup_regs->pol &= ~pin_mask;
216 		}
217 	} while (pin_value != (config->data_regs->data & pin_mask));
218 }
219 
gpio_smartbond_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)220 static int gpio_smartbond_pin_interrupt_configure(const struct device *dev,
221 						gpio_pin_t pin,
222 						enum gpio_int_mode mode,
223 						enum gpio_int_trig trig)
224 {
225 	const struct gpio_smartbond_config *config = dev->config;
226 	struct gpio_smartbond_data *data = dev->data;
227 	uint32_t pin_mask = BIT(pin);
228 #if CONFIG_PM
229 	int trig_select_id = (config->wkup_trig_select << 5) | pin;
230 	int pdc_ix;
231 #endif
232 
233 	/* Not supported by hardware */
234 	if (mode == GPIO_INT_MODE_LEVEL) {
235 		return -ENOTSUP;
236 	}
237 
238 #if CONFIG_PM
239 	pdc_ix = da1469x_pdc_find(trig_select_id, MCU_PDC_MASTER_M33, MCU_PDC_EN_XTAL);
240 #endif
241 	if (mode == GPIO_INT_MODE_DISABLED) {
242 		config->wkup_regs->sel &= ~pin_mask;
243 		config->wkup_regs->clear = pin_mask;
244 		data->both_edges_pins &= ~pin_mask;
245 #if CONFIG_PM
246 		if (pdc_ix >= 0) {
247 			da1469x_pdc_del(pdc_ix);
248 		}
249 #endif
250 	} else {
251 		if (trig == GPIO_INT_TRIG_BOTH) {
252 			/* Not supported by hardware */
253 			data->both_edges_pins |= pin_mask;
254 			gpio_smartbond_arm_next_edge_interrupt(dev, pin_mask);
255 		} else if (trig == GPIO_INT_TRIG_HIGH) {
256 			config->wkup_regs->pol &= ~pin_mask;
257 		} else {
258 			config->wkup_regs->pol |= pin_mask;
259 		}
260 
261 		config->wkup_regs->sel |= pin_mask;
262 #if CONFIG_PM
263 		if (pdc_ix < 0) {
264 			pdc_ix = da1469x_pdc_add(trig_select_id, MCU_PDC_MASTER_M33,
265 						 MCU_PDC_EN_XTAL);
266 		}
267 		if (pdc_ix < 0) {
268 			return -ENOMEM;
269 		}
270 #endif
271 	}
272 
273 	return 0;
274 }
275 
gpio_smartbond_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)276 static int gpio_smartbond_manage_callback(const struct device *dev,
277 				       struct gpio_callback *callback, bool set)
278 {
279 	struct gpio_smartbond_data *data = dev->data;
280 
281 	return gpio_manage_callback(&data->callbacks, callback, set);
282 }
283 
gpio_smartbond_isr(const struct device * dev)284 static void gpio_smartbond_isr(const struct device *dev)
285 {
286 	const struct gpio_smartbond_config *config = dev->config;
287 	struct gpio_smartbond_data *data = dev->data;
288 	uint32_t stat;
289 	uint32_t two_edge_triggered;
290 
291 	WAKEUP->WKUP_RESET_IRQ_REG = WAKEUP_WKUP_RESET_IRQ_REG_WKUP_IRQ_RST_Msk;
292 
293 	stat = config->wkup_regs->status;
294 
295 	two_edge_triggered = stat & data->both_edges_pins;
296 	while (two_edge_triggered) {
297 		int pos = find_lsb_set(two_edge_triggered) - 1;
298 
299 		two_edge_triggered &= ~BIT(pos);
300 		/* Re-arm for other edge */
301 		gpio_smartbond_arm_next_edge_interrupt(dev, BIT(pos));
302 	}
303 
304 	config->wkup_regs->clear = stat;
305 
306 	gpio_fire_callbacks(&data->callbacks, dev, stat);
307 }
308 
309 #ifdef CONFIG_PM_DEVICE
310 
gpio_latch_inst(mem_addr_t data_reg,mem_addr_t mode_reg,mem_addr_t latch_reg,uint8_t ngpios,uint32_t * data,uint32_t * mode)311 static void gpio_latch_inst(mem_addr_t data_reg, mem_addr_t mode_reg, mem_addr_t latch_reg,
312 			    uint8_t ngpios, uint32_t *data, uint32_t *mode)
313 {
314 	uint8_t idx;
315 
316 	*data = sys_read32(data_reg);
317 	for (idx = 0; idx < ngpios; idx++, mode_reg += 4) {
318 		mode[idx] = sys_read32(mode_reg);
319 	}
320 	sys_write32(BIT_MASK(ngpios), latch_reg);
321 
322 }
323 
gpio_unlatch_inst(mem_addr_t data_reg,mem_addr_t mode_reg,mem_addr_t latch_reg,uint8_t ngpios,uint32_t data,uint32_t * mode)324 static void gpio_unlatch_inst(mem_addr_t data_reg, mem_addr_t mode_reg, mem_addr_t latch_reg,
325 			      uint8_t ngpios, uint32_t data, uint32_t *mode)
326 {
327 	uint8_t idx;
328 
329 	sys_write32(data, data_reg);
330 	for (idx = 0; idx < ngpios; idx++, mode_reg += 4) {
331 		sys_write32(mode[idx], mode_reg);
332 	}
333 	sys_write32(BIT_MASK(ngpios), latch_reg);
334 }
335 
gpio_latch(const struct device * dev)336 static void gpio_latch(const struct device *dev)
337 {
338 	const struct gpio_smartbond_config *config = dev->config;
339 	const struct gpio_smartbond_data *data = dev->data;
340 
341 	gpio_latch_inst((mem_addr_t)&config->data_regs->data,
342 			(mem_addr_t)config->mode_regs,
343 			(mem_addr_t)&config->latch_regs->reset,
344 			config->ngpios, data->gpio_saved_state, data->gpio_saved_state + 1);
345 }
346 
gpio_unlatch(const struct device * dev)347 static void gpio_unlatch(const struct device *dev)
348 {
349 	const struct gpio_smartbond_config *config = dev->config;
350 	const struct gpio_smartbond_data *data = dev->data;
351 
352 	gpio_unlatch_inst((mem_addr_t)&config->data_regs->data,
353 			  (mem_addr_t)config->mode_regs,
354 			  (mem_addr_t)&config->latch_regs->set,
355 			  config->ngpios, data->gpio_saved_state[0], data->gpio_saved_state + 1);
356 }
357 
gpio_smartbond_pm_action(const struct device * dev,enum pm_device_action action)358 static int gpio_smartbond_pm_action(const struct device *dev,
359 				    enum pm_device_action action)
360 {
361 	int ret = 0;
362 
363 	switch (action) {
364 	case PM_DEVICE_ACTION_RESUME:
365 		da1469x_pd_acquire(MCU_PD_DOMAIN_COM);
366 		gpio_unlatch(dev);
367 		break;
368 	case PM_DEVICE_ACTION_SUSPEND:
369 		gpio_latch(dev);
370 		da1469x_pd_release(MCU_PD_DOMAIN_COM);
371 		break;
372 	default:
373 		ret = -ENOTSUP;
374 	}
375 
376 	return ret;
377 }
378 
379 #endif /* CONFIG_PM_DEVICE */
380 
381 /* GPIO driver registration */
382 static DEVICE_API(gpio, gpio_smartbond_drv_api_funcs) = {
383 	.pin_configure = gpio_smartbond_pin_configure,
384 	.port_get_raw = gpio_smartbond_port_get_raw,
385 	.port_set_masked_raw = gpio_smartbond_port_set_masked_raw,
386 	.port_set_bits_raw = gpio_smartbond_port_set_bits_raw,
387 	.port_clear_bits_raw = gpio_smartbond_port_clear_bits_raw,
388 	.port_toggle_bits = gpio_smartbond_port_toggle_bits,
389 	.pin_interrupt_configure = gpio_smartbond_pin_interrupt_configure,
390 	.manage_callback = gpio_smartbond_manage_callback,
391 };
392 
393 #define GPIO_SAVED_STATE(id) gpio_smartbond_saved_state_##id
394 #define GPIO_PM_DEVICE_CFG(fld, val) \
395 	COND_CODE_1(CONFIG_PM_DEVICE, (fld = val,), ())
396 #define GPIO_PM_DEVICE_STATE(id, ngpios) \
397 	COND_CODE_1(CONFIG_PM_DEVICE, (static uint32_t GPIO_SAVED_STATE(id)[1 + ngpios];), ())
398 
399 #define GPIO_SMARTBOND_DEVICE(id)							\
400 	GPIO_PM_DEVICE_STATE(id, DT_INST_PROP(id, ngpios))				\
401 	static const struct gpio_smartbond_config gpio_smartbond_config_##id = {	\
402 		.common = {								\
403 			.port_pin_mask =						\
404 			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),				\
405 		},									\
406 		.data_regs = (volatile struct gpio_smartbond_data_regs *)		\
407 						DT_INST_REG_ADDR_BY_NAME(id, data),	\
408 		.mode_regs = (volatile uint32_t *)DT_INST_REG_ADDR_BY_NAME(id, mode),	\
409 		.latch_regs = (volatile struct gpio_smartbond_latch_regs *)		\
410 						DT_INST_REG_ADDR_BY_NAME(id, latch),	\
411 		.wkup_regs = (volatile struct gpio_smartbond_wkup_regs *)		\
412 						DT_INST_REG_ADDR_BY_NAME(id, wkup),	\
413 		.wkup_trig_select = id,							\
414 		GPIO_PM_DEVICE_CFG(.ngpios, DT_INST_PROP(id, ngpios))			\
415 	};										\
416 											\
417 	static struct gpio_smartbond_data gpio_smartbond_data_##id = {			\
418 		GPIO_PM_DEVICE_CFG(.gpio_saved_state, GPIO_SAVED_STATE(id))		\
419 	};										\
420 											\
421 	static int gpio_smartbond_init_##id(const struct device *dev)			\
422 	{										\
423 		da1469x_pd_acquire(MCU_PD_DOMAIN_COM);					\
424 		gpio_smartbond_wkup_init();						\
425 		IRQ_CONNECT(DT_INST_IRQN(id),						\
426 			    DT_INST_IRQ(id, priority),					\
427 			    gpio_smartbond_isr,						\
428 			    DEVICE_DT_INST_GET(id), 0);					\
429 		irq_enable(DT_INST_IRQN(id));						\
430 		return 0;								\
431 	}										\
432 											\
433 	PM_DEVICE_DEFINE(id, gpio_smartbond_pm_action);					\
434 	DEVICE_DT_INST_DEFINE(id, gpio_smartbond_init_##id,				\
435 			      PM_DEVICE_GET(id),					\
436 			      &gpio_smartbond_data_##id,				\
437 			      &gpio_smartbond_config_##id,				\
438 			      PRE_KERNEL_1,						\
439 			      CONFIG_GPIO_INIT_PRIORITY,				\
440 			      &gpio_smartbond_drv_api_funcs);
441 
442 DT_INST_FOREACH_STATUS_OKAY(GPIO_SMARTBOND_DEVICE)
443