lpc_gpio.c revision 266084
1/*-
2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28/*
29 * GPIO on LPC32x0 consist of 4 ports:
30 * - Port0 with 8 input/output pins
31 * - Port1 with 24 input/output pins
32 * - Port2 with 13 input/output pins
33 * - Port3 with:
34 *   - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
35 *   - 24 output pins (GPO_00..GPO_23)
36 *   - 6 input/output pins (GPIO_00..GPIO_05)
37 *
38 * Pins are mapped to logical pin number as follows:
39 * [0..9] -> GPI_00..GPI_09 		(port 3)
40 * [10..18] -> GPI_15..GPI_23 		(port 3)
41 * [19] -> GPI_25			(port 3)
42 * [20..21] -> GPI_27..GPI_28		(port 3)
43 * [22..45] -> GPO_00..GPO_23		(port 3)
44 * [46..51] -> GPIO_00..GPIO_05		(port 3)
45 * [52..64] -> P2.0..P2.12		(port 2)
46 * [65..88] -> P1.0..P1.23		(port 1)
47 * [89..96] -> P0.0..P0.7		(port 0)
48 *
49 */
50
51
52#include <sys/cdefs.h>
53__FBSDID("$FreeBSD: stable/10/sys/arm/lpc/lpc_gpio.c 266084 2014-05-14 19:18:58Z ian $");
54
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/bio.h>
58#include <sys/bus.h>
59#include <sys/conf.h>
60#include <sys/endian.h>
61#include <sys/kernel.h>
62#include <sys/kthread.h>
63#include <sys/lock.h>
64#include <sys/malloc.h>
65#include <sys/module.h>
66#include <sys/mutex.h>
67#include <sys/queue.h>
68#include <sys/resource.h>
69#include <sys/rman.h>
70#include <sys/time.h>
71#include <sys/timetc.h>
72#include <sys/watchdog.h>
73#include <sys/gpio.h>
74
75#include <machine/bus.h>
76#include <machine/cpu.h>
77#include <machine/cpufunc.h>
78#include <machine/resource.h>
79#include <machine/intr.h>
80#include <machine/fdt.h>
81
82#include <dev/ofw/ofw_bus.h>
83#include <dev/ofw/ofw_bus_subr.h>
84
85#include <arm/lpc/lpcreg.h>
86#include <arm/lpc/lpcvar.h>
87
88#include "gpio_if.h"
89
90struct lpc_gpio_softc
91{
92	device_t		lg_dev;
93	struct resource *	lg_res;
94	bus_space_tag_t		lg_bst;
95	bus_space_handle_t	lg_bsh;
96};
97
98struct lpc_gpio_pinmap
99{
100	int			lp_start_idx;
101	int			lp_pin_count;
102	int			lp_port;
103	int			lp_start_bit;
104	int			lp_flags;
105};
106
107static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
108	{ 0,	10,	3,	0,	GPIO_PIN_INPUT },
109	{ 10,	9,	3,	15,	GPIO_PIN_INPUT },
110	{ 19,	1,	3,	25,	GPIO_PIN_INPUT },
111	{ 20,	2,	3,	27,	GPIO_PIN_INPUT },
112	{ 22,	24,	3,	0,	GPIO_PIN_OUTPUT },
113	/*
114	 * -1 below is to mark special case for Port3 GPIO pins, as they
115	 * have other bits in Port 3 registers as inputs and as outputs
116	 */
117	{ 46,	6,	3,	-1,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
118	{ 52,	13,	2,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
119	{ 65,	24,	1,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
120	{ 89,	8,	0,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
121	{ -1,	-1,	-1,	-1,	-1 },
122};
123
124#define	LPC_GPIO_NPINS				\
125    (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT +	\
126    LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
127
128#define	LPC_GPIO_PIN_IDX(_map, _idx)	\
129    (_idx - _map->lp_start_idx)
130
131#define	LPC_GPIO_PIN_BIT(_map, _idx)	\
132    (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
133
134static int lpc_gpio_probe(device_t);
135static int lpc_gpio_attach(device_t);
136static int lpc_gpio_detach(device_t);
137
138static int lpc_gpio_pin_max(device_t, int *);
139static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
140static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
141static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
142static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
143static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
144static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
145static int lpc_gpio_pin_toggle(device_t, uint32_t);
146
147static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
148
149static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
150
151#define	lpc_gpio_read_4(_sc, _reg) \
152    bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
153#define	lpc_gpio_write_4(_sc, _reg, _val) \
154    bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
155#define	lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
156    lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
157#define	lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
158    lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
159
160static int
161lpc_gpio_probe(device_t dev)
162{
163	if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
164		return (ENXIO);
165
166	device_set_desc(dev, "LPC32x0 GPIO");
167	return (BUS_PROBE_DEFAULT);
168}
169
170static int
171lpc_gpio_attach(device_t dev)
172{
173	struct lpc_gpio_softc *sc = device_get_softc(dev);
174	int rid;
175
176	sc->lg_dev = dev;
177
178	rid = 0;
179	sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
180	    RF_ACTIVE);
181	if (!sc->lg_res) {
182		device_printf(dev, "cannot allocate memory window\n");
183		return (ENXIO);
184	}
185
186	sc->lg_bst = rman_get_bustag(sc->lg_res);
187	sc->lg_bsh = rman_get_bushandle(sc->lg_res);
188
189	lpc_gpio_sc = sc;
190
191	device_add_child(dev, "gpioc", device_get_unit(dev));
192	device_add_child(dev, "gpiobus", device_get_unit(dev));
193
194	return (bus_generic_attach(dev));
195}
196
197static int
198lpc_gpio_detach(device_t dev)
199{
200	return (EBUSY);
201}
202
203static int
204lpc_gpio_pin_max(device_t dev, int *npins)
205{
206	*npins = LPC_GPIO_NPINS - 1;
207	return (0);
208}
209
210static int
211lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
212{
213	const struct lpc_gpio_pinmap *map;
214
215	if (pin > LPC_GPIO_NPINS)
216		return (ENODEV);
217
218	map = lpc_gpio_get_pinmap(pin);
219
220	*caps = map->lp_flags;
221	return (0);
222}
223
224static int
225lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
226{
227	struct lpc_gpio_softc *sc = device_get_softc(dev);
228	const struct lpc_gpio_pinmap *map;
229	uint32_t state;
230	int dir;
231
232	if (pin > LPC_GPIO_NPINS)
233		return (ENODEV);
234
235	map = lpc_gpio_get_pinmap(pin);
236
237	/* Check whether it's bidirectional pin */
238	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
239	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
240		*flags = map->lp_flags;
241		return (0);
242	}
243
244	switch (map->lp_port) {
245	case 0:
246		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
247		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
248		break;
249	case 1:
250		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
251		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
252		break;
253	case 2:
254		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
255		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
256		break;
257	case 3:
258		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
259		dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
260		break;
261	default:
262		panic("unknown GPIO port");
263	}
264
265	*flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
266
267	return (0);
268}
269
270static int
271lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
272{
273	struct lpc_gpio_softc *sc = device_get_softc(dev);
274	const struct lpc_gpio_pinmap *map;
275	uint32_t dir, state;
276
277	if (pin > LPC_GPIO_NPINS)
278		return (ENODEV);
279
280	map = lpc_gpio_get_pinmap(pin);
281
282	/* Check whether it's bidirectional pin */
283	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
284	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
285		return (ENOTSUP);
286
287	if (flags & GPIO_PIN_INPUT)
288		dir = 0;
289
290	if (flags & GPIO_PIN_OUTPUT)
291		dir = 1;
292
293	switch (map->lp_port) {
294	case 0:
295		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
296		lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET,
297		    LPC_GPIO_P0_DIR_CLR, state);
298		break;
299	case 1:
300		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
301		lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET,
302		    LPC_GPIO_P0_DIR_CLR, state);
303		break;
304	case 2:
305		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
306		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
307		    LPC_GPIO_P0_DIR_CLR, state);
308		break;
309	case 3:
310		state = (1 << (25 + (pin - map->lp_start_idx)));
311		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
312		    LPC_GPIO_P0_DIR_CLR, state);
313		break;
314	}
315
316	return (0);
317}
318
319static int
320lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
321{
322	const struct lpc_gpio_pinmap *map;
323	int idx;
324
325	map = lpc_gpio_get_pinmap(pin);
326	idx = LPC_GPIO_PIN_IDX(map, pin);
327
328	switch (map->lp_port) {
329	case 0:
330	case 1:
331	case 2:
332		snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port,
333		    map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
334		break;
335	case 3:
336		if (map->lp_start_bit == -1) {
337			snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
338			break;
339		}
340
341		snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
342		    (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
343		    map->lp_start_bit + idx);
344		break;
345	}
346
347	return (0);
348}
349
350static int
351lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
352{
353	struct lpc_gpio_softc *sc = device_get_softc(dev);
354	const struct lpc_gpio_pinmap *map;
355	uint32_t state, flags;
356	int dir;
357
358	map = lpc_gpio_get_pinmap(pin);
359
360	if (lpc_gpio_pin_getflags(dev, pin, &flags))
361		return (ENXIO);
362
363	if (flags & GPIO_PIN_OUTPUT)
364		dir = 1;
365
366	if (flags & GPIO_PIN_INPUT)
367		dir = 0;
368
369	switch (map->lp_port) {
370	case 0:
371		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
372		    LPC_GPIO_P0_INP_STATE);
373		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
374	case 1:
375		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
376		    LPC_GPIO_P1_INP_STATE);
377		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
378	case 2:
379		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
380		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
381	case 3:
382		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
383		    LPC_GPIO_P3_INP_STATE);
384		if (map->lp_start_bit == -1) {
385			if (dir)
386				*value = !!(state & (1 << (25 +
387				    LPC_GPIO_PIN_IDX(map, pin))));
388			else
389				*value = !!(state & (1 << (10 +
390				    LPC_GPIO_PIN_IDX(map, pin))));
391		}
392
393		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
394	}
395
396	return (0);
397}
398
399static int
400lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
401{
402	struct lpc_gpio_softc *sc = device_get_softc(dev);
403	const struct lpc_gpio_pinmap *map;
404	uint32_t state, flags;
405
406	map = lpc_gpio_get_pinmap(pin);
407
408	if (lpc_gpio_pin_getflags(dev, pin, &flags))
409		return (ENXIO);
410
411	if ((flags & GPIO_PIN_OUTPUT) == 0)
412		return (EINVAL);
413
414	state = (1 << LPC_GPIO_PIN_BIT(map, pin));
415
416	switch (map->lp_port) {
417	case 0:
418		lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
419		    LPC_GPIO_P0_OUTP_CLR, state);
420		break;
421	case 1:
422		lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
423		    LPC_GPIO_P1_OUTP_CLR, state);
424		break;
425	case 2:
426		lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
427		    LPC_GPIO_P2_OUTP_CLR, state);
428		break;
429	case 3:
430		if (map->lp_start_bit == -1)
431			state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
432
433		lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
434		    LPC_GPIO_P3_OUTP_CLR, state);
435		break;
436	}
437
438	return (0);
439}
440
441static int
442lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
443{
444	const struct lpc_gpio_pinmap *map;
445	uint32_t flags;
446
447	map = lpc_gpio_get_pinmap(pin);
448
449	if (lpc_gpio_pin_getflags(dev, pin, &flags))
450		return (ENXIO);
451
452	if ((flags & GPIO_PIN_OUTPUT) == 0)
453		return (EINVAL);
454
455	panic("not implemented yet");
456
457	return (0);
458
459}
460
461static const struct lpc_gpio_pinmap *
462lpc_gpio_get_pinmap(int pin)
463{
464	const struct lpc_gpio_pinmap *map;
465
466	for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
467		if (pin >= map->lp_start_idx &&
468		    pin < map->lp_start_idx + map->lp_pin_count)
469			return map;
470	}
471
472	panic("pin number %d out of range", pin);
473}
474
475int
476lpc_gpio_set_flags(device_t dev, int pin, int flags)
477{
478	if (lpc_gpio_sc == NULL)
479		return (ENXIO);
480
481	return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
482}
483
484int
485lpc_gpio_set_state(device_t dev, int pin, int state)
486{
487	if (lpc_gpio_sc == NULL)
488		return (ENXIO);
489
490	return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state);
491}
492
493int
494lpc_gpio_get_state(device_t dev, int pin, int *state)
495{
496	if (lpc_gpio_sc == NULL)
497		return (ENXIO);
498
499	return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
500}
501
502void
503platform_gpio_init()
504{
505	bus_space_tag_t bst;
506	bus_space_handle_t bsh;
507
508	bst = fdtbus_bs_tag;
509
510	/* Preset SPI devices CS pins to one */
511	bus_space_map(bst, LPC_GPIO_PHYS_BASE, LPC_GPIO_SIZE, 0, &bsh);
512	bus_space_write_4(bst, bsh, LPC_GPIO_P3_OUTP_SET,
513	    1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
514	    1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
515	    1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));
516	bus_space_unmap(bst, bsh, LPC_GPIO_SIZE);
517}
518
519static device_method_t lpc_gpio_methods[] = {
520	/* Device interface */
521	DEVMETHOD(device_probe,		lpc_gpio_probe),
522	DEVMETHOD(device_attach,	lpc_gpio_attach),
523	DEVMETHOD(device_detach,	lpc_gpio_detach),
524
525	/* GPIO interface */
526	DEVMETHOD(gpio_pin_max,		lpc_gpio_pin_max),
527	DEVMETHOD(gpio_pin_getcaps,	lpc_gpio_pin_getcaps),
528	DEVMETHOD(gpio_pin_getflags,	lpc_gpio_pin_getflags),
529	DEVMETHOD(gpio_pin_setflags,	lpc_gpio_pin_setflags),
530	DEVMETHOD(gpio_pin_getname,	lpc_gpio_pin_getname),
531	DEVMETHOD(gpio_pin_set,		lpc_gpio_pin_set),
532	DEVMETHOD(gpio_pin_get,		lpc_gpio_pin_get),
533	DEVMETHOD(gpio_pin_toggle,	lpc_gpio_pin_toggle),
534
535	{ 0, 0 }
536};
537
538static devclass_t lpc_gpio_devclass;
539
540static driver_t lpc_gpio_driver = {
541	"lpcgpio",
542	lpc_gpio_methods,
543	sizeof(struct lpc_gpio_softc),
544};
545
546extern devclass_t gpiobus_devclass, gpioc_devclass;
547extern driver_t gpiobus_driver, gpioc_driver;
548
549DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
550DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
551DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
552MODULE_VERSION(lpcgpio, 1);
553