1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2020 Alstom Group.
5 * Copyright (c) 2020 Semihalf.
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__FBSDID("$FreeBSD$");
31
32#include <sys/param.h>
33
34#include <sys/bus.h>
35#include <sys/endian.h>
36#include <sys/gpio.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40
41#include <dev/gpio/gpiobusvar.h>
42#include <dev/ofw/ofw_bus.h>
43#include <machine/bus.h>
44
45#include "gpio_if.h"
46
47/* constants */
48enum {
49	DIRECTION  = 0x0,
50	OPEN_DRAIN = 0x4,
51	DATA       = 0x8,
52	INT_EV     = 0xC,
53	INT_MASK   = 0x10,
54	INT_CTRL   = 0x14
55};
56
57#define	PIN_COUNT 32
58#define	DEFAULT_CAPS				\
59	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |	\
60	GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)
61#define	GPIO(n) (1 << (31 - (n)))
62
63struct gpio_res {
64	int mem_rid;
65	struct resource *mem_res;
66};
67
68/* software context */
69struct gpio_softc {
70	device_t           dev;
71	device_t           busdev;
72	struct gpio_res    res;
73	struct gpio_pin    setup[PIN_COUNT];
74	struct mtx         mutex;
75};
76
77#define	QORIQ_GPIO_LOCK(_sc)          mtx_lock_spin(&(_sc)->mutex)
78#define	QORIQ_GPIO_UNLOCK(_sc)        mtx_unlock_spin(&(_sc)->mutex)
79#define	QORIQ_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mutex, MA_OWNED)
80
81/* prototypes */
82/* helpers */
83static bool qoriq_make_gpio_res(device_t, struct gpio_res*);
84static uint32_t qoriq_gpio_reg_read(device_t, uint32_t);
85static void qoriq_gpio_reg_write(device_t, uint32_t, uint32_t);
86static void qoriq_gpio_set(device_t, uint32_t, uint32_t, uint32_t);
87static int qoriq_gpio_configure(device_t, uint32_t, uint32_t);
88
89/* GPIO API */
90static int qoriq_gpio_probe(device_t);
91static int qoriq_gpio_attach(device_t);
92static device_t qoriq_gpio_get_bus(device_t);
93static int qoriq_gpio_pin_max(device_t, int*);
94static int qoriq_gpio_pin_getname(device_t, uint32_t, char*);
95static int qoriq_gpio_pin_getflags(device_t, uint32_t, uint32_t*);
96static int qoriq_gpio_pin_setflags(device_t, uint32_t, uint32_t);
97static int qoriq_gpio_pin_getcaps(device_t, uint32_t, uint32_t*);
98static int qoriq_gpio_pin_get(device_t, uint32_t, uint32_t*);
99static int qoriq_gpio_pin_set(device_t, uint32_t, uint32_t);
100static int qoriq_gpio_pin_toggle(device_t, uint32_t);
101static int qoriq_gpio_map_gpios(device_t, phandle_t, phandle_t,
102    int, pcell_t*, uint32_t*, uint32_t*);
103static int qoriq_gpio_pin_access_32(device_t, uint32_t, uint32_t, uint32_t,
104    uint32_t*);
105static int qoriq_gpio_pin_config_32(device_t, uint32_t, uint32_t, uint32_t*);
106
107static device_method_t qoriq_gpio_methods[] = {
108	DEVMETHOD(device_probe,		qoriq_gpio_probe),
109	DEVMETHOD(device_attach,	qoriq_gpio_attach),
110
111	/* GPIO protocol */
112	DEVMETHOD(gpio_get_bus,		qoriq_gpio_get_bus),
113	DEVMETHOD(gpio_pin_max,		qoriq_gpio_pin_max),
114	DEVMETHOD(gpio_pin_getname,	qoriq_gpio_pin_getname),
115	DEVMETHOD(gpio_pin_getflags,	qoriq_gpio_pin_getflags),
116	DEVMETHOD(gpio_pin_setflags,	qoriq_gpio_pin_setflags),
117	DEVMETHOD(gpio_pin_getcaps,	qoriq_gpio_pin_getcaps),
118	DEVMETHOD(gpio_pin_get,		qoriq_gpio_pin_get),
119	DEVMETHOD(gpio_pin_set,		qoriq_gpio_pin_set),
120	DEVMETHOD(gpio_pin_toggle,	qoriq_gpio_pin_toggle),
121	DEVMETHOD(gpio_map_gpios,	qoriq_gpio_map_gpios),
122	DEVMETHOD(gpio_pin_access_32,	qoriq_gpio_pin_access_32),
123	DEVMETHOD(gpio_pin_config_32,	qoriq_gpio_pin_config_32),
124
125	DEVMETHOD_END
126};
127
128static driver_t gpio_driver = {
129	"gpio",
130	qoriq_gpio_methods,
131	sizeof(struct gpio_softc),
132};
133
134static devclass_t gpio_devclass;
135
136DRIVER_MODULE(gpio, simplebus, gpio_driver, gpio_devclass, 0, 0);
137MODULE_VERSION(gpio, 1);
138
139/*
140 * helpers
141 */
142static bool
143qoriq_make_gpio_res(device_t dev, struct gpio_res *out)
144{
145
146	out->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
147	    &out->mem_rid, RF_ACTIVE | RF_SHAREABLE);
148
149	return (out->mem_res == NULL);
150}
151
152static uint32_t
153qoriq_gpio_reg_read(device_t dev, uint32_t reg)
154{
155	struct gpio_softc *sc = device_get_softc(dev);
156	uint32_t result;
157
158	QORIQ_GPIO_ASSERT_LOCKED(sc);
159	result = bus_read_4(sc->res.mem_res, reg);
160
161	return be32toh(result);
162}
163
164static void
165qoriq_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val)
166{
167	struct gpio_softc *sc = device_get_softc(dev);
168
169	QORIQ_GPIO_ASSERT_LOCKED(sc);
170	val = htobe32(val);
171
172	bus_write_4(sc->res.mem_res, reg, val);
173	bus_barrier(sc->res.mem_res, reg, 4, BUS_SPACE_BARRIER_READ |
174	    BUS_SPACE_BARRIER_WRITE);
175}
176
177static void
178qoriq_gpio_set(device_t dev, uint32_t reg, uint32_t pin, uint32_t set)
179{
180	uint32_t val;
181
182	set = set != 0;
183	val = (qoriq_gpio_reg_read(dev, reg) & ~(1U << pin)) | (set << pin);
184	qoriq_gpio_reg_write(dev, reg, val);
185}
186
187static int
188qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags)
189{
190	struct gpio_softc *sc = device_get_softc(dev);
191	uint32_t newflags;
192
193	if (pin >= PIN_COUNT)
194		return (EINVAL);
195
196	/*
197	 * Pin cannot function as input and output at the same time.
198	 * The same applies to open-drain and push-pull functionality.
199	 */
200	if (((flags & GPIO_PIN_INPUT) && (flags & GPIO_PIN_OUTPUT)) ||
201	    ((flags & GPIO_PIN_OPENDRAIN) && (flags & GPIO_PIN_PUSHPULL)))
202		return (EINVAL);
203
204	QORIQ_GPIO_ASSERT_LOCKED(sc);
205
206	if (flags & GPIO_PIN_INPUT) {
207		newflags = GPIO_PIN_INPUT;
208		qoriq_gpio_set(dev, DIRECTION, pin, 0);
209	}
210
211	if (flags & GPIO_PIN_OUTPUT) {
212		newflags = GPIO_PIN_OUTPUT;
213		qoriq_gpio_set(dev, DIRECTION, pin, 1);
214
215		if (flags & GPIO_PIN_OPENDRAIN) {
216			newflags |= GPIO_PIN_OPENDRAIN;
217			qoriq_gpio_set(dev, OPEN_DRAIN, pin, 1);
218		} else {
219			newflags |= GPIO_PIN_PUSHPULL;
220			qoriq_gpio_set(dev, OPEN_DRAIN, pin, 0);
221		}
222	}
223
224	sc->setup[pin].gp_flags = newflags;
225
226	return (0);
227}
228
229/* GPIO API */
230static int
231qoriq_gpio_probe(device_t dev)
232{
233
234	if (!ofw_bus_status_okay(dev))
235		return (ENXIO);
236
237	if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio"))
238		return (ENXIO);
239
240	device_set_desc(dev, "Integrated GPIO Controller");
241
242	return (BUS_PROBE_DEFAULT);
243}
244
245static int
246qoriq_gpio_attach(device_t dev)
247{
248	struct gpio_softc *sc = device_get_softc(dev);
249	int i;
250
251	if (qoriq_make_gpio_res(dev, &sc->res))
252		return (ENXIO);
253
254	for (i = 0; i < PIN_COUNT; i++)
255		sc->setup[i].gp_caps = DEFAULT_CAPS;
256
257	sc->dev = dev;
258
259	sc->busdev = gpiobus_attach_bus(dev);
260	if (sc->busdev == NULL)
261		return (ENXIO);
262
263	return (0);
264}
265
266static device_t
267qoriq_gpio_get_bus(device_t dev)
268{
269	struct gpio_softc *softc = device_get_softc(dev);
270
271	return (softc->busdev);
272}
273
274static int
275qoriq_gpio_pin_max(device_t dev, int *maxpin)
276{
277
278	if (maxpin == NULL)
279		return (EINVAL);
280
281	*maxpin = PIN_COUNT - 1;
282
283	return (0);
284}
285
286static int
287qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
288{
289
290	if (name == NULL || pin >= PIN_COUNT)
291		return (EINVAL);
292
293	snprintf(name, GPIOMAXNAME, "pin %d", pin);
294
295	return (0);
296}
297
298static int
299qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags)
300{
301	struct gpio_softc *sc = device_get_softc(dev);
302
303	if (pflags == NULL || pin >= PIN_COUNT)
304		return (EINVAL);
305
306	QORIQ_GPIO_LOCK(sc);
307	*pflags = sc->setup[pin].gp_flags;
308	QORIQ_GPIO_UNLOCK(sc);
309
310	return (0);
311}
312
313static int
314qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
315{
316	struct gpio_softc *sc = device_get_softc(dev);
317	int ret;
318
319	if (pin >= PIN_COUNT)
320		return (EINVAL);
321
322	/* Check for unwanted flags. */
323	QORIQ_GPIO_LOCK(sc);
324
325	if ((flags & sc->setup[pin].gp_caps) != flags) {
326		QORIQ_GPIO_UNLOCK(sc);
327		return (EINVAL);
328	}
329
330	ret = qoriq_gpio_configure(dev, pin, flags);
331
332	QORIQ_GPIO_UNLOCK(sc);
333
334	return (ret);
335}
336
337static int
338qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
339{
340	struct gpio_softc *sc = device_get_softc(dev);
341
342	if (caps == NULL || pin >= PIN_COUNT)
343		return (EINVAL);
344
345	QORIQ_GPIO_LOCK(sc);
346	*caps = sc->setup[pin].gp_caps;
347	QORIQ_GPIO_UNLOCK(sc);
348
349	return (0);
350}
351
352static int
353qoriq_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
354{
355	struct gpio_softc *sc = device_get_softc(dev);
356
357	if (value == NULL || pin >= PIN_COUNT)
358		return (EINVAL);
359
360	QORIQ_GPIO_LOCK(sc);
361	*value = (qoriq_gpio_reg_read(dev, DATA) & GPIO(pin)) != 0;
362	QORIQ_GPIO_UNLOCK(sc);
363
364	return (0);
365}
366
367static int
368qoriq_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
369{
370	struct gpio_softc *sc = device_get_softc(dev);
371
372	if (pin >= PIN_COUNT)
373		return (EINVAL);
374
375	QORIQ_GPIO_LOCK(sc);
376	qoriq_gpio_set(dev, DATA, pin, value);
377	QORIQ_GPIO_UNLOCK(sc);
378
379	return (0);
380}
381
382static int
383qoriq_gpio_pin_toggle(device_t dev, uint32_t pin)
384{
385	struct gpio_softc *sc;
386	uint32_t value;
387
388	if (pin >= PIN_COUNT)
389		return (EINVAL);
390
391	sc = device_get_softc(dev);
392
393	QORIQ_GPIO_LOCK(sc);
394	value = qoriq_gpio_reg_read(dev, DATA) ^ (1 << pin);
395	qoriq_gpio_reg_write(dev, DATA, value);
396	QORIQ_GPIO_UNLOCK(sc);
397
398	return (0);
399}
400
401static int
402qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
403    pcell_t *gpios, uint32_t *pin, uint32_t *flags)
404{
405	struct gpio_softc *sc = device_get_softc(bus);
406	int err;
407
408	if (gpios[0] >= PIN_COUNT)
409		return (EINVAL);
410
411	QORIQ_GPIO_LOCK(sc);
412	err = qoriq_gpio_configure(bus, gpios[0], gpios[1]);
413	QORIQ_GPIO_UNLOCK(sc);
414
415	if (err != 0)
416		return (err);
417
418	*pin = gpios[0];
419	*flags = gpios[1];
420
421	return (0);
422}
423
424static int
425qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
426    uint32_t change_pins, uint32_t *orig_pins)
427{
428	struct gpio_softc *sc;
429	uint32_t hwstate;
430
431	sc = device_get_softc(dev);
432
433	if (first_pin != 0)
434		return (EINVAL);
435
436	QORIQ_GPIO_LOCK(sc);
437	hwstate = qoriq_gpio_reg_read(dev, DATA);
438	qoriq_gpio_reg_write(dev, DATA, (hwstate & ~clear_pins) ^ change_pins);
439	QORIQ_GPIO_UNLOCK(sc);
440
441	if (orig_pins != NULL)
442		*orig_pins = hwstate;
443
444	return (0);
445}
446
447static int
448qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
449    uint32_t *pin_flags)
450{
451	uint32_t dir, odr, mask, reg;
452	struct gpio_softc *sc;
453	uint32_t newflags[32];
454	int i;
455
456	if (first_pin != 0 || num_pins > PIN_COUNT)
457		return (EINVAL);
458
459	sc = device_get_softc(dev);
460
461	dir = odr = mask = 0;
462
463	for (i = 0; i < num_pins; i++) {
464		newflags[i] = 0;
465		mask |= (1 << i);
466
467		if (pin_flags[i] & GPIO_PIN_INPUT) {
468			newflags[i] = GPIO_PIN_INPUT;
469			dir &= ~(1 << i);
470		} else {
471			newflags[i] = GPIO_PIN_OUTPUT;
472			dir |= (1 << i);
473
474			if (pin_flags[i] & GPIO_PIN_OPENDRAIN) {
475				newflags[i] |= GPIO_PIN_OPENDRAIN;
476				odr |= (1 << i);
477			} else {
478				newflags[i] |= GPIO_PIN_PUSHPULL;
479				odr &= ~(1 << i);
480			}
481		}
482	}
483
484	QORIQ_GPIO_LOCK(sc);
485
486	reg = (qoriq_gpio_reg_read(dev, DIRECTION) & ~mask) | dir;
487	qoriq_gpio_reg_write(dev, DIRECTION, reg);
488
489	reg = (qoriq_gpio_reg_read(dev, OPEN_DRAIN) & ~mask) | odr;
490	qoriq_gpio_reg_write(dev, OPEN_DRAIN, reg);
491
492	for (i = 0; i < num_pins; i++)
493		sc->setup[i].gp_flags = newflags[i];
494
495	QORIQ_GPIO_UNLOCK(sc);
496
497	return (0);
498}
499