xref: /freebsd/sys/riscv/sifive/sifive_gpio.c (revision 5e3190f700637fcfc1a52daeaa4a031fdd2557c7)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 Jessica Clarke <jrtc27@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28 
29 /* TODO: Provide interrupt controller interface */
30 
31 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/rman.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/gpio.h>
41 
42 #include <dev/gpio/gpiobusvar.h>
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45 
46 #include <machine/bus.h>
47 
48 /* Registers are 32-bit so can only fit 32 pins */
49 #define	SFGPIO_MAX_PINS		32
50 
51 #define	SFGPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
52 
53 #define	SFGPIO_INPUT_VAL	0x0
54 #define	SFGPIO_INPUT_EN		0x4
55 #define	SFGPIO_OUTPUT_EN	0x8
56 #define	SFGPIO_OUTPUT_VAL	0xc
57 #define	SFGPIO_RISE_IE		0x18
58 #define	SFGPIO_RISE_IP		0x1c
59 #define	SFGPIO_FALL_IE		0x20
60 #define	SFGPIO_FALL_IP		0x24
61 #define	SFGPIO_HIGH_IE		0x28
62 #define	SFGPIO_HIGH_IP		0x2c
63 #define	SFGPIO_LOW_IE		0x30
64 #define	SFGPIO_LOW_IP		0x34
65 
66 struct sfgpio_softc {
67 	device_t	dev;
68 	device_t	busdev;
69 	struct mtx	mtx;
70 	struct resource	*mem_res;
71 	int		mem_rid;
72 	struct resource	*irq_res;
73 	int		irq_rid;
74 	int		npins;
75 	struct gpio_pin	gpio_pins[SFGPIO_MAX_PINS];
76 };
77 
78 #define	SFGPIO_LOCK(_sc)	mtx_lock(&(_sc)->mtx)
79 #define	SFGPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->mtx)
80 
81 #define	SFGPIO_READ(_sc, _off)		\
82     bus_read_4((_sc)->mem_res, (_off))
83 #define	SFGPIO_WRITE(_sc, _off, _val)	\
84     bus_write_4((_sc)->mem_res, (_off), (_val))
85 
86 static struct ofw_compat_data compat_data[] = {
87 	{ "sifive,gpio0",	1 },
88 	{ NULL,			0 },
89 };
90 
91 static int
92 sfgpio_probe(device_t dev)
93 {
94 	if (!ofw_bus_status_okay(dev))
95 		return (ENXIO);
96 
97 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
98 		return (ENXIO);
99 
100 	device_set_desc(dev, "SiFive GPIO Controller");
101 
102 	return (BUS_PROBE_DEFAULT);
103 }
104 
105 static int
106 sfgpio_attach(device_t dev)
107 {
108 	struct sfgpio_softc *sc;
109 	phandle_t node;
110 	int error, i;
111 	pcell_t npins;
112 	uint32_t input_en, output_en;
113 
114 	sc = device_get_softc(dev);
115 	sc->dev = dev;
116 
117 	node = ofw_bus_get_node(dev);
118 
119 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF);
120 
121 	sc->mem_rid = 0;
122 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
123 	    &sc->mem_rid, RF_ACTIVE);
124 	if (sc->mem_res == NULL) {
125 		device_printf(dev, "Cannot allocate memory resource\n");
126 		error = ENXIO;
127 		goto fail;
128 	}
129 
130 	if (OF_getencprop(node, "ngpios", &npins, sizeof(npins)) <= 0) {
131 		/* Optional; defaults to 16 */
132 		npins = 16;
133 	} else if (npins > SFGPIO_MAX_PINS) {
134 		device_printf(dev, "Too many pins: %d\n", npins);
135 		error = ENXIO;
136 		goto fail;
137 	}
138 	sc->npins = npins;
139 
140 	sc->irq_rid = 0;
141 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
142 	    RF_ACTIVE);
143 	if (sc->irq_res == NULL) {
144 		device_printf(dev, "Cannot allocate IRQ resource\n");
145 		error = ENXIO;
146 		goto fail;
147 	}
148 
149 	input_en = SFGPIO_READ(sc, SFGPIO_INPUT_EN);
150 	output_en = SFGPIO_READ(sc, SFGPIO_OUTPUT_EN);
151 	for (i = 0; i < sc->npins; ++i) {
152 		sc->gpio_pins[i].gp_pin = i;
153 		sc->gpio_pins[i].gp_caps = SFGPIO_DEFAULT_CAPS;
154 		sc->gpio_pins[i].gp_flags =
155 		    ((input_en & (1u << i)) ? GPIO_PIN_INPUT : 0) |
156 		    ((output_en & (1u << i)) ? GPIO_PIN_OUTPUT : 0);
157 		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, "GPIO%d", i);
158 		sc->gpio_pins[i].gp_name[GPIOMAXNAME - 1] = '\0';
159 	}
160 
161 	sc->busdev = gpiobus_attach_bus(dev);
162 	if (sc->busdev == NULL) {
163 		device_printf(dev, "Cannot attach gpiobus\n");
164 		error = ENXIO;
165 		goto fail;
166 	}
167 
168 	return (0);
169 
170 fail:
171 	if (sc->busdev != NULL)
172 		gpiobus_detach_bus(dev);
173 	if (sc->irq_res != NULL)
174 		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
175 		    sc->irq_res);
176 	if (sc->mem_res != NULL)
177 		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
178 		    sc->mem_res);
179 	mtx_destroy(&sc->mtx);
180 	return (error);
181 }
182 
183 static device_t
184 sfgpio_get_bus(device_t dev)
185 {
186 	struct sfgpio_softc *sc;
187 
188 	sc = device_get_softc(dev);
189 
190 	return (sc->busdev);
191 }
192 
193 static int
194 sfgpio_pin_max(device_t dev, int *maxpin)
195 {
196 	struct sfgpio_softc *sc;
197 
198 	sc = device_get_softc(dev);
199 
200 	*maxpin = sc->npins - 1;
201 
202 	return (0);
203 }
204 
205 static int
206 sfgpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
207 {
208 	struct sfgpio_softc *sc;
209 	uint32_t reg;
210 
211 	sc = device_get_softc(dev);
212 
213 	if (pin >= sc->npins)
214 		return (EINVAL);
215 
216 	SFGPIO_LOCK(sc);
217 	reg = SFGPIO_READ(sc, SFGPIO_OUTPUT_VAL);
218 	if (val)
219 		reg |= (1u << pin);
220 	else
221 		reg &= ~(1u << pin);
222 	SFGPIO_WRITE(sc, SFGPIO_OUTPUT_VAL, reg);
223 	SFGPIO_UNLOCK(sc);
224 
225 	return (0);
226 }
227 
228 static int
229 sfgpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
230 {
231 	struct sfgpio_softc *sc;
232 	uint32_t reg;
233 
234 	sc = device_get_softc(dev);
235 
236 	if (pin >= sc->npins)
237 		return (EINVAL);
238 
239 	SFGPIO_LOCK(sc);
240 	if (sc->gpio_pins[pin].gp_flags & GPIO_PIN_OUTPUT)
241 		reg = SFGPIO_READ(sc, SFGPIO_OUTPUT_VAL);
242 	else
243 		reg = SFGPIO_READ(sc, SFGPIO_INPUT_VAL);
244 	*val = (reg & (1u << pin)) ? 1 : 0;
245 	SFGPIO_UNLOCK(sc);
246 
247 	return (0);
248 }
249 
250 static int
251 sfgpio_pin_toggle(device_t dev, uint32_t pin)
252 {
253 	struct sfgpio_softc *sc;
254 	uint32_t reg;
255 
256 	sc = device_get_softc(dev);
257 
258 	if (pin >= sc->npins)
259 		return (EINVAL);
260 
261 	SFGPIO_LOCK(sc);
262 	reg = SFGPIO_READ(sc, SFGPIO_OUTPUT_VAL);
263 	reg ^= (1u << pin);
264 	SFGPIO_WRITE(sc, SFGPIO_OUTPUT_VAL, reg);
265 	SFGPIO_UNLOCK(sc);
266 
267 	return (0);
268 }
269 
270 static int
271 sfgpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
272 {
273 	struct sfgpio_softc *sc;
274 
275 	sc = device_get_softc(dev);
276 
277 	if (pin >= sc->npins)
278 		return (EINVAL);
279 
280 	SFGPIO_LOCK(sc);
281 	*caps = sc->gpio_pins[pin].gp_caps;
282 	SFGPIO_UNLOCK(sc);
283 
284 	return (0);
285 }
286 
287 static int
288 sfgpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
289 {
290 	struct sfgpio_softc *sc;
291 
292 	sc = device_get_softc(dev);
293 
294 	if (pin >= sc->npins)
295 		return (EINVAL);
296 
297 	SFGPIO_LOCK(sc);
298 	*flags = sc->gpio_pins[pin].gp_flags;
299 	SFGPIO_UNLOCK(sc);
300 
301 	return (0);
302 }
303 
304 static int
305 sfgpio_pin_getname(device_t dev, uint32_t pin, char *name)
306 {
307 	struct sfgpio_softc *sc;
308 
309 	sc = device_get_softc(dev);
310 
311 	if (pin >= sc->npins)
312 		return (EINVAL);
313 
314 	SFGPIO_LOCK(sc);
315 	memcpy(name, sc->gpio_pins[pin].gp_name, GPIOMAXNAME);
316 	SFGPIO_UNLOCK(sc);
317 
318 	return (0);
319 }
320 
321 static int
322 sfgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
323 {
324 	struct sfgpio_softc *sc;
325 	uint32_t reg;
326 
327 	sc = device_get_softc(dev);
328 
329 	if (pin >= sc->npins)
330 		return (EINVAL);
331 
332 	SFGPIO_LOCK(sc);
333 
334 	reg = SFGPIO_READ(sc, SFGPIO_INPUT_EN);
335 	if (flags & GPIO_PIN_INPUT) {
336 		reg |= (1u << pin);
337 		sc->gpio_pins[pin].gp_flags |= GPIO_PIN_INPUT;
338 	} else {
339 		reg &= ~(1u << pin);
340 		sc->gpio_pins[pin].gp_flags &= ~GPIO_PIN_INPUT;
341 	}
342 	SFGPIO_WRITE(sc, SFGPIO_INPUT_EN, reg);
343 
344 	reg = SFGPIO_READ(sc, SFGPIO_OUTPUT_EN);
345 	if (flags & GPIO_PIN_OUTPUT) {
346 		reg |= (1u << pin);
347 		sc->gpio_pins[pin].gp_flags |= GPIO_PIN_OUTPUT;
348 	} else {
349 		reg &= ~(1u << pin);
350 		sc->gpio_pins[pin].gp_flags &= ~GPIO_PIN_OUTPUT;
351 	}
352 	SFGPIO_WRITE(sc, SFGPIO_OUTPUT_EN, reg);
353 
354 	SFGPIO_UNLOCK(sc);
355 
356 	return (0);
357 }
358 
359 static int
360 sfgpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
361     uint32_t change_pins, uint32_t *orig_pins)
362 {
363 	struct sfgpio_softc *sc;
364 	uint32_t reg;
365 
366 	if (first_pin != 0)
367 		return (EINVAL);
368 
369 	sc = device_get_softc(dev);
370 
371 	SFGPIO_LOCK(sc);
372 
373 	reg = SFGPIO_READ(sc, SFGPIO_OUTPUT_VAL);
374 
375 	if (orig_pins != NULL)
376 		/* Only input_val is implicitly masked by input_en */
377 		*orig_pins = SFGPIO_READ(sc, SFGPIO_INPUT_VAL) |
378 		     (reg & SFGPIO_READ(sc, SFGPIO_OUTPUT_EN));
379 
380 	if ((clear_pins | change_pins) != 0)
381 		SFGPIO_WRITE(sc, SFGPIO_OUTPUT_VAL,
382 		    (reg & ~clear_pins) ^ change_pins);
383 
384 	SFGPIO_UNLOCK(sc);
385 
386 	return (0);
387 }
388 
389 static int
390 sfgpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
391     uint32_t *pin_flags)
392 {
393 	struct sfgpio_softc *sc;
394 	uint32_t ireg, oreg;
395 	int i;
396 
397 	sc = device_get_softc(dev);
398 
399 	if (first_pin != 0 || num_pins > sc->npins)
400 		return (EINVAL);
401 
402 	SFGPIO_LOCK(sc);
403 
404 	ireg = SFGPIO_READ(sc, SFGPIO_INPUT_EN);
405 	oreg = SFGPIO_READ(sc, SFGPIO_OUTPUT_EN);
406 	for (i = 0; i < num_pins; ++i) {
407 		if (pin_flags[i] & GPIO_PIN_INPUT) {
408 			ireg |= (1u << i);
409 			oreg &= ~(1u << i);
410 			sc->gpio_pins[i].gp_flags |= GPIO_PIN_INPUT;
411 			sc->gpio_pins[i].gp_flags &= ~GPIO_PIN_OUTPUT;
412 		} else if (pin_flags[i] & GPIO_PIN_OUTPUT) {
413 			ireg &= ~(1u << i);
414 			oreg |= (1u << i);
415 			sc->gpio_pins[i].gp_flags &= ~GPIO_PIN_INPUT;
416 			sc->gpio_pins[i].gp_flags |= GPIO_PIN_OUTPUT;
417 		}
418 	}
419 	SFGPIO_WRITE(sc, SFGPIO_INPUT_EN, ireg);
420 	SFGPIO_WRITE(sc, SFGPIO_OUTPUT_EN, oreg);
421 
422 	SFGPIO_UNLOCK(sc);
423 
424 	return (0);
425 }
426 
427 static phandle_t
428 sfgpio_get_node(device_t bus, device_t dev)
429 {
430 	return (ofw_bus_get_node(bus));
431 }
432 
433 static device_method_t sfgpio_methods[] = {
434 	/* Device interface */
435 	DEVMETHOD(device_probe,		sfgpio_probe),
436 	DEVMETHOD(device_attach,	sfgpio_attach),
437 
438 	/* GPIO protocol */
439 	DEVMETHOD(gpio_get_bus,		sfgpio_get_bus),
440 	DEVMETHOD(gpio_pin_max,		sfgpio_pin_max),
441 	DEVMETHOD(gpio_pin_set,		sfgpio_pin_set),
442 	DEVMETHOD(gpio_pin_get,		sfgpio_pin_get),
443 	DEVMETHOD(gpio_pin_toggle,	sfgpio_pin_toggle),
444 	DEVMETHOD(gpio_pin_getcaps,	sfgpio_pin_getcaps),
445 	DEVMETHOD(gpio_pin_getflags,	sfgpio_pin_getflags),
446 	DEVMETHOD(gpio_pin_getname,	sfgpio_pin_getname),
447 	DEVMETHOD(gpio_pin_setflags,	sfgpio_pin_setflags),
448 	DEVMETHOD(gpio_pin_access_32,	sfgpio_pin_access_32),
449 	DEVMETHOD(gpio_pin_config_32,	sfgpio_pin_config_32),
450 
451 	/* ofw_bus interface */
452 	DEVMETHOD(ofw_bus_get_node,	sfgpio_get_node),
453 
454 	DEVMETHOD_END
455 };
456 
457 DEFINE_CLASS_0(gpio, sfgpio_driver, sfgpio_methods,
458     sizeof(struct sfgpio_softc));
459 EARLY_DRIVER_MODULE(gpio, simplebus, sfgpio_driver, 0, 0,
460     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
461 MODULE_DEPEND(sfgpio, gpiobus, 1, 1, 1);
462