2 * Copyright (c) 2006 Benno Rice. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 #include <sys/cdefs.h>
26 __FBSDID("$FreeBSD$");
28 #include <sys/param.h>
29 #include <sys/systm.h>
31 #include <sys/kernel.h>
33 #include <sys/interrupt.h>
34 #include <sys/module.h>
35 #include <sys/malloc.h>
36 #include <sys/mutex.h>
38 #include <sys/queue.h>
39 #include <sys/taskqueue.h>
40 #include <sys/timetc.h>
41 #include <machine/bus.h>
42 #include <machine/intr.h>
44 #include <arm/xscale/pxa/pxavar.h>
45 #include <arm/xscale/pxa/pxareg.h>
47 struct pxa_gpio_softc {
48 struct resource * pg_res[4];
49 bus_space_tag_t pg_bst;
50 bus_space_handle_t pg_bsh;
56 static struct resource_spec pxa_gpio_spec[] = {
57 { SYS_RES_MEMORY, 0, RF_ACTIVE },
58 { SYS_RES_IRQ, 0, RF_ACTIVE },
59 { SYS_RES_IRQ, 1, RF_ACTIVE },
60 { SYS_RES_IRQ, 2, RF_ACTIVE },
64 static struct pxa_gpio_softc *pxa_gpio_softc = NULL;
66 static int pxa_gpio_probe(device_t);
67 static int pxa_gpio_attach(device_t);
69 static driver_filter_t pxa_gpio_intr0;
70 static driver_filter_t pxa_gpio_intr1;
71 static driver_filter_t pxa_gpio_intrN;
74 pxa_gpio_probe(device_t dev)
77 device_set_desc(dev, "GPIO Controller");
82 pxa_gpio_attach(device_t dev)
86 struct pxa_gpio_softc *sc;
88 sc = (struct pxa_gpio_softc *)device_get_softc(dev);
90 if (pxa_gpio_softc != NULL)
94 error = bus_alloc_resources(dev, pxa_gpio_spec, sc->pg_res);
96 device_printf(dev, "could not allocate resources\n");
100 sc->pg_bst = rman_get_bustag(sc->pg_res[0]);
101 sc->pg_bsh = rman_get_bushandle(sc->pg_res[0]);
103 /* Disable and clear all interrupts. */
104 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER0, 0);
105 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER1, 0);
106 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER2, 0);
107 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER0, 0);
108 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER1, 0);
109 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER2, 0);
110 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, ~0);
111 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, ~0);
112 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, ~0);
114 mtx_init(&sc->pg_mtx, "GPIO mutex", NULL, MTX_SPIN);
116 if (bus_setup_intr(dev, sc->pg_res[1], INTR_TYPE_MISC|INTR_MPSAFE,
117 pxa_gpio_intr0, NULL, sc, &ihl) != 0) {
118 bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
119 device_printf(dev, "could not set up intr0\n");
123 if (bus_setup_intr(dev, sc->pg_res[2], INTR_TYPE_MISC|INTR_MPSAFE,
124 pxa_gpio_intr1, NULL, sc, &ihl) != 0) {
125 bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
126 device_printf(dev, "could not set up intr1\n");
130 if (bus_setup_intr(dev, sc->pg_res[3], INTR_TYPE_MISC|INTR_MPSAFE,
131 pxa_gpio_intrN, NULL, sc, &ihl) != 0) {
132 bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
133 device_printf(dev, "could not set up intrN\n");
141 pxa_gpio_intr0(void *arg)
143 struct pxa_gpio_softc *sc;
145 sc = (struct pxa_gpio_softc *)arg;
147 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x1);
150 return (FILTER_HANDLED);
154 pxa_gpio_intr1(void *arg)
156 struct pxa_gpio_softc *sc;
158 sc = (struct pxa_gpio_softc *)arg;
160 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x2);
163 return (FILTER_HANDLED);
167 pxa_gpio_intrN(void *arg)
169 uint32_t gedr0, gedr1, gedr2;
170 struct pxa_gpio_softc *sc;
172 sc = (struct pxa_gpio_softc *)arg;
174 gedr0 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0);
176 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, gedr0);
178 gedr1 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1);
179 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, gedr1);
181 gedr2 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2);
183 bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, gedr2);
185 sc->pg_intr[0] |= gedr0;
186 sc->pg_intr[1] |= gedr1;
187 sc->pg_intr[2] |= gedr2;
189 return (FILTER_HANDLED);
192 static device_method_t pxa_gpio_methods[] = {
193 DEVMETHOD(device_probe, pxa_gpio_probe),
194 DEVMETHOD(device_attach, pxa_gpio_attach),
199 static driver_t pxa_gpio_driver = {
202 sizeof(struct pxa_gpio_softc),
205 static devclass_t pxa_gpio_devclass;
207 DRIVER_MODULE(pxagpio, pxa, pxa_gpio_driver, pxa_gpio_devclass, 0, 0);
209 #define pxagpio_reg_read(softc, reg) \
210 bus_space_read_4(sc->pg_bst, sc->pg_bsh, reg)
211 #define pxagpio_reg_write(softc, reg, val) \
212 bus_space_write_4(sc->pg_bst, sc->pg_bsh, reg, val)
215 pxa_gpio_get_function(int gpio)
217 struct pxa_gpio_softc *sc;
222 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
225 io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio));
226 if (io & GPIO_BIT(gpio))
229 io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPLR0, gpio));
230 if (io & GPIO_BIT(gpio))
237 pxa_gpio_set_function(int gpio, uint32_t fn)
239 struct pxa_gpio_softc *sc;
240 uint32_t rv, bit, oldfn;
244 oldfn = pxa_gpio_get_function(gpio);
246 if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
247 GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
249 * The pin's function is not changing.
250 * For Alternate Functions and GPIO input, we can just
252 * For GPIO output pins, check the initial state is
255 * Return 'fn' instead of 'oldfn' so the caller can
256 * reliably detect that we didn't change anything.
257 * (The initial state might be different for non-
260 if (!GPIO_IS_GPIO_OUT(fn) ||
261 GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
266 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
267 * the correct procedure for changing GPIO pin functions.
270 bit = GPIO_BIT(gpio);
273 * 1. Configure the correct set/clear state of the pin
275 if (GPIO_FN_IS_SET(fn))
276 pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPSR0, gpio), bit);
278 pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPCR0, gpio), bit);
281 * 2. Configure the pin as an input or output as appropriate
283 rv = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
284 if (GPIO_FN_IS_OUT(fn))
286 pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio), rv);
289 * 3. Configure the pin's function
291 bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
292 fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
293 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
294 pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
300 * GPIO "interrupt" handling.
304 pxa_gpio_mask_irq(int irq)
307 struct pxa_gpio_softc *sc;
311 gpio = IRQ_TO_GPIO(irq);
313 val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
314 val &= ~GPIO_BIT(gpio);
315 pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
319 pxa_gpio_unmask_irq(int irq)
322 struct pxa_gpio_softc *sc;
326 gpio = IRQ_TO_GPIO(irq);
328 val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
329 val |= GPIO_BIT(gpio);
330 pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
334 pxa_gpio_get_next_irq()
336 struct pxa_gpio_softc *sc;
341 if (sc->pg_intr[0] != 0) {
342 gpio = ffs(sc->pg_intr[0]) - 1;
343 sc->pg_intr[0] &= ~(1 << gpio);
344 return (GPIO_TO_IRQ(gpio));
346 if (sc->pg_intr[1] != 0) {
347 gpio = ffs(sc->pg_intr[1]) - 1;
348 sc->pg_intr[1] &= ~(1 << gpio);
349 return (GPIO_TO_IRQ(gpio + 32));
351 if (sc->pg_intr[2] != 0) {
352 gpio = ffs(sc->pg_intr[2]) - 1;
353 sc->pg_intr[2] &= ~(1 << gpio);
354 return (GPIO_TO_IRQ(gpio + 64));