1 /*
2  * Copyright (c) 2023 Frontgrade Gaisler AB
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * Driver for GRLIB GRGPIO revision 2.
9  * - iflag determine pending interrupt.
10  * - interrupt map decides interrupt number if implemented.
11  * - logic or/and/xor registers used when possible
12  */
13 
14 #define DT_DRV_COMPAT gaisler_grgpio
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/drivers/gpio.h>
18 #include <zephyr/drivers/gpio/gpio_utils.h>
19 #include "gpio_grgpio.h"
20 
21 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(gpio_grgpio2);
24 
25 struct cfg {
26 	struct gpio_driver_config common;
27 	volatile struct grgpio_regs *regs;
28 	int interrupt;
29 };
30 
31 struct data {
32 	struct gpio_driver_data common;
33 	struct k_spinlock lock;
34 	sys_slist_t cb;
35 	uint32_t imask;
36 	uint32_t connected;
37 	int irqgen;
38 };
39 
40 static void grgpio_isr(const struct device *dev);
41 
pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)42 static int pin_configure(const struct device *dev,
43 				gpio_pin_t pin, gpio_flags_t flags)
44 {
45 	const struct cfg *cfg = dev->config;
46 	struct data *data = dev->data;
47 	volatile struct grgpio_regs *regs = cfg->regs;
48 	uint32_t mask = 1 << pin;
49 
50 	if (flags & GPIO_SINGLE_ENDED) {
51 		return -ENOTSUP;
52 	}
53 
54 	if (flags == GPIO_DISCONNECTED) {
55 		return -ENOTSUP;
56 	}
57 
58 	if ((flags & GPIO_DIR_MASK) == (GPIO_INPUT | GPIO_OUTPUT)) {
59 		return -ENOTSUP;
60 	}
61 
62 	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
63 		return -ENOTSUP;
64 	}
65 
66 	if (flags & GPIO_OUTPUT) {
67 		k_spinlock_key_t key;
68 
69 		/*
70 		 * Register operations are atomic, but do the sequence under
71 		 * lock so it serializes.
72 		 */
73 		key = k_spin_lock(&data->lock);
74 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
75 			regs->output_or = mask;
76 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
77 			regs->output_and = ~mask;
78 		}
79 		regs->dir_or = mask;
80 		k_spin_unlock(&data->lock, key);
81 	} else {
82 		regs->dir_and = ~mask;
83 	}
84 
85 	return 0;
86 }
87 
port_get_raw(const struct device * dev,gpio_port_value_t * value)88 static int port_get_raw(const struct device *dev, gpio_port_value_t *value)
89 {
90 	const struct cfg *cfg = dev->config;
91 
92 	*value = cfg->regs->data;
93 	return 0;
94 }
95 
port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)96 static int port_set_masked_raw(const struct device *dev,
97 					  gpio_port_pins_t mask,
98 					  gpio_port_value_t value)
99 {
100 	const struct cfg *cfg = dev->config;
101 	struct data *data = dev->data;
102 	volatile struct grgpio_regs *regs = cfg->regs;
103 	uint32_t port_val;
104 	k_spinlock_key_t key;
105 
106 	value &= mask;
107 	key = k_spin_lock(&data->lock);
108 	port_val = (regs->output & ~mask) | value;
109 	regs->output = port_val;
110 	k_spin_unlock(&data->lock, key);
111 
112 	return 0;
113 }
114 
port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)115 static int port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
116 {
117 	const struct cfg *cfg = dev->config;
118 	volatile struct grgpio_regs *regs = cfg->regs;
119 
120 	regs->output_or = pins;
121 	return 0;
122 }
123 
port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)124 static int port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
125 {
126 	const struct cfg *cfg = dev->config;
127 	volatile struct grgpio_regs *regs = cfg->regs;
128 
129 	regs->output_and = ~pins;
130 	return 0;
131 }
132 
port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)133 static int port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
134 {
135 	const struct cfg *cfg = dev->config;
136 	volatile struct grgpio_regs *regs = cfg->regs;
137 
138 	regs->output_xor = pins;
139 	return 0;
140 }
141 
get_pending_int(const struct device * dev)142 static uint32_t get_pending_int(const struct device *dev)
143 {
144 	const struct cfg *cfg = dev->config;
145 	volatile struct grgpio_regs *regs = cfg->regs;
146 
147 	return regs->iflag;
148 }
149 
pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)150 static int pin_interrupt_configure(const struct device *dev,
151 					      gpio_pin_t pin,
152 					      enum gpio_int_mode mode,
153 					      enum gpio_int_trig trig)
154 {
155 	const struct cfg *cfg = dev->config;
156 	struct data *data = dev->data;
157 	volatile struct grgpio_regs *regs = cfg->regs;
158 	int ret = 0;
159 	const uint32_t mask = 1 << pin;
160 	uint32_t polmask;
161 	k_spinlock_key_t key;
162 
163 	if ((mask & data->imask) == 0) {
164 		/* This pin can not generate interrupt */
165 		return -ENOTSUP;
166 	}
167 	if (mode != GPIO_INT_MODE_DISABLED) {
168 		if (trig == GPIO_INT_TRIG_LOW) {
169 			polmask = 0;
170 		} else if (trig == GPIO_INT_TRIG_HIGH) {
171 			polmask = mask;
172 		} else {
173 			return -ENOTSUP;
174 		}
175 	}
176 	key = k_spin_lock(&data->lock);
177 	if (mode == GPIO_INT_MODE_DISABLED) {
178 		regs->imask_and = ~mask;
179 	} else if (mode == GPIO_INT_MODE_LEVEL) {
180 		regs->imask_and = ~mask;
181 		regs->iedge &= ~mask;
182 		regs->ipol = (regs->ipol & ~mask) | polmask;
183 		regs->imask_or = mask;
184 	} else if (mode == GPIO_INT_MODE_EDGE) {
185 		regs->imask_and = ~mask;
186 		regs->iedge |= mask;
187 		regs->ipol = (regs->ipol & ~mask) | polmask;
188 		regs->imask_or = mask;
189 	} else {
190 		ret = -ENOTSUP;
191 	}
192 	k_spin_unlock(&data->lock, key);
193 
194 	/* Remove old interrupt history for this pin. */
195 	regs->iflag = mask;
196 
197 	int interrupt = cfg->interrupt;
198 	const int irqgen = data->irqgen;
199 
200 	if (irqgen == 0) {
201 		interrupt += pin;
202 	} else if (irqgen == 1) {
203 		;
204 	} else if (irqgen < 32) {
205 		/* look up interrupt number in GRGPIO interrupt map */
206 		uint32_t val = regs->irqmap[pin/4];
207 
208 		val >>= (3 - pin % 4) * 8;
209 		interrupt += (val & 0x1f);
210 	}
211 
212 	if (interrupt && ((1 << interrupt) & data->connected) == 0) {
213 		irq_connect_dynamic(
214 			interrupt,
215 			0,
216 			(void (*)(const void *)) grgpio_isr,
217 			dev,
218 			0
219 		);
220 		irq_enable(interrupt);
221 		data->connected |= 1 << interrupt;
222 	}
223 
224 	return ret;
225 }
226 
manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)227 static int manage_callback(const struct device *dev,
228 			   struct gpio_callback *callback,
229 			   bool set)
230 {
231 	struct data *data = dev->data;
232 
233 	return gpio_manage_callback(&data->cb, callback, set);
234 }
235 
grgpio_isr(const struct device * dev)236 static void grgpio_isr(const struct device *dev)
237 {
238 	const struct cfg *cfg = dev->config;
239 	struct data *data = dev->data;
240 	volatile struct grgpio_regs *regs = cfg->regs;
241 	uint32_t pins;
242 
243 	/* no locking needed when iflag is implemented */
244 	pins = regs->iflag;
245 	if (pins == 0) {
246 		return;
247 	}
248 	regs->iflag = pins;
249 	gpio_fire_callbacks(&data->cb, dev, pins);
250 }
251 
grgpio_init(const struct device * dev)252 static int grgpio_init(const struct device *dev)
253 {
254 	const struct cfg *cfg = dev->config;
255 	struct data *data = dev->data;
256 	volatile struct grgpio_regs *regs = cfg->regs;
257 
258 	data->irqgen = (regs->cap & GRGPIO_CAP_IRQGEN) >> GRGPIO_CAP_IRQGEN_BIT;
259 	regs->dir = 0;
260 	/* Mask all Interrupts */
261 	regs->imask = 0;
262 	/* Make IRQ Rising edge triggered default */
263 	regs->ipol = 0xffffffff;
264 	regs->iedge = 0xffffffff;
265 	regs->iflag = 0xffffffff;
266 	/* Read what I/O lines have IRQ support */
267 	data->imask = regs->ipol;
268 
269 	return 0;
270 }
271 
272 static DEVICE_API(gpio, driver_api) = {
273 	.pin_configure                  = pin_configure,
274 	.port_get_raw                   = port_get_raw,
275 	.port_set_masked_raw            = port_set_masked_raw,
276 	.port_set_bits_raw              = port_set_bits_raw,
277 	.port_clear_bits_raw            = port_clear_bits_raw,
278 	.port_toggle_bits               = port_toggle_bits,
279 	.pin_interrupt_configure        = pin_interrupt_configure,
280 	.manage_callback                = manage_callback,
281 	.get_pending_int                = get_pending_int,
282 };
283 
284 #define GRGPIO_INIT(n)							\
285 	static const struct cfg cfg_##n = {				\
286 		.common = {						\
287 			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),\
288 		},							\
289 		.regs = (void *) DT_INST_REG_ADDR(n),			\
290 		.interrupt = DT_INST_IRQN(n),				\
291 	};								\
292 	static struct data data_##n;					\
293 									\
294 	DEVICE_DT_INST_DEFINE(n,					\
295 			    grgpio_init,				\
296 			    NULL,					\
297 			    &data_##n,					\
298 			    &cfg_##n,					\
299 			    POST_KERNEL,				\
300 			    CONFIG_GPIO_INIT_PRIORITY,			\
301 			    &driver_api					\
302 			   );
303 
304 DT_INST_FOREACH_STATUS_OKAY(GRGPIO_INIT)
305