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
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/conf.h>
32 #include <sys/bus.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/mutex.h>
36 #include <sys/rman.h>
37 #include <sys/gpio.h>
38
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 #include <machine/stdarg.h>
42
43 #include <dev/gpio/gpiobusvar.h>
44 #include <dev/gpio/qoriq_gpio.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
47
48 #include "gpio_if.h"
49
50 static device_t
qoriq_gpio_get_bus(device_t dev)51 qoriq_gpio_get_bus(device_t dev)
52 {
53 struct qoriq_gpio_softc *sc;
54
55 sc = device_get_softc(dev);
56
57 return (sc->busdev);
58 }
59
60 static int
qoriq_gpio_pin_max(device_t dev,int * maxpin)61 qoriq_gpio_pin_max(device_t dev, int *maxpin)
62 {
63
64 *maxpin = MAXPIN;
65 return (0);
66 }
67
68 /* Get a specific pin's capabilities. */
69 static int
qoriq_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)70 qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
71 {
72 struct qoriq_gpio_softc *sc;
73
74 sc = device_get_softc(dev);
75
76 if (!VALID_PIN(pin))
77 return (EINVAL);
78
79 GPIO_LOCK(sc);
80 *caps = sc->sc_pins[pin].gp_caps;
81 GPIO_UNLOCK(sc);
82
83 return (0);
84 }
85
86 /* Get a specific pin's name. */
87 static int
qoriq_gpio_pin_getname(device_t dev,uint32_t pin,char * name)88 qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
89 {
90
91 if (!VALID_PIN(pin))
92 return (EINVAL);
93
94 snprintf(name, GPIOMAXNAME, "qoriq_gpio%d.%d",
95 device_get_unit(dev), pin);
96 name[GPIOMAXNAME-1] = '\0';
97
98 return (0);
99 }
100
101 static int
qoriq_gpio_pin_configure(device_t dev,uint32_t pin,uint32_t flags)102 qoriq_gpio_pin_configure(device_t dev, uint32_t pin, uint32_t flags)
103 {
104 struct qoriq_gpio_softc *sc;
105 uint32_t reg;
106
107 sc = device_get_softc(dev);
108
109 if ((flags & sc->sc_pins[pin].gp_caps) != flags) {
110 return (EINVAL);
111 }
112
113 if (flags & GPIO_PIN_INPUT) {
114 reg = bus_read_4(sc->sc_mem, GPIO_GPDIR);
115 reg &= ~(1 << (31 - pin));
116 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
117 }
118 else if (flags & GPIO_PIN_OUTPUT) {
119 reg = bus_read_4(sc->sc_mem, GPIO_GPDIR);
120 reg |= (1 << (31 - pin));
121 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
122 reg = bus_read_4(sc->sc_mem, GPIO_GPODR);
123 if (flags & GPIO_PIN_OPENDRAIN)
124 reg |= (1 << (31 - pin));
125 else
126 reg &= ~(1 << (31 - pin));
127 bus_write_4(sc->sc_mem, GPIO_GPODR, reg);
128 }
129 sc->sc_pins[pin].gp_flags = flags;
130
131 return (0);
132 }
133
134 /* Set flags for the pin. */
135 static int
qoriq_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)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 ret;
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 ret = qoriq_gpio_pin_configure(dev, pin, flags);
150 GPIO_UNLOCK(sc);
151 return (ret);
152 }
153
154 static int
qoriq_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * pflags)155 qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags)
156 {
157 struct qoriq_gpio_softc *sc;
158
159 if (!VALID_PIN(pin))
160 return (EINVAL);
161
162 sc = device_get_softc(dev);
163
164 GPIO_LOCK(sc);
165 *pflags = sc->sc_pins[pin].gp_flags;
166 GPIO_UNLOCK(sc);
167
168 return (0);
169 }
170
171 /* Set a specific output pin's value. */
172 static int
qoriq_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)173 qoriq_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
174 {
175 struct qoriq_gpio_softc *sc = device_get_softc(dev);
176 uint32_t outvals;
177 uint8_t pinbit;
178
179 if (!VALID_PIN(pin) || value > 1)
180 return (EINVAL);
181
182 GPIO_LOCK(sc);
183 pinbit = 31 - pin;
184
185 outvals = bus_read_4(sc->sc_mem, GPIO_GPDAT);
186 outvals &= ~(1 << pinbit);
187 outvals |= (value << pinbit);
188 bus_write_4(sc->sc_mem, GPIO_GPDAT, outvals);
189
190 GPIO_UNLOCK(sc);
191
192 return (0);
193 }
194
195 /* Get a specific pin's input value. */
196 static int
qoriq_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * value)197 qoriq_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
198 {
199 struct qoriq_gpio_softc *sc = device_get_softc(dev);
200
201 if (!VALID_PIN(pin))
202 return (EINVAL);
203
204 *value = (bus_read_4(sc->sc_mem, GPIO_GPDAT) >> (31 - pin)) & 1;
205
206 return (0);
207 }
208
209 /* Toggle a pin's output value. */
210 static int
qoriq_gpio_pin_toggle(device_t dev,uint32_t pin)211 qoriq_gpio_pin_toggle(device_t dev, uint32_t pin)
212 {
213 struct qoriq_gpio_softc *sc = device_get_softc(dev);
214 uint32_t val;
215
216 if (!VALID_PIN(pin))
217 return (EINVAL);
218
219 GPIO_LOCK(sc);
220
221 val = bus_read_4(sc->sc_mem, GPIO_GPDAT);
222 val ^= (1 << (31 - pin));
223 bus_write_4(sc->sc_mem, GPIO_GPDAT, val);
224
225 GPIO_UNLOCK(sc);
226
227 return (0);
228 }
229
230 static struct ofw_compat_data gpio_matches[] = {
231 {"fsl,pq3-gpio", 1},
232 {"fsl,mpc8572-gpio", 1},
233 {"fsl,qoriq-gpio", 1},
234 {0, 0}
235 };
236
237 static int
qoriq_gpio_probe(device_t dev)238 qoriq_gpio_probe(device_t dev)
239 {
240
241 if (ofw_bus_search_compatible(dev, gpio_matches)->ocd_data == 0)
242 return (ENXIO);
243
244 device_set_desc(dev, "Freescale QorIQ GPIO driver");
245
246 return (0);
247 }
248
249 static int
qoriq_gpio_pin_access_32(device_t dev,uint32_t first_pin,uint32_t clear_pins,uint32_t change_pins,uint32_t * orig_pins)250 qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
251 uint32_t change_pins, uint32_t *orig_pins)
252 {
253 struct qoriq_gpio_softc *sc;
254 uint32_t hwstate;
255
256 sc = device_get_softc(dev);
257
258 if (first_pin != 0)
259 return (EINVAL);
260
261 GPIO_LOCK(sc);
262 hwstate = bus_read_4(sc->sc_mem, GPIO_GPDAT);
263 bus_write_4(sc->sc_mem, GPIO_GPDAT,
264 (hwstate & ~clear_pins) ^ change_pins);
265 GPIO_UNLOCK(sc);
266
267 if (orig_pins != NULL)
268 *orig_pins = hwstate;
269
270 return (0);
271 }
272
273 static int
qoriq_gpio_pin_config_32(device_t dev,uint32_t first_pin,uint32_t num_pins,uint32_t * pin_flags)274 qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
275 uint32_t *pin_flags)
276 {
277 uint32_t dir, odr, mask, reg;
278 struct qoriq_gpio_softc *sc;
279 uint32_t newflags[32];
280 int i;
281
282 if (first_pin != 0 || !VALID_PIN(num_pins))
283 return (EINVAL);
284
285 sc = device_get_softc(dev);
286
287 dir = odr = mask = 0;
288
289 for (i = 0; i < num_pins; i++) {
290 newflags[i] = 0;
291 mask |= (1 << i);
292
293 if (pin_flags[i] & GPIO_PIN_INPUT) {
294 newflags[i] = GPIO_PIN_INPUT;
295 dir &= ~(1 << i);
296 } else {
297 newflags[i] = GPIO_PIN_OUTPUT;
298 dir |= (1 << i);
299
300 if (pin_flags[i] & GPIO_PIN_OPENDRAIN) {
301 newflags[i] |= GPIO_PIN_OPENDRAIN;
302 odr |= (1 << i);
303 } else {
304 newflags[i] |= GPIO_PIN_PUSHPULL;
305 odr &= ~(1 << i);
306 }
307 }
308 }
309
310 GPIO_LOCK(sc);
311
312 reg = (bus_read_4(sc->sc_mem, GPIO_GPDIR) & ~mask) | dir;
313 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg);
314
315 reg = (bus_read_4(sc->sc_mem, GPIO_GPODR) & ~mask) | odr;
316 bus_write_4(sc->sc_mem, GPIO_GPODR, reg);
317
318 for (i = 0; i < num_pins; i++)
319 sc->sc_pins[i].gp_flags = newflags[i];
320
321 GPIO_UNLOCK(sc);
322
323 return (0);
324 }
325
326 static int
qoriq_gpio_map_gpios(device_t bus,phandle_t dev,phandle_t gparent,int gcells,pcell_t * gpios,uint32_t * pin,uint32_t * flags)327 qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
328 pcell_t *gpios, uint32_t *pin, uint32_t *flags)
329 {
330 struct qoriq_gpio_softc *sc;
331 int err;
332
333 if (!VALID_PIN(gpios[0]))
334 return (EINVAL);
335
336 sc = device_get_softc(bus);
337 GPIO_LOCK(sc);
338 err = qoriq_gpio_pin_configure(bus, gpios[0], gpios[1]);
339 GPIO_UNLOCK(sc);
340
341 if (err == 0) {
342 *pin = gpios[0];
343 *flags = gpios[1];
344 }
345
346 return (err);
347 }
348
349 int
qoriq_gpio_attach(device_t dev)350 qoriq_gpio_attach(device_t dev)
351 {
352 struct qoriq_gpio_softc *sc = device_get_softc(dev);
353 int i, rid;
354
355 sc->dev = dev;
356
357 GPIO_LOCK_INIT(sc);
358
359 /* Allocate memory. */
360 rid = 0;
361 sc->sc_mem = bus_alloc_resource_any(dev,
362 SYS_RES_MEMORY, &rid, RF_ACTIVE);
363 if (sc->sc_mem == NULL) {
364 device_printf(dev, "Can't allocate memory for device output port");
365 qoriq_gpio_detach(dev);
366 return (ENOMEM);
367 }
368
369 for (i = 0; i <= MAXPIN; i++)
370 sc->sc_pins[i].gp_caps = DEFAULT_CAPS;
371
372 sc->busdev = gpiobus_attach_bus(dev);
373 if (sc->busdev == NULL) {
374 qoriq_gpio_detach(dev);
375 return (ENOMEM);
376 }
377 /*
378 * Enable the GPIO Input Buffer for all GPIOs.
379 * This is safe on devices without a GPIBE register, because those
380 * devices ignore writes and read 0's in undefined portions of the map.
381 */
382 if (ofw_bus_is_compatible(dev, "fsl,qoriq-gpio"))
383 bus_write_4(sc->sc_mem, GPIO_GPIBE, 0xffffffff);
384
385 OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
386
387 return (0);
388 }
389
390 int
qoriq_gpio_detach(device_t dev)391 qoriq_gpio_detach(device_t dev)
392 {
393 struct qoriq_gpio_softc *sc = device_get_softc(dev);
394
395 gpiobus_detach_bus(dev);
396
397 if (sc->sc_mem != NULL) {
398 /* Release output port resource. */
399 bus_release_resource(dev, SYS_RES_MEMORY,
400 rman_get_rid(sc->sc_mem), sc->sc_mem);
401 }
402
403 GPIO_LOCK_DESTROY(sc);
404
405 return (0);
406 }
407
408 static device_method_t qoriq_gpio_methods[] = {
409 /* device_if */
410 DEVMETHOD(device_probe, qoriq_gpio_probe),
411 DEVMETHOD(device_attach, qoriq_gpio_attach),
412 DEVMETHOD(device_detach, qoriq_gpio_detach),
413
414 /* GPIO protocol */
415 DEVMETHOD(gpio_get_bus, qoriq_gpio_get_bus),
416 DEVMETHOD(gpio_pin_max, qoriq_gpio_pin_max),
417 DEVMETHOD(gpio_pin_getname, qoriq_gpio_pin_getname),
418 DEVMETHOD(gpio_pin_getcaps, qoriq_gpio_pin_getcaps),
419 DEVMETHOD(gpio_pin_get, qoriq_gpio_pin_get),
420 DEVMETHOD(gpio_pin_set, qoriq_gpio_pin_set),
421 DEVMETHOD(gpio_pin_getflags, qoriq_gpio_pin_getflags),
422 DEVMETHOD(gpio_pin_setflags, qoriq_gpio_pin_setflags),
423 DEVMETHOD(gpio_pin_toggle, qoriq_gpio_pin_toggle),
424
425 DEVMETHOD(gpio_map_gpios, qoriq_gpio_map_gpios),
426 DEVMETHOD(gpio_pin_access_32, qoriq_gpio_pin_access_32),
427 DEVMETHOD(gpio_pin_config_32, qoriq_gpio_pin_config_32),
428
429 DEVMETHOD_END
430 };
431
432 DEFINE_CLASS_0(gpio, qoriq_gpio_driver, qoriq_gpio_methods,
433 sizeof(struct qoriq_gpio_softc));
434
435 EARLY_DRIVER_MODULE(qoriq_gpio, simplebus, qoriq_gpio_driver, NULL, NULL,
436 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
437