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