xref: /freebsd/sys/dev/gpio/qoriq_gpio.c (revision ac099daf6742ead81ea7ea86351a8ef4e783041b)
1 /*-
2  * Copyright (c) 2020 Alstom Group.
3  * Copyright (c) 2020 Semihalf.
4  * Copyright (c) 2015 Justin Hibbits
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/conf.h>
37 #include <sys/bus.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/mutex.h>
41 #include <sys/rman.h>
42 #include <sys/gpio.h>
43 
44 #include <machine/bus.h>
45 #include <machine/resource.h>
46 #include <machine/stdarg.h>
47 
48 #include <dev/gpio/gpiobusvar.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51 
52 #include "gpio_if.h"
53 
54 #define MAXPIN		(31)
55 
56 #define VALID_PIN(u)	((u) >= 0 && (u) <= MAXPIN)
57 #define DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
58 			 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)
59 
60 #define GPIO_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
61 #define	GPIO_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
62 #define GPIO_LOCK_INIT(sc) \
63 	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev),	\
64 	    "gpio", MTX_DEF)
65 #define GPIO_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
66 
67 #define	GPIO_GPDIR	0x0
68 #define	GPIO_GPODR	0x4
69 #define	GPIO_GPDAT	0x8
70 #define	GPIO_GPIER	0xc
71 #define	GPIO_GPIMR	0x10
72 #define	GPIO_GPICR	0x14
73 #define	GPIO_GPIBE	0x18
74 
75 struct qoriq_gpio_softc {
76 	device_t	dev;
77 	device_t	busdev;
78 	struct mtx	sc_mtx;
79 	struct resource *sc_mem;	/* Memory resource */
80 	struct gpio_pin	 sc_pins[MAXPIN + 1];
81 };
82 
83 static device_t
84 qoriq_gpio_get_bus(device_t dev)
85 {
86 	struct qoriq_gpio_softc *sc;
87 
88 	sc = device_get_softc(dev);
89 
90 	return (sc->busdev);
91 }
92 
93 static int
94 qoriq_gpio_pin_max(device_t dev, int *maxpin)
95 {
96 
97 	*maxpin = MAXPIN;
98 	return (0);
99 }
100 
101 /* Get a specific pin's capabilities. */
102 static int
103 qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
104 {
105 	struct qoriq_gpio_softc *sc;
106 
107 	sc = device_get_softc(dev);
108 
109 	if (!VALID_PIN(pin))
110 		return (EINVAL);
111 
112 	GPIO_LOCK(sc);
113 	*caps = sc->sc_pins[pin].gp_caps;
114 	GPIO_UNLOCK(sc);
115 
116 	return (0);
117 }
118 
119 /* Get a specific pin's name. */
120 static int
121 qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
122 {
123 
124 	if (!VALID_PIN(pin))
125 		return (EINVAL);
126 
127 	snprintf(name, GPIOMAXNAME, "qoriq_gpio%d.%d",
128 	    device_get_unit(dev), pin);
129 	name[GPIOMAXNAME-1] = '\0';
130 
131 	return (0);
132 }
133 
134 /* Set flags for the pin. */
135 static int
136 qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
137 {
138 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
139 	uint32_t reg;
140 
141 	if (!VALID_PIN(pin))
142 		return (EINVAL);
143 
144 	if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
145 	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
146 		return (EINVAL);
147 
148 	GPIO_LOCK(sc);
149 	if ((flags & sc->sc_pins[pin].gp_caps) != flags) {
150 		GPIO_UNLOCK(sc);
151 		return (EINVAL);
152 	}
153 
154 	if (flags & GPIO_PIN_INPUT) {
155 		reg = bus_read_4(sc->sc_mem, GPIO_GPDIR);
156 		reg &= ~(1 << (31 - pin));
157 		bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
158 	}
159 	else if (flags & GPIO_PIN_OUTPUT) {
160 		reg = bus_read_4(sc->sc_mem, GPIO_GPDIR);
161 		reg |= (1 << (31 - pin));
162 		bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
163 		reg = bus_read_4(sc->sc_mem, GPIO_GPODR);
164 		if (flags & GPIO_PIN_OPENDRAIN)
165 			reg |= (1 << (31 - pin));
166 		else
167 			reg &= ~(1 << (31 - pin));
168 		bus_write_4(sc->sc_mem, GPIO_GPODR, reg);
169 	}
170 	sc->sc_pins[pin].gp_flags = flags;
171 	GPIO_UNLOCK(sc);
172 	return (0);
173 }
174 
175 static int
176 qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags)
177 {
178 	struct qoriq_gpio_softc *sc;
179 
180 	if (!VALID_PIN(pin))
181 		return (EINVAL);
182 
183 	sc = device_get_softc(dev);
184 
185 	GPIO_LOCK(sc);
186 	*pflags = sc->sc_pins[pin].gp_flags;
187 	GPIO_UNLOCK(sc);
188 
189 	return (0);
190 }
191 
192 /* Set a specific output pin's value. */
193 static int
194 qoriq_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
195 {
196 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
197 	uint32_t outvals;
198 	uint8_t pinbit;
199 
200 	if (!VALID_PIN(pin) || value > 1)
201 		return (EINVAL);
202 
203 	GPIO_LOCK(sc);
204 	pinbit = 31 - pin;
205 
206 	outvals = bus_read_4(sc->sc_mem, GPIO_GPDAT);
207 	outvals &= ~(1 << pinbit);
208 	outvals |= (value << pinbit);
209 	bus_write_4(sc->sc_mem, GPIO_GPDAT, outvals);
210 
211 	GPIO_UNLOCK(sc);
212 
213 	return (0);
214 }
215 
216 /* Get a specific pin's input value. */
217 static int
218 qoriq_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
219 {
220 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
221 
222 	if (!VALID_PIN(pin))
223 		return (EINVAL);
224 
225 	*value = (bus_read_4(sc->sc_mem, GPIO_GPDAT) >> (31 - pin)) & 1;
226 
227 	return (0);
228 }
229 
230 /* Toggle a pin's output value. */
231 static int
232 qoriq_gpio_pin_toggle(device_t dev, uint32_t pin)
233 {
234 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
235 	uint32_t val;
236 
237 	if (!VALID_PIN(pin))
238 		return (EINVAL);
239 
240 	GPIO_LOCK(sc);
241 
242 	val = bus_read_4(sc->sc_mem, GPIO_GPDAT);
243 	val ^= (1 << (31 - pin));
244 	bus_write_4(sc->sc_mem, GPIO_GPDAT, val);
245 
246 	GPIO_UNLOCK(sc);
247 
248 	return (0);
249 }
250 
251 static struct ofw_compat_data gpio_matches[] = {
252     {"fsl,qoriq-gpio", 1},
253     {"fsl,pq3-gpio", 1},
254     {"fsl,mpc8572-gpio", 1},
255     {0, 0}
256 };
257 
258 static int
259 qoriq_gpio_probe(device_t dev)
260 {
261 
262 	if (ofw_bus_search_compatible(dev, gpio_matches)->ocd_data == 0)
263 		return (ENXIO);
264 
265 	device_set_desc(dev, "Freescale QorIQ GPIO driver");
266 
267 	return (0);
268 }
269 
270 static int
271 qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
272     uint32_t change_pins, uint32_t *orig_pins)
273 {
274 	struct qoriq_gpio_softc *sc;
275 	uint32_t hwstate;
276 
277 	sc = device_get_softc(dev);
278 
279 	if (first_pin != 0)
280 		return (EINVAL);
281 
282 	GPIO_LOCK(sc);
283 	hwstate = bus_read_4(sc->sc_mem, GPIO_GPDAT);
284 	bus_write_4(sc->sc_mem, GPIO_GPDAT,
285 	    (hwstate & ~clear_pins) ^ change_pins);
286 	GPIO_UNLOCK(sc);
287 
288 	if (orig_pins != NULL)
289 		*orig_pins = hwstate;
290 
291 	return (0);
292 }
293 
294 static int
295 qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
296     uint32_t *pin_flags)
297 {
298 	uint32_t dir, odr, mask, reg;
299 	struct qoriq_gpio_softc *sc;
300 	uint32_t newflags[32];
301 	int i;
302 
303 	if (first_pin != 0 || !VALID_PIN(num_pins))
304 		return (EINVAL);
305 
306 	sc = device_get_softc(dev);
307 
308 	dir = odr = mask = 0;
309 
310 	for (i = 0; i < num_pins; i++) {
311 		newflags[i] = 0;
312 		mask |= (1 << i);
313 
314 		if (pin_flags[i] & GPIO_PIN_INPUT) {
315 			newflags[i] = GPIO_PIN_INPUT;
316 			dir &= ~(1 << i);
317 		} else {
318 			newflags[i] = GPIO_PIN_OUTPUT;
319 			dir |= (1 << i);
320 
321 			if (pin_flags[i] & GPIO_PIN_OPENDRAIN) {
322 				newflags[i] |= GPIO_PIN_OPENDRAIN;
323 				odr |= (1 << i);
324 			} else {
325 				newflags[i] |= GPIO_PIN_PUSHPULL;
326 				odr &= ~(1 << i);
327 			}
328 		}
329 	}
330 
331 	GPIO_LOCK(sc);
332 
333 	reg = (bus_read_4(sc->sc_mem, GPIO_GPDIR) & ~mask) | dir;
334 	bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
335 
336 	reg = (bus_read_4(sc->sc_mem, GPIO_GPODR) & ~mask) | odr;
337 	bus_write_4(sc->sc_mem, GPIO_GPODR, reg);
338 
339 	for (i = 0; i < num_pins; i++)
340 		sc->sc_pins[i].gp_flags = newflags[i];
341 
342 	GPIO_UNLOCK(sc);
343 
344 	return (0);
345 }
346 
347 static int
348 qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
349     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
350 {
351 	struct qoriq_gpio_softc *sc;
352 	int err;
353 
354 	if (!VALID_PIN(gpios[0]))
355 		return (EINVAL);
356 
357 	sc = device_get_softc(bus);
358 	GPIO_LOCK(sc);
359 	err = qoriq_gpio_pin_setflags(bus, gpios[0], gpios[1]);
360 	GPIO_UNLOCK(sc);
361 
362 	if (err == 0) {
363 		*pin = gpios[0];
364 		*flags = gpios[1];
365 	}
366 
367 	return (err);
368 }
369 
370 static int qoriq_gpio_detach(device_t dev);
371 
372 static int
373 qoriq_gpio_attach(device_t dev)
374 {
375 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
376 	int i, rid;
377 
378 	sc->dev = dev;
379 
380 	GPIO_LOCK_INIT(sc);
381 
382 	/* Allocate memory. */
383 	rid = 0;
384 	sc->sc_mem = bus_alloc_resource_any(dev,
385 		     SYS_RES_MEMORY, &rid, RF_ACTIVE);
386 	if (sc->sc_mem == NULL) {
387 		device_printf(dev, "Can't allocate memory for device output port");
388 		qoriq_gpio_detach(dev);
389 		return (ENOMEM);
390 	}
391 
392 	for (i = 0; i <= MAXPIN; i++)
393 		sc->sc_pins[i].gp_caps = DEFAULT_CAPS;
394 
395 	sc->busdev = gpiobus_attach_bus(dev);
396 	if (sc->busdev == NULL) {
397 		qoriq_gpio_detach(dev);
398 		return (ENOMEM);
399 	}
400 	/*
401 	 * Enable the GPIO Input Buffer for all GPIOs.
402 	 * This is safe on devices without a GPIBE register, because those
403 	 * devices ignore writes and read 0's in undefined portions of the map.
404 	 */
405 	if (ofw_bus_is_compatible(dev, "fsl,qoriq-gpio"))
406 		bus_write_4(sc->sc_mem, GPIO_GPIBE, 0xffffffff);
407 
408 	OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
409 
410 	return (0);
411 }
412 
413 static int
414 qoriq_gpio_detach(device_t dev)
415 {
416 	struct qoriq_gpio_softc *sc = device_get_softc(dev);
417 
418 	gpiobus_detach_bus(dev);
419 
420 	if (sc->sc_mem != NULL) {
421 		/* Release output port resource. */
422 		bus_release_resource(dev, SYS_RES_MEMORY,
423 				     rman_get_rid(sc->sc_mem), sc->sc_mem);
424 	}
425 
426 	GPIO_LOCK_DESTROY(sc);
427 
428 	return (0);
429 }
430 
431 static device_method_t qoriq_gpio_methods[] = {
432 	/* device_if */
433 	DEVMETHOD(device_probe, 	qoriq_gpio_probe),
434 	DEVMETHOD(device_attach, 	qoriq_gpio_attach),
435 	DEVMETHOD(device_detach, 	qoriq_gpio_detach),
436 
437 	/* GPIO protocol */
438 	DEVMETHOD(gpio_get_bus, 	qoriq_gpio_get_bus),
439 	DEVMETHOD(gpio_pin_max, 	qoriq_gpio_pin_max),
440 	DEVMETHOD(gpio_pin_getname, 	qoriq_gpio_pin_getname),
441 	DEVMETHOD(gpio_pin_getcaps, 	qoriq_gpio_pin_getcaps),
442 	DEVMETHOD(gpio_pin_get, 	qoriq_gpio_pin_get),
443 	DEVMETHOD(gpio_pin_set, 	qoriq_gpio_pin_set),
444 	DEVMETHOD(gpio_pin_getflags, 	qoriq_gpio_pin_getflags),
445 	DEVMETHOD(gpio_pin_setflags, 	qoriq_gpio_pin_setflags),
446 	DEVMETHOD(gpio_pin_toggle, 	qoriq_gpio_pin_toggle),
447 
448 	DEVMETHOD(gpio_map_gpios,	qoriq_gpio_map_gpios),
449 	DEVMETHOD(gpio_pin_access_32,	qoriq_gpio_pin_access_32),
450 	DEVMETHOD(gpio_pin_config_32,	qoriq_gpio_pin_config_32),
451 
452 	DEVMETHOD_END
453 };
454 
455 static driver_t qoriq_gpio_driver = {
456 	"gpio",
457 	qoriq_gpio_methods,
458 	sizeof(struct qoriq_gpio_softc),
459 };
460 static devclass_t qoriq_gpio_devclass;
461 
462 EARLY_DRIVER_MODULE(qoriq_gpio, simplebus, qoriq_gpio_driver,
463     qoriq_gpio_devclass, NULL, NULL,
464     BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
465