1 /*
2  * Copyright (c) 2021 Andes Technology Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file GPIO driver for the AndesTech ATCGPIO100 controller
9  */
10 
11 #include <errno.h>
12 #include <stdbool.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/device.h>
15 #include <zephyr/drivers/gpio.h>
16 #include <zephyr/dt-bindings/gpio/andestech-atcgpio100.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/sys/sys_io.h>
19 #include <zephyr/irq.h>
20 
21 #include <zephyr/drivers/gpio/gpio_utils.h>
22 
23 #define DT_DRV_COMPAT andestech_atcgpio100
24 
25 /* Andes ATCGPIO100 register definition */
26 #define REG_IDR  0x00 /* ID and Revision reg.           */
27 #define REG_CFG  0x10 /* Hardware configure reg.        */
28 #define REG_DIN  0x20 /* Data In reg.                   */
29 #define REG_DOUT 0x24 /* Data Out reg.                  */
30 #define REG_DIR  0x28 /* Channel direction reg.         */
31 #define REG_DCLR 0x2C /* Data out clear reg.            */
32 #define REG_DSET 0x30 /* Data out set reg.              */
33 #define REG_PUEN 0x40 /* Pull enable reg.               */
34 #define REG_PTYP 0x44 /* Pull type reg.                 */
35 #define REG_INTE 0x50 /* Interrupt enable reg.          */
36 #define REG_IMD0 0x54 /* Interrupt mode 0 ~ 7 reg.      */
37 #define REG_IMD1 0x58 /* Interrupt mode 8 ~ 15 reg.     */
38 #define REG_IMD2 0x5C /* Interrupt mode 16 ~ 23 reg.    */
39 #define REG_IMD3 0x60 /* Interrupt mode 24 ~ 31 reg.    */
40 #define REG_ISTA 0x64 /* Interrupt status reg.          */
41 #define REG_DEBE 0x70 /* De-bounce enable reg.          */
42 #define REG_DEBC 0x74 /* De-Bounce control reg.         */
43 
44 #define INT_NO_OPERATION        0x0
45 #define INT_HIGH_LEVEL          0x2
46 #define INT_LOW_LEVEL           0x3
47 #define INT_NEGATIVE_EDGE       0x5
48 #define INT_POSITIVE_EDGE       0x6
49 #define INT_DUAL_EDGE           0x7
50 
51 #define PULL_CONFIGURED         BIT(31)
52 #define DEBOUNCE_CONFIGURED     BIT(29)
53 #define DF_DEBOUNCED_SETTING    (0x80000003)
54 
55 #define GPIO_BASE(dev) \
56 	((const struct gpio_atcgpio100_config * const)(dev)->config)->base
57 
58 #define GPIO_CFG(dev)  (GPIO_BASE(dev) + REG_CFG)
59 #define GPIO_DIR(dev)  (GPIO_BASE(dev) + REG_DIR)
60 #define GPIO_DIN(dev)  (GPIO_BASE(dev) + REG_DIN)
61 #define GPIO_DOUT(dev) (GPIO_BASE(dev) + REG_DOUT)
62 #define GPIO_DCLR(dev) (GPIO_BASE(dev) + REG_DCLR)
63 #define GPIO_DSET(dev) (GPIO_BASE(dev) + REG_DSET)
64 #define GPIO_PUEN(dev) (GPIO_BASE(dev) + REG_PUEN)
65 #define GPIO_PTYP(dev) (GPIO_BASE(dev) + REG_PTYP)
66 #define GPIO_INTE(dev) (GPIO_BASE(dev) + REG_INTE)
67 #define GPIO_IMD(dev, idx) (GPIO_BASE(dev) + REG_IMD0 + (idx * 4))
68 #define GPIO_ISTA(dev) (GPIO_BASE(dev) + REG_ISTA)
69 #define GPIO_DEBE(dev) (GPIO_BASE(dev) + REG_DEBE)
70 #define GPIO_DEBC(dev) (GPIO_BASE(dev) + REG_DEBC)
71 
72 #define SET_GPIO_INT_MODE(cur_val, mode, ch_idx)			\
73 		do {							\
74 			cur_val &= ~(BIT_MASK(3) << (ch_idx * 4));	\
75 			cur_val |=  (mode << (ch_idx * 4));		\
76 		} while (false)
77 
78 
79 typedef void (*atcgpio100_cfg_func_t)(void);
80 
81 struct gpio_atcgpio100_config {
82 	/* gpio_driver_config needs to be first */
83 	struct gpio_driver_config common;
84 	uint32_t                  base;
85 	uint32_t                  irq_num;
86 	atcgpio100_cfg_func_t     cfg_func;
87 };
88 
89 struct gpio_atcgpio100_data {
90 	/* gpio_driver_data needs to be first */
91 	struct gpio_driver_data common;
92 	/* list of callbacks */
93 	sys_slist_t cb;
94 	struct k_spinlock lock;
95 };
96 
gpio_atcgpio100_config(const struct device * port,gpio_pin_t pin,gpio_flags_t flags)97 static int gpio_atcgpio100_config(const struct device *port,
98 				  gpio_pin_t pin,
99 				  gpio_flags_t flags)
100 {
101 	struct gpio_atcgpio100_data * const data = port->data;
102 	uint32_t port_value, pin_mask, io_flags;
103 	k_spinlock_key_t key;
104 
105 	/* Does not support disconnected pin, and
106 	 * not supporting both input/output at same time.
107 	 */
108 	io_flags = flags & (GPIO_INPUT | GPIO_OUTPUT);
109 	if ((io_flags == GPIO_DISCONNECTED)
110 	    || (io_flags == (GPIO_INPUT | GPIO_OUTPUT))) {
111 		return -ENOTSUP;
112 	}
113 
114 	pin_mask = BIT(pin);
115 
116 	if (flags & GPIO_OUTPUT) {
117 
118 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
119 			sys_write32(pin_mask, GPIO_DSET(port));
120 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
121 			sys_write32(pin_mask, GPIO_DCLR(port));
122 		}
123 
124 		key = k_spin_lock(&data->lock);
125 
126 		/* Set channel output */
127 		port_value = sys_read32(GPIO_DIR(port));
128 		sys_write32((port_value | pin_mask), GPIO_DIR(port));
129 
130 		k_spin_unlock(&data->lock, key);
131 
132 	} else if (flags & GPIO_INPUT) {
133 
134 		if (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) {
135 			return -ENOTSUP;
136 		}
137 
138 		key = k_spin_lock(&data->lock);
139 
140 		/* Set de-bounce */
141 		if (flags & ATCGPIO100_GPIO_DEBOUNCE) {
142 			/* Default settings: Filter out pulses which are
143 			 *  less than 4 de-bounce clock period
144 			 */
145 			sys_write32(DF_DEBOUNCED_SETTING, GPIO_DEBC(port));
146 			port_value = sys_read32(GPIO_DEBE(port));
147 			sys_write32((port_value | pin_mask), GPIO_DEBE(port));
148 		}
149 
150 		/* Set channel input */
151 		port_value = sys_read32(GPIO_DIR(port));
152 		sys_write32((port_value & ~pin_mask), GPIO_DIR(port));
153 
154 		k_spin_unlock(&data->lock, key);
155 
156 	} else {
157 		return -ENOTSUP;
158 	}
159 
160 	return 0;
161 }
162 
gpio_atcgpio100_port_get_raw(const struct device * port,gpio_port_value_t * value)163 static int gpio_atcgpio100_port_get_raw(const struct device *port,
164 					gpio_port_value_t *value)
165 {
166 	*value = sys_read32(GPIO_DIN(port));
167 	return 0;
168 }
169 
gpio_atcgpio100_set_masked_raw(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t value)170 static int gpio_atcgpio100_set_masked_raw(const struct device *port,
171 					  gpio_port_pins_t mask,
172 					  gpio_port_value_t value)
173 {
174 	struct gpio_atcgpio100_data * const data = port->data;
175 	uint32_t port_value;
176 
177 	k_spinlock_key_t key = k_spin_lock(&data->lock);
178 
179 	port_value = sys_read32(GPIO_DOUT(port));
180 	sys_write32((port_value & ~mask) | (value & mask), GPIO_DOUT(port));
181 
182 	k_spin_unlock(&data->lock, key);
183 
184 	return 0;
185 }
186 
gpio_atcgpio100_set_bits_raw(const struct device * port,gpio_port_pins_t pins)187 static int gpio_atcgpio100_set_bits_raw(const struct device *port,
188 					gpio_port_pins_t pins)
189 {
190 	sys_write32(pins, GPIO_DSET(port));
191 	return 0;
192 }
193 
gpio_atcgpio100_clear_bits_raw(const struct device * port,gpio_port_pins_t pins)194 static int gpio_atcgpio100_clear_bits_raw(const struct device *port,
195 					gpio_port_pins_t pins)
196 {
197 	sys_write32(pins, GPIO_DCLR(port));
198 	return 0;
199 }
200 
gpio_atcgpio100_toggle_bits(const struct device * port,gpio_port_pins_t pins)201 static int gpio_atcgpio100_toggle_bits(const struct device *port,
202 					gpio_port_pins_t pins)
203 {
204 	struct gpio_atcgpio100_data * const data = port->data;
205 	uint32_t port_value;
206 
207 	k_spinlock_key_t key = k_spin_lock(&data->lock);
208 
209 	port_value = sys_read32(GPIO_DOUT(port));
210 	sys_write32((port_value ^ pins), GPIO_DOUT(port));
211 
212 	k_spin_unlock(&data->lock, key);
213 
214 	return 0;
215 }
216 
gpio_atcgpio100_pin_interrupt_configure(const struct device * port,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)217 static int gpio_atcgpio100_pin_interrupt_configure(
218 					const struct device *port,
219 					gpio_pin_t pin,
220 					enum gpio_int_mode mode,
221 					enum gpio_int_trig trig)
222 {
223 	struct gpio_atcgpio100_data * const data = port->data;
224 	uint32_t port_value, int_mode, imr_idx, ch_idx;
225 	k_spinlock_key_t key;
226 
227 	switch (mode | trig) {
228 	case GPIO_INT_EDGE_BOTH:
229 		int_mode = INT_DUAL_EDGE;
230 		break;
231 	case GPIO_INT_EDGE_RISING:
232 		int_mode = INT_POSITIVE_EDGE;
233 		break;
234 	case GPIO_INT_EDGE_FALLING:
235 		int_mode = INT_NEGATIVE_EDGE;
236 		break;
237 	case GPIO_INT_LEVEL_LOW:
238 		int_mode = INT_LOW_LEVEL;
239 		break;
240 	case GPIO_INT_LEVEL_HIGH:
241 		int_mode = INT_HIGH_LEVEL;
242 		break;
243 	default:
244 		int_mode = INT_NO_OPERATION;
245 		break;
246 	}
247 
248 	imr_idx = (pin / 8);
249 	ch_idx = (pin % 8);
250 
251 	key = k_spin_lock(&data->lock);
252 
253 	if (int_mode == INT_NO_OPERATION) {
254 		/* Disable interrupt of pin */
255 		port_value = sys_read32(GPIO_INTE(port));
256 		sys_write32((port_value & ~BIT(pin)), GPIO_INTE(port));
257 
258 		/* Clear the remain pending interrupt */
259 		port_value = sys_read32(GPIO_ISTA(port));
260 		sys_write32(port_value, GPIO_ISTA(port));
261 	} else {
262 		/* Set interrupt mode of pin */
263 		port_value = sys_read32(GPIO_IMD(port, imr_idx));
264 		SET_GPIO_INT_MODE(port_value, int_mode, ch_idx);
265 		sys_write32(port_value, GPIO_IMD(port, imr_idx));
266 
267 		/* Enable interrupt of pin */
268 		port_value = sys_read32(GPIO_INTE(port));
269 		sys_write32((port_value | BIT(pin)), GPIO_INTE(port));
270 	}
271 
272 	k_spin_unlock(&data->lock, key);
273 
274 	return 0;
275 }
276 
gpio_atcgpio100_manage_callback(const struct device * port,struct gpio_callback * callback,bool set)277 static int gpio_atcgpio100_manage_callback(const struct device *port,
278 					struct gpio_callback *callback,
279 					bool set)
280 {
281 
282 	struct gpio_atcgpio100_data * const data = port->data;
283 
284 	return gpio_manage_callback(&data->cb, callback, set);
285 }
286 
287 #ifdef CONFIG_GPIO_GET_DIRECTION
gpio_atcgpio100_port_get_dir(const struct device * port,gpio_port_pins_t map,gpio_port_pins_t * inputs,gpio_port_pins_t * outputs)288 static int gpio_atcgpio100_port_get_dir(const struct device *port,
289 					gpio_port_pins_t map,
290 					gpio_port_pins_t *inputs,
291 					gpio_port_pins_t *outputs)
292 {
293 	const struct gpio_atcgpio100_config * const dev_cfg = port->config;
294 	uint32_t direction = sys_read32(GPIO_DIR(port));
295 
296 	map &= dev_cfg->common.port_pin_mask;
297 
298 	if (inputs != NULL) {
299 		*inputs = map & ~direction;
300 	}
301 
302 	if (outputs != NULL) {
303 		*outputs = map & direction;
304 	}
305 
306 	return 0;
307 }
308 #endif /* CONFIG_GPIO_GET_DIRECTION */
309 
gpio_atcgpio100_irq_handler(const struct device * port)310 static void gpio_atcgpio100_irq_handler(const struct device *port)
311 {
312 	struct gpio_atcgpio100_data * const data = port->data;
313 	uint32_t port_value;
314 
315 	port_value = sys_read32(GPIO_ISTA(port));
316 	sys_write32(port_value, GPIO_ISTA(port));
317 
318 	gpio_fire_callbacks(&data->cb, port, port_value);
319 
320 }
321 
322 static const struct gpio_driver_api gpio_atcgpio100_api = {
323 	.pin_configure           = gpio_atcgpio100_config,
324 	.port_get_raw            = gpio_atcgpio100_port_get_raw,
325 	.port_set_masked_raw     = gpio_atcgpio100_set_masked_raw,
326 	.port_set_bits_raw       = gpio_atcgpio100_set_bits_raw,
327 	.port_clear_bits_raw     = gpio_atcgpio100_clear_bits_raw,
328 	.port_toggle_bits        = gpio_atcgpio100_toggle_bits,
329 	.pin_interrupt_configure = gpio_atcgpio100_pin_interrupt_configure,
330 	.manage_callback         = gpio_atcgpio100_manage_callback,
331 #ifdef CONFIG_GPIO_GET_DIRECTION
332 	.port_get_direction      = gpio_atcgpio100_port_get_dir,
333 #endif /* CONFIG_GPIO_GET_DIRECTION */
334 };
335 
gpio_atcgpio100_init(const struct device * port)336 static int gpio_atcgpio100_init(const struct device *port)
337 {
338 	const struct gpio_atcgpio100_config * const dev_cfg = port->config;
339 
340 	/* Disable all interrupts */
341 	sys_write32(BIT_MASK(0), GPIO_INTE(port));
342 
343 	/* Write 1 to clear interrupt status */
344 	sys_write32((uint32_t) BIT64_MASK(32), GPIO_ISTA(port));
345 
346 	/* Configure GPIO device */
347 	dev_cfg->cfg_func();
348 
349 	/* Enable PLIC interrupt GPIO source */
350 	irq_enable(dev_cfg->irq_num);
351 
352 	return 0;
353 }
354 
355 #define GPIO_ATCGPIO100_INIT(n)						\
356 	static void gpio_atcgpio100_cfg_func_##n(void);			\
357 	static struct gpio_atcgpio100_data gpio_atcgpio100_data_##n;	\
358 									\
359 	static const struct gpio_atcgpio100_config			\
360 		gpio_atcgpio100_config_##n = {				\
361 			.common = {					\
362 				.port_pin_mask =			\
363 				GPIO_PORT_PIN_MASK_FROM_DT_INST(n),	\
364 			},						\
365 			.base = DT_INST_REG_ADDR(n),			\
366 			.irq_num = DT_INST_IRQN(n),			\
367 			.cfg_func = gpio_atcgpio100_cfg_func_##n	\
368 		};							\
369 									\
370 	DEVICE_DT_INST_DEFINE(n,			                \
371 		gpio_atcgpio100_init,					\
372 		NULL,							\
373 		&gpio_atcgpio100_data_##n,				\
374 		&gpio_atcgpio100_config_##n,				\
375 		PRE_KERNEL_1,						\
376 		CONFIG_GPIO_INIT_PRIORITY,				\
377 		&gpio_atcgpio100_api);					\
378 									\
379 	static void gpio_atcgpio100_cfg_func_##n(void)			\
380 	{								\
381 		IRQ_CONNECT(DT_INST_IRQN(n),				\
382 			    DT_INST_IRQ(n, priority),			\
383 			    gpio_atcgpio100_irq_handler,		\
384 			    DEVICE_DT_INST_GET(n),	                \
385 			    0);						\
386 		return;							\
387 	}								\
388 
389 
390 DT_INST_FOREACH_STATUS_OKAY(GPIO_ATCGPIO100_INIT)
391