lpc_gpio.c revision 242692
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: head/sys/arm/lpc/lpc_gpio.c 242692 2012-11-07 07:00:59Z kevlo $");
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/frame.h>
80#include <machine/intr.h>
81#include <machine/fdt.h>
82
83#include <dev/ofw/ofw_bus.h>
84#include <dev/ofw/ofw_bus_subr.h>
85
86#include <arm/lpc/lpcreg.h>
87#include <arm/lpc/lpcvar.h>
88
89#include "gpio_if.h"
90
91struct lpc_gpio_softc
92{
93	device_t		lg_dev;
94	struct resource *	lg_res;
95	bus_space_tag_t		lg_bst;
96	bus_space_handle_t	lg_bsh;
97};
98
99struct lpc_gpio_pinmap
100{
101	int			lp_start_idx;
102	int			lp_pin_count;
103	int			lp_port;
104	int			lp_start_bit;
105	int			lp_flags;
106};
107
108static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
109	{ 0,	10,	3,	0,	GPIO_PIN_INPUT },
110	{ 10,	9,	3,	15,	GPIO_PIN_INPUT },
111	{ 19,	1,	3,	25,	GPIO_PIN_INPUT },
112	{ 20,	2,	3,	27,	GPIO_PIN_INPUT },
113	{ 22,	24,	3,	0,	GPIO_PIN_OUTPUT },
114	/*
115	 * -1 below is to mark special case for Port3 GPIO pins, as they
116	 * have other bits in Port 3 registers as inputs and as outputs
117	 */
118	{ 46,	6,	3,	-1,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
119	{ 52,	13,	2,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
120	{ 65,	24,	1,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
121	{ 89,	8,	0,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
122	{ -1,	-1,	-1,	-1,	-1 },
123};
124
125#define	LPC_GPIO_NPINS				\
126    (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT +	\
127    LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
128
129#define	LPC_GPIO_PIN_IDX(_map, _idx)	\
130    (_idx - _map->lp_start_idx)
131
132#define	LPC_GPIO_PIN_BIT(_map, _idx)	\
133    (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
134
135static int lpc_gpio_probe(device_t);
136static int lpc_gpio_attach(device_t);
137static int lpc_gpio_detach(device_t);
138
139static int lpc_gpio_pin_max(device_t, int *);
140static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
141static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
142static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
143static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
144static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
145static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
146static int lpc_gpio_pin_toggle(device_t, uint32_t);
147
148static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
149
150static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
151
152#define	lpc_gpio_read_4(_sc, _reg) \
153    bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
154#define	lpc_gpio_write_4(_sc, _reg, _val) \
155    bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
156#define	lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
157    lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
158#define	lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
159    lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
160
161static int
162lpc_gpio_probe(device_t dev)
163{
164	if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
165		return (ENXIO);
166
167	device_set_desc(dev, "LPC32x0 GPIO");
168	return (BUS_PROBE_DEFAULT);
169}
170
171static int
172lpc_gpio_attach(device_t dev)
173{
174	struct lpc_gpio_softc *sc = device_get_softc(dev);
175	int rid;
176
177	sc->lg_dev = dev;
178
179	rid = 0;
180	sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
181	    RF_ACTIVE);
182	if (!sc->lg_res) {
183		device_printf(dev, "cannot allocate memory window\n");
184		return (ENXIO);
185	}
186
187	sc->lg_bst = rman_get_bustag(sc->lg_res);
188	sc->lg_bsh = rman_get_bushandle(sc->lg_res);
189
190	lpc_gpio_sc = sc;
191
192	device_add_child(dev, "gpioc", device_get_unit(dev));
193	device_add_child(dev, "gpiobus", device_get_unit(dev));
194
195	return (bus_generic_attach(dev));
196}
197
198static int
199lpc_gpio_detach(device_t dev)
200{
201	return (EBUSY);
202}
203
204static int
205lpc_gpio_pin_max(device_t dev, int *npins)
206{
207	*npins = LPC_GPIO_NPINS - 1;
208	return (0);
209}
210
211static int
212lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
213{
214	const struct lpc_gpio_pinmap *map;
215
216	if (pin > LPC_GPIO_NPINS)
217		return (ENODEV);
218
219	map = lpc_gpio_get_pinmap(pin);
220
221	*caps = map->lp_flags;
222	return (0);
223}
224
225static int
226lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
227{
228	struct lpc_gpio_softc *sc = device_get_softc(dev);
229	const struct lpc_gpio_pinmap *map;
230	uint32_t state;
231	int dir;
232
233	if (pin > LPC_GPIO_NPINS)
234		return (ENODEV);
235
236	map = lpc_gpio_get_pinmap(pin);
237
238	/* Check whether it's bidirectional pin */
239	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
240	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
241		*flags = map->lp_flags;
242		return (0);
243	}
244
245	switch (map->lp_port) {
246	case 0:
247		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
248		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
249		break;
250	case 1:
251		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
252		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
253		break;
254	case 2:
255		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
256		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
257		break;
258	case 3:
259		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
260		dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
261		break;
262	default:
263		panic("unknown GPIO port");
264	}
265
266	*flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
267
268	return (0);
269}
270
271static int
272lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
273{
274	struct lpc_gpio_softc *sc = device_get_softc(dev);
275	const struct lpc_gpio_pinmap *map;
276	uint32_t dir, state;
277
278	if (pin > LPC_GPIO_NPINS)
279		return (ENODEV);
280
281	map = lpc_gpio_get_pinmap(pin);
282
283	/* Check whether it's bidirectional pin */
284	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
285	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
286		return (ENOTSUP);
287
288	if (flags & GPIO_PIN_INPUT)
289		dir = 0;
290
291	if (flags & GPIO_PIN_OUTPUT)
292		dir = 1;
293
294	switch (map->lp_port) {
295	case 0:
296		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
297		lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET,
298		    LPC_GPIO_P0_DIR_CLR, state);
299		break;
300	case 1:
301		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
302		lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET,
303		    LPC_GPIO_P0_DIR_CLR, state);
304		break;
305	case 2:
306		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
307		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
308		    LPC_GPIO_P0_DIR_CLR, state);
309		break;
310	case 3:
311		state = (1 << (25 + (pin - map->lp_start_idx)));
312		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
313		    LPC_GPIO_P0_DIR_CLR, state);
314		break;
315	}
316
317	return (0);
318}
319
320static int
321lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
322{
323	const struct lpc_gpio_pinmap *map;
324	int idx;
325
326	map = lpc_gpio_get_pinmap(pin);
327	idx = LPC_GPIO_PIN_IDX(map, pin);
328
329	switch (map->lp_port) {
330	case 0:
331	case 1:
332	case 2:
333		snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port,
334		    map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
335		break;
336	case 3:
337		if (map->lp_start_bit == -1) {
338			snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
339			break;
340		}
341
342		snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
343		    (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
344		    map->lp_start_bit + idx);
345		break;
346	}
347
348	return (0);
349}
350
351static int
352lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
353{
354	struct lpc_gpio_softc *sc = device_get_softc(dev);
355	const struct lpc_gpio_pinmap *map;
356	uint32_t state, flags;
357	int dir;
358
359	map = lpc_gpio_get_pinmap(pin);
360
361	if (lpc_gpio_pin_getflags(dev, pin, &flags))
362		return (ENXIO);
363
364	if (flags & GPIO_PIN_OUTPUT)
365		dir = 1;
366
367	if (flags & GPIO_PIN_INPUT)
368		dir = 0;
369
370	switch (map->lp_port) {
371	case 0:
372		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
373		    LPC_GPIO_P0_INP_STATE);
374		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
375	case 1:
376		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
377		    LPC_GPIO_P1_INP_STATE);
378		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
379	case 2:
380		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
381		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
382	case 3:
383		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
384		    LPC_GPIO_P3_INP_STATE);
385		if (map->lp_start_bit == -1) {
386			if (dir)
387				*value = !!(state & (1 << (25 +
388				    LPC_GPIO_PIN_IDX(map, pin))));
389			else
390				*value = !!(state & (1 << (10 +
391				    LPC_GPIO_PIN_IDX(map, pin))));
392		}
393
394		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
395	}
396
397	return (0);
398}
399
400static int
401lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
402{
403	struct lpc_gpio_softc *sc = device_get_softc(dev);
404	const struct lpc_gpio_pinmap *map;
405	uint32_t state, flags;
406
407	map = lpc_gpio_get_pinmap(pin);
408
409	if (lpc_gpio_pin_getflags(dev, pin, &flags))
410		return (ENXIO);
411
412	if ((flags & GPIO_PIN_OUTPUT) == 0)
413		return (EINVAL);
414
415	state = (1 << LPC_GPIO_PIN_BIT(map, pin));
416
417	switch (map->lp_port) {
418	case 0:
419		lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
420		    LPC_GPIO_P0_OUTP_CLR, state);
421		break;
422	case 1:
423		lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
424		    LPC_GPIO_P1_OUTP_CLR, state);
425		break;
426	case 2:
427		lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
428		    LPC_GPIO_P2_OUTP_CLR, state);
429		break;
430	case 3:
431		if (map->lp_start_bit == -1)
432			state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
433
434		lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
435		    LPC_GPIO_P3_OUTP_CLR, state);
436		break;
437	}
438
439	return (0);
440}
441
442static int
443lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
444{
445	const struct lpc_gpio_pinmap *map;
446	uint32_t flags;
447
448	map = lpc_gpio_get_pinmap(pin);
449
450	if (lpc_gpio_pin_getflags(dev, pin, &flags))
451		return (ENXIO);
452
453	if ((flags & GPIO_PIN_OUTPUT) == 0)
454		return (EINVAL);
455
456	panic("not implemented yet");
457
458	return (0);
459
460}
461
462static const struct lpc_gpio_pinmap *
463lpc_gpio_get_pinmap(int pin)
464{
465	const struct lpc_gpio_pinmap *map;
466
467	for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
468		if (pin >= map->lp_start_idx &&
469		    pin < map->lp_start_idx + map->lp_pin_count)
470			return map;
471	}
472
473	panic("pin number %d out of range", pin);
474}
475
476int
477lpc_gpio_set_flags(device_t dev, int pin, int flags)
478{
479	if (lpc_gpio_sc == NULL)
480		return (ENXIO);
481
482	return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
483}
484
485int
486lpc_gpio_set_state(device_t dev, int pin, int state)
487{
488	if (lpc_gpio_sc == NULL)
489		return (ENXIO);
490
491	return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state);
492}
493
494int
495lpc_gpio_get_state(device_t dev, int pin, int *state)
496{
497	if (lpc_gpio_sc == NULL)
498		return (ENXIO);
499
500	return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
501}
502
503void
504platform_gpio_init()
505{
506	/* Preset SPI devices CS pins to one */
507	bus_space_write_4(fdtbus_bs_tag,
508	    LPC_GPIO_BASE, LPC_GPIO_P3_OUTP_SET,
509	    1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
510	    1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
511	    1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));
512}
513
514static device_method_t lpc_gpio_methods[] = {
515	/* Device interface */
516	DEVMETHOD(device_probe,		lpc_gpio_probe),
517	DEVMETHOD(device_attach,	lpc_gpio_attach),
518	DEVMETHOD(device_detach,	lpc_gpio_detach),
519
520	/* GPIO interface */
521	DEVMETHOD(gpio_pin_max,		lpc_gpio_pin_max),
522	DEVMETHOD(gpio_pin_getcaps,	lpc_gpio_pin_getcaps),
523	DEVMETHOD(gpio_pin_getflags,	lpc_gpio_pin_getflags),
524	DEVMETHOD(gpio_pin_setflags,	lpc_gpio_pin_setflags),
525	DEVMETHOD(gpio_pin_getname,	lpc_gpio_pin_getname),
526	DEVMETHOD(gpio_pin_set,		lpc_gpio_pin_set),
527	DEVMETHOD(gpio_pin_get,		lpc_gpio_pin_get),
528	DEVMETHOD(gpio_pin_toggle,	lpc_gpio_pin_toggle),
529
530	{ 0, 0 }
531};
532
533static devclass_t lpc_gpio_devclass;
534
535static driver_t lpc_gpio_driver = {
536	"lpcgpio",
537	lpc_gpio_methods,
538	sizeof(struct lpc_gpio_softc),
539};
540
541extern devclass_t gpiobus_devclass, gpioc_devclass;
542extern driver_t gpiobus_driver, gpioc_driver;
543
544DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
545DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
546DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
547MODULE_VERSION(lpcgpio, 1);
548