Home | History | Annotate | Line # | Download | only in xscale
pxa2x0_gpio.c revision 1.16
      1 /*	$NetBSD: pxa2x0_gpio.c,v 1.16 2012/11/12 18:00:38 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright 2003 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Steve C. Woodford for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_gpio.c,v 1.16 2012/11/12 18:00:38 skrll Exp $");
     40 
     41 #include "opt_pxa2x0_gpio.h"
     42 
     43 #include <sys/param.h>
     44 #include <sys/systm.h>
     45 #include <sys/device.h>
     46 #include <sys/malloc.h>
     47 
     48 #include <machine/intr.h>
     49 #include <sys/bus.h>
     50 
     51 #include <arm/xscale/pxa2x0cpu.h>
     52 #include <arm/xscale/pxa2x0reg.h>
     53 #include <arm/xscale/pxa2x0var.h>
     54 #include <arm/xscale/pxa2x0_gpio.h>
     55 
     56 #include "locators.h"
     57 
     58 struct gpio_irq_handler {
     59 	struct gpio_irq_handler *gh_next;
     60 	int (*gh_func)(void *);
     61 	void *gh_arg;
     62 	int gh_spl;
     63 	u_int gh_gpio;
     64 	int gh_level;
     65 };
     66 
     67 struct pxagpio_softc {
     68 	device_t sc_dev;
     69 	bus_space_tag_t sc_bust;
     70 	bus_space_handle_t sc_bush;
     71 	void *sc_irqcookie[4];
     72 	uint32_t sc_mask[4];
     73 #ifdef PXAGPIO_HAS_GPION_INTRS
     74 	struct gpio_irq_handler *sc_handlers[GPIO_NPINS];
     75 #else
     76 	struct gpio_irq_handler *sc_handlers[2];
     77 #endif
     78 };
     79 
     80 static int	pxagpio_match(device_t, cfdata_t, void *);
     81 static void	pxagpio_attach(device_t, device_t, void *);
     82 
     83 CFATTACH_DECL_NEW(pxagpio, sizeof(struct pxagpio_softc),
     84     pxagpio_match, pxagpio_attach, NULL, NULL);
     85 
     86 static struct pxagpio_softc *pxagpio_softc;
     87 static vaddr_t pxagpio_regs;
     88 #define GPIO_BOOTSTRAP_REG(reg)	\
     89 	(*((volatile uint32_t *)(pxagpio_regs + (reg))))
     90 
     91 static int gpio_intr0(void *);
     92 static int gpio_intr1(void *);
     93 #ifdef PXAGPIO_HAS_GPION_INTRS
     94 static int gpio_dispatch(struct pxagpio_softc *, int);
     95 static int gpio_intrN(void *);
     96 #endif
     97 
     98 static inline uint32_t
     99 pxagpio_reg_read(struct pxagpio_softc *sc, int reg)
    100 {
    101 	if (__predict_true(sc != NULL))
    102 		return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg));
    103 	else
    104 	if (pxagpio_regs)
    105 		return (GPIO_BOOTSTRAP_REG(reg));
    106 	panic("pxagpio_reg_read: not bootstrapped");
    107 }
    108 
    109 static inline void
    110 pxagpio_reg_write(struct pxagpio_softc *sc, int reg, uint32_t val)
    111 {
    112 	if (__predict_true(sc != NULL))
    113 		bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
    114 	else
    115 	if (pxagpio_regs)
    116 		GPIO_BOOTSTRAP_REG(reg) = val;
    117 	else
    118 		panic("pxagpio_reg_write: not bootstrapped");
    119 	return;
    120 }
    121 
    122 static int
    123 pxagpio_match(device_t parent, cfdata_t cf, void *aux)
    124 {
    125 	struct pxaip_attach_args *pxa = aux;
    126 
    127 	if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE)
    128 		return (0);
    129 
    130 	pxa->pxa_size = PXA2X0_GPIO_SIZE;
    131 
    132 	return (1);
    133 }
    134 
    135 static void
    136 pxagpio_attach(device_t parent, device_t self, void *aux)
    137 {
    138 	struct pxagpio_softc *sc = device_private(self);
    139 	struct pxaip_attach_args *pxa = aux;
    140 
    141 	sc->sc_dev = self;
    142 	sc->sc_bust = pxa->pxa_iot;
    143 
    144 	aprint_normal(": GPIO Controller\n");
    145 
    146 	if (bus_space_map(sc->sc_bust, pxa->pxa_addr, pxa->pxa_size, 0,
    147 	    &sc->sc_bush)) {
    148 		aprint_error_dev(self, "Can't map registers!\n");
    149 		return;
    150 	}
    151 
    152 	pxagpio_regs = (vaddr_t)bus_space_vaddr(sc->sc_bust, sc->sc_bush);
    153 
    154 	memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));
    155 
    156 	/*
    157 	 * Disable all GPIO interrupts
    158 	 */
    159 	pxagpio_reg_write(sc, GPIO_GRER0, 0);
    160 	pxagpio_reg_write(sc, GPIO_GRER1, 0);
    161 	pxagpio_reg_write(sc, GPIO_GRER2, 0);
    162 	pxagpio_reg_write(sc, GPIO_GFER0, 0);
    163 	pxagpio_reg_write(sc, GPIO_GFER1, 0);
    164 	pxagpio_reg_write(sc, GPIO_GFER2, 0);
    165 	pxagpio_reg_write(sc, GPIO_GEDR0, ~0);
    166 	pxagpio_reg_write(sc, GPIO_GEDR1, ~0);
    167 	pxagpio_reg_write(sc, GPIO_GEDR2, ~0);
    168 #ifdef	CPU_XSCALE_PXA270
    169 	if (CPU_IS_PXA270) {
    170 		pxagpio_reg_write(sc, GPIO_GRER3, 0);
    171 		pxagpio_reg_write(sc, GPIO_GFER3, 0);
    172 		pxagpio_reg_write(sc, GPIO_GEDR3, ~0);
    173 	}
    174 #endif
    175 
    176 #ifdef PXAGPIO_HAS_GPION_INTRS
    177 	sc->sc_irqcookie[2] = pxa2x0_intr_establish(PXA2X0_INT_GPION, IPL_BIO,
    178 	    gpio_intrN, sc);
    179 	if (sc->sc_irqcookie[2] == NULL) {
    180 		aprint_error_dev(self, "failed to hook main GPIO interrupt\n");
    181 		return;
    182 	}
    183 #endif
    184 
    185 	sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;
    186 
    187 	pxagpio_softc = sc;
    188 }
    189 
    190 void
    191 pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
    192 {
    193 
    194 	pxagpio_regs = gpio_regs;
    195 }
    196 
    197 void *
    198 pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),
    199     void *arg)
    200 {
    201 	struct pxagpio_softc *sc = pxagpio_softc;
    202 	struct gpio_irq_handler *gh;
    203 	uint32_t bit, reg;
    204 
    205 #ifdef PXAGPIO_HAS_GPION_INTRS
    206 	if (gpio >= GPIO_NPINS)
    207 		panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
    208 #else
    209 	if (gpio > 1)
    210 		panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
    211 #endif
    212 
    213 	if (!GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(gpio)))
    214 		panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio);
    215 
    216 	switch (level) {
    217 	case IST_EDGE_FALLING:
    218 	case IST_EDGE_RISING:
    219 	case IST_EDGE_BOTH:
    220 		break;
    221 
    222 	default:
    223 		panic("pxa2x0_gpio_intr_establish: bad level: %d", level);
    224 		break;
    225 	}
    226 
    227 	if (sc->sc_handlers[gpio] != NULL)
    228 		panic("pxa2x0_gpio_intr_establish: illegal shared interrupt");
    229 
    230 	gh = malloc(sizeof(struct gpio_irq_handler), M_DEVBUF, M_NOWAIT);
    231 
    232 	gh->gh_func = func;
    233 	gh->gh_arg = arg;
    234 	gh->gh_spl = spl;
    235 	gh->gh_gpio = gpio;
    236 	gh->gh_level = level;
    237 	gh->gh_next = sc->sc_handlers[gpio];
    238 	sc->sc_handlers[gpio] = gh;
    239 
    240 	if (gpio == 0) {
    241 		KDASSERT(sc->sc_irqcookie[0] == NULL);
    242 		sc->sc_irqcookie[0] = pxa2x0_intr_establish(PXA2X0_INT_GPIO0,
    243 		    spl, gpio_intr0, sc);
    244 		KDASSERT(sc->sc_irqcookie[0]);
    245 	} else
    246 	if (gpio == 1) {
    247 		KDASSERT(sc->sc_irqcookie[1] == NULL);
    248 		sc->sc_irqcookie[1] = pxa2x0_intr_establish(PXA2X0_INT_GPIO1,
    249 		    spl, gpio_intr1, sc);
    250 		KDASSERT(sc->sc_irqcookie[1]);
    251 	}
    252 
    253 	bit = GPIO_BIT(gpio);
    254 	sc->sc_mask[GPIO_BANK(gpio)] |= bit;
    255 
    256 	switch (level) {
    257 	case IST_EDGE_FALLING:
    258 		reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
    259 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
    260 		break;
    261 
    262 	case IST_EDGE_RISING:
    263 		reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
    264 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
    265 		break;
    266 
    267 	case IST_EDGE_BOTH:
    268 		reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
    269 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
    270 		reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
    271 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
    272 		break;
    273 	}
    274 
    275 	return (gh);
    276 }
    277 
    278 void
    279 pxa2x0_gpio_intr_disestablish(void *cookie)
    280 {
    281 	struct pxagpio_softc *sc = pxagpio_softc;
    282 	struct gpio_irq_handler *gh = cookie;
    283 	uint32_t bit, reg;
    284 
    285 	bit = GPIO_BIT(gh->gh_gpio);
    286 
    287 	reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio));
    288 	reg &= ~bit;
    289 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio), reg);
    290 	reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio));
    291 	reg &= ~bit;
    292 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio), reg);
    293 
    294 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit);
    295 
    296 	sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit;
    297 	sc->sc_handlers[gh->gh_gpio] = NULL;
    298 
    299 	if (gh->gh_gpio == 0) {
    300 #if 0
    301 		pxa2x0_intr_disestablish(sc->sc_irqcookie[0]);
    302 		sc->sc_irqcookie[0] = NULL;
    303 #else
    304 		panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#0");
    305 #endif
    306 	} else
    307 	if (gh->gh_gpio == 1) {
    308 #if 0
    309 		pxa2x0_intr_disestablish(sc->sc_irqcookie[1]);
    310 		sc->sc_irqcookie[1] = NULL;
    311 #else
    312 		panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#1");
    313 #endif
    314 	}
    315 
    316 	free(gh, M_DEVBUF);
    317 }
    318 
    319 static int
    320 gpio_intr0(void *arg)
    321 {
    322 	struct pxagpio_softc *sc = arg;
    323 
    324 #ifdef DIAGNOSTIC
    325 	if (sc->sc_handlers[0] == NULL) {
    326 		aprint_error_dev(sc->sc_dev, "stray GPIO#0 edge interrupt\n");
    327 		return (0);
    328 	}
    329 #endif
    330 
    331 	bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0),
    332 	    GPIO_BIT(0));
    333 
    334 	return ((sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg));
    335 }
    336 
    337 static int
    338 gpio_intr1(void *arg)
    339 {
    340 	struct pxagpio_softc *sc = arg;
    341 
    342 #ifdef DIAGNOSTIC
    343 	if (sc->sc_handlers[1] == NULL) {
    344 		aprint_error_dev(sc->sc_dev, "stray GPIO#1 edge interrupt\n");
    345 		return (0);
    346 	}
    347 #endif
    348 
    349 	bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1),
    350 	    GPIO_BIT(1));
    351 
    352 	return ((sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg));
    353 }
    354 
    355 #ifdef PXAGPIO_HAS_GPION_INTRS
    356 static int
    357 gpio_dispatch(struct pxagpio_softc *sc, int gpio_base)
    358 {
    359 	struct gpio_irq_handler **ghp, *gh;
    360 	int i, s, nhandled, handled, pins;
    361 	uint32_t gedr, mask;
    362 	int bank;
    363 
    364 	/* Fetch bitmap of pending interrupts on this GPIO bank */
    365 	gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base));
    366 
    367 	/* Don't handle GPIO 0/1 here */
    368 	if (gpio_base == 0)
    369 		gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1));
    370 
    371 	/* Bail early if there are no pending interrupts in this bank */
    372 	if (gedr == 0)
    373 		return (0);
    374 
    375 	/* Acknowledge pending interrupts. */
    376 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr);
    377 
    378 	bank = GPIO_BANK(gpio_base);
    379 
    380 	/*
    381 	 * We're only interested in those for which we have a handler
    382 	 * registered
    383 	 */
    384 #ifdef DEBUG
    385 	if ((gedr & sc->sc_mask[bank]) == 0) {
    386 		aprint_error_dev(sc->sc_dev,
    387 		    "stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n",
    388 		    bank, gedr, sc->sc_mask[bank]);
    389 		return (1);	/* XXX: Pretend we dealt with it */
    390 	}
    391 #endif
    392 
    393 	gedr &= sc->sc_mask[bank];
    394 	ghp = &sc->sc_handlers[gpio_base];
    395 	if (CPU_IS_PXA270)
    396 		pins = (gpio_base < 96) ? 32 : 25;
    397 	else
    398 		pins = (gpio_base < 64) ? 32 : 17;
    399 	handled = 0;
    400 
    401 	for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) {
    402 		if ((gedr & mask) == 0)
    403 			continue;
    404 		gedr &= ~mask;
    405 
    406 		if ((gh = *ghp) == NULL) {
    407 			aprint_error_dev(sc->sc_dev,
    408 			    "unhandled GPIO interrupt. GPIO#%d\n",
    409 			    gpio_base + i);
    410 			continue;
    411 		}
    412 
    413 		s = _splraise(gh->gh_spl);
    414 		do {
    415 			nhandled = (gh->gh_func)(gh->gh_arg);
    416 			handled |= nhandled;
    417 			gh = gh->gh_next;
    418 		} while (gh != NULL);
    419 		splx(s);
    420 	}
    421 
    422 	return (handled);
    423 }
    424 
    425 static int
    426 gpio_intrN(void *arg)
    427 {
    428 	struct pxagpio_softc *sc = arg;
    429 	int handled;
    430 
    431 	handled = gpio_dispatch(sc, 0);
    432 	handled |= gpio_dispatch(sc, 32);
    433 	handled |= gpio_dispatch(sc, 64);
    434 	if (CPU_IS_PXA270)
    435 		handled |= gpio_dispatch(sc, 96);
    436 	return (handled);
    437 }
    438 #endif	/* PXAGPIO_HAS_GPION_INTRS */
    439 
    440 u_int
    441 pxa2x0_gpio_get_function(u_int gpio)
    442 {
    443 	struct pxagpio_softc *sc = pxagpio_softc;
    444 	uint32_t rv, io;
    445 
    446 	KDASSERT(gpio < GPIO_NPINS);
    447 
    448 	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
    449 	rv = GPIO_FN(rv);
    450 
    451 	io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio));
    452 	if (io & GPIO_BIT(gpio))
    453 		rv |= GPIO_OUT;
    454 
    455 	io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio));
    456 	if (io & GPIO_BIT(gpio))
    457 		rv |= GPIO_SET;
    458 
    459 	return (rv);
    460 }
    461 
    462 u_int
    463 pxa2x0_gpio_set_function(u_int gpio, u_int fn)
    464 {
    465 	struct pxagpio_softc *sc = pxagpio_softc;
    466 	uint32_t rv, bit;
    467 	u_int oldfn;
    468 
    469 	KDASSERT(gpio < GPIO_NPINS);
    470 
    471 	oldfn = pxa2x0_gpio_get_function(gpio);
    472 
    473 	if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
    474 	    GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
    475 		/*
    476 		 * The pin's function is not changing.
    477 		 * For Alternate Functions and GPIO input, we can just
    478 		 * return now.
    479 		 * For GPIO output pins, check the initial state is
    480 		 * the same.
    481 		 *
    482 		 * Return 'fn' instead of 'oldfn' so the caller can
    483 		 * reliably detect that we didn't change anything.
    484 		 * (The initial state might be different for non-
    485 		 * GPIO output pins).
    486 		 */
    487 		if (!GPIO_IS_GPIO_OUT(fn) ||
    488 		    GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
    489 			return (fn);
    490 	}
    491 
    492 	/*
    493 	 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
    494 	 * the correct procedure for changing GPIO pin functions.
    495 	 */
    496 
    497 	bit = GPIO_BIT(gpio);
    498 
    499 	/*
    500 	 * 1. Configure the correct set/clear state of the pin
    501 	 */
    502 	if (GPIO_FN_IS_SET(fn))
    503 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
    504 	else
    505 		pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
    506 
    507 	/*
    508 	 * 2. Configure the pin as an input or output as appropriate
    509 	 */
    510 	rv = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
    511 	if (GPIO_FN_IS_OUT(fn))
    512 		rv |= bit;
    513 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), rv);
    514 
    515 	/*
    516 	 * 3. Configure the pin's function
    517 	 */
    518 	bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
    519 	fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
    520 	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
    521 	pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
    522 
    523 	return (oldfn);
    524 }
    525 
    526 /*
    527  * Quick function to read pin value
    528  */
    529 int
    530 pxa2x0_gpio_get_bit(u_int gpio)
    531 {
    532 	struct pxagpio_softc *sc = pxagpio_softc;
    533 	int bit;
    534 
    535 	bit = GPIO_BIT(gpio);
    536 	if (pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio)) & bit)
    537 		return 1;
    538 	else
    539 		return 0;
    540 }
    541 
    542 /*
    543  * Quick function to set pin to 1
    544  */
    545 void
    546 pxa2x0_gpio_set_bit(u_int gpio)
    547 {
    548 	struct pxagpio_softc *sc = pxagpio_softc;
    549 	int bit;
    550 
    551 	bit = GPIO_BIT(gpio);
    552 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
    553 }
    554 
    555 /*
    556  * Quick function to set pin to 0
    557  */
    558 void
    559 pxa2x0_gpio_clear_bit(u_int gpio)
    560 {
    561 	struct pxagpio_softc *sc = pxagpio_softc;
    562 	int bit;
    563 
    564 	bit = GPIO_BIT(gpio);
    565 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
    566 }
    567 
    568 /*
    569  * Quick function to change pin direction
    570  */
    571 void
    572 pxa2x0_gpio_set_dir(u_int gpio, int dir)
    573 {
    574 	struct pxagpio_softc *sc = pxagpio_softc;
    575 	int bit;
    576 	uint32_t reg;
    577 
    578 	bit = GPIO_BIT(gpio);
    579 
    580 	reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
    581 	if (GPIO_FN_IS_OUT(dir))
    582 		reg |= bit;
    583 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), reg);
    584 }
    585 
    586 /*
    587  * Quick function to clear interrupt status on a pin
    588  * GPIO pins may be toggle in an interrupt and we dont want
    589  * extra spurious interrupts to occur.
    590  * Suppose this causes a slight race if a key is pressed while
    591  * the interrupt handler is running. (yes this is for the keyboard driver)
    592  */
    593 void
    594 pxa2x0_gpio_clear_intr(u_int gpio)
    595 {
    596 	struct pxagpio_softc *sc = pxagpio_softc;
    597 	int bit;
    598 
    599 	bit = GPIO_BIT(gpio);
    600 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio), bit);
    601 }
    602 
    603 /*
    604  * Quick function to mask (disable) a GPIO interrupt
    605  */
    606 void
    607 pxa2x0_gpio_intr_mask(void *v)
    608 {
    609 	struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
    610 
    611 	pxa2x0_gpio_set_intr_level(gh->gh_gpio, IPL_NONE);
    612 }
    613 
    614 /*
    615  * Quick function to unmask (enable) a GPIO interrupt
    616  */
    617 void
    618 pxa2x0_gpio_intr_unmask(void *v)
    619 {
    620 	struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
    621 
    622 	pxa2x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level);
    623 }
    624 
    625 /*
    626  * Configure the edge sensitivity of interrupt pins
    627  */
    628 void
    629 pxa2x0_gpio_set_intr_level(u_int gpio, int level)
    630 {
    631 	struct pxagpio_softc *sc = pxagpio_softc;
    632 	uint32_t bit;
    633 	uint32_t gfer;
    634 	uint32_t grer;
    635 	int s;
    636 
    637 	s = splhigh();
    638 
    639 	bit = GPIO_BIT(gpio);
    640 	gfer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
    641 	grer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
    642 
    643 	switch (level) {
    644 	case IST_NONE:
    645 		gfer &= ~bit;
    646 		grer &= ~bit;
    647 		break;
    648 	case IST_EDGE_FALLING:
    649 		gfer |= bit;
    650 		grer &= ~bit;
    651 		break;
    652 	case IST_EDGE_RISING:
    653 		gfer &= ~bit;
    654 		grer |= bit;
    655 		break;
    656 	case IST_EDGE_BOTH:
    657 		gfer |= bit;
    658 		grer |= bit;
    659 		break;
    660 	default:
    661 		panic("pxa2x0_gpio_set_intr_level: bad level: %d", level);
    662 		break;
    663 	}
    664 
    665 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), gfer);
    666 	pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), grer);
    667 
    668 	splx(s);
    669 }
    670 
    671 
    672 #if defined(CPU_XSCALE_PXA250)
    673 /*
    674  * Configurations of GPIO for PXA25x
    675  */
    676 struct pxa2x0_gpioconf pxa25x_com_btuart_gpioconf[] = {
    677 	{ 42, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BTRXD */
    678 	{ 43, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* BTTXD */
    679 
    680 #if 0	/* optional */
    681 	{ 44, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BTCTS */
    682 	{ 45, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* BTRTS */
    683 #endif
    684 
    685 	{ -1 }
    686 };
    687 
    688 struct pxa2x0_gpioconf pxa25x_com_ffuart_gpioconf[] = {
    689 	{ 34, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    690 
    691 #if 0	/* optional */
    692 	{ 35, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* CTS */
    693 	{ 36, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* DCD */
    694 	{ 37, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* DSR */
    695 	{ 38, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* RI */
    696 #endif
    697 
    698 	{ 39, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* FFTXD */
    699 
    700 #if 0	/* optional */
    701 	{ 40, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* DTR */
    702 	{ 41, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* RTS */
    703 #endif
    704 
    705 	{ -1 }
    706 };
    707 
    708 struct pxa2x0_gpioconf pxa25x_com_hwuart_gpioconf[] = {
    709 #if 0	/* We can select and/or. */
    710 	{ 42, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* HWRXD */
    711 	{ 49, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* HWRXD */
    712 
    713 	{ 43, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* HWTXD */
    714 	{ 48, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* HWTXD */
    715 
    716 #if 0	/* optional */
    717 	{ 44, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* HWCST */
    718 	{ 51, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* HWCST */
    719 
    720 	{ 45, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* HWRST */
    721 	{ 52, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* HWRST */
    722 #endif
    723 #endif
    724 
    725 	{ -1 }
    726 };
    727 
    728 struct pxa2x0_gpioconf pxa25x_com_stuart_gpioconf[] = {
    729 	{ 46, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* RXD */
    730 	{ 47, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* TXD */
    731 	{ -1 }
    732 };
    733 
    734 struct pxa2x0_gpioconf pxa25x_i2c_gpioconf[] = {
    735 	{ -1 }
    736 };
    737 
    738 struct pxa2x0_gpioconf pxa25x_i2s_gpioconf[] = {
    739 	{ 28, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* BITCLK */
    740 	{ 29, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* SDATA_IN */
    741 	{ 30, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* SDATA_OUT */
    742 	{ 31, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* SYNC */
    743 	{ 32, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* SYSCLK */
    744 	{ -1 }
    745 };
    746 
    747 struct pxa2x0_gpioconf pxa25x_pcic_gpioconf[] = {
    748 	{ 48, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPOE */
    749 	{ 49, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPWE */
    750 	{ 50, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPIOR */
    751 	{ 51, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPIOW */
    752 
    753 #if 0	/* We can select and/or. */
    754 	{ 52, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPCE1 */
    755 	{ 53, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPCE2 */
    756 #endif
    757 
    758 	{ 54, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* pSKTSEL */
    759 	{ 55, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPREG */
    760 	{ 56, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* nPWAIT */
    761 	{ 57, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* nIOIS16 */
    762 	{ -1 }
    763 };
    764 
    765 struct pxa2x0_gpioconf pxa25x_pxaacu_gpioconf[] = {
    766 	{ 28, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BITCLK */
    767 	{ 30, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* SDATA_OUT */
    768 	{ 31, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* SYNC */
    769 
    770 #if 0	/* We can select and/or. */
    771 	{ 29, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
    772 	{ 32, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SDATA_IN1 */
    773 #endif
    774 
    775 	{ -1 }
    776 };
    777 
    778 struct pxa2x0_gpioconf pxa25x_pxamci_gpioconf[] = {
    779 #if 0	/* We can select and/or. */
    780 	{  6, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCLK */
    781 	{ 53, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCLK */
    782 	{ 54, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCLK */
    783 
    784 	{  8, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCS0 */
    785 	{ 34, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* MMCCS0 */
    786 	{ 67, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCS0 */
    787 
    788 	{  9, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCS1 */
    789 	{ 39, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCS1 */
    790 	{ 68, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* MMCCS1 */
    791 #endif
    792 
    793 	{  -1 }
    794 };
    795 #endif
    796 
    797 #if defined(CPU_XSCALE_PXA270)
    798 /*
    799  * Configurations of GPIO for PXA27x
    800  */
    801 struct pxa2x0_gpioconf pxa27x_com_btuart_gpioconf[] = {
    802 	{  42, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BTRXD */
    803 	{  43, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* BTTXD */
    804 
    805 #if 0	/* optional */
    806 	{  44, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BTCTS */
    807 	{  45, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* BTRTS */
    808 #endif
    809 
    810 	{  -1 }
    811 };
    812 
    813 struct pxa2x0_gpioconf pxa27x_com_ffuart_gpioconf[] = {
    814 #if 0	/* We can select and/or. */
    815 	{  16, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFTXD */
    816 	{  37, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFTXD */
    817 	{  39, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* FFTXD */
    818 	{  83, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* FFTXD */
    819 	{  99, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFTXD */
    820 
    821 	{  19, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFRXD */
    822 	{  33, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    823 	{  34, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    824 	{  41, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    825 	{  53, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    826 	{  85, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRXD */
    827 	{  96, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFRXD */
    828 	{ 102, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFRXD */
    829 
    830 	{   9, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFCTS */
    831 	{  26, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFCTS */
    832 	{  35, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFCTS */
    833 	{ 100, GPIO_CLR | GPIO_ALT_FN_3_IN },	/* FFCTS */
    834 
    835 	{  27, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFRTS */
    836 	{  41, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* FFRTS */
    837 	{  83, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFRTS */
    838 	{  98, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFRTS */
    839 
    840 	{  40, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* FFDTR */
    841 	{  82, GPIO_CLR | GPIO_ALT_FN_3_OUT },	/* FFDTR */
    842 
    843 	{  36, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFDCD */
    844 
    845 	{  33, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* FFDSR */
    846 	{  37, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFDSR */
    847 
    848 	{  38, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* FFRI */
    849 #endif
    850 	{  -1 }
    851 };
    852 
    853 struct pxa2x0_gpioconf pxa27x_com_stuart_gpioconf[] = {
    854 	{  46, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* STD_RXD */
    855 	{  47, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* STD_TXD */
    856 	{  -1 }
    857 };
    858 
    859 struct pxa2x0_gpioconf pxa27x_i2c_gpioconf[] = {
    860 	{ 117, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SCL */
    861 	{ 118, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SDA */
    862 	{  -1 }
    863 };
    864 
    865 struct pxa2x0_gpioconf pxa27x_i2s_gpioconf[] = {
    866 	{  28, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* I2S_BITCLK */
    867 	{  29, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* I2S_SDATA_IN */
    868 	{  30, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* I2S_SDATA_OUT */
    869 	{  31, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* I2S_SYNC */
    870 	{ 113, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* I2S_SYSCLK */
    871 	{  -1 }
    872 };
    873 
    874 struct pxa2x0_gpioconf pxa27x_ohci_gpioconf[] = {
    875 #if 0	/* We can select and/or. */
    876 	{  88, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* USBHPWR1 */
    877 	{  89, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* USBHPEN1 */
    878 	{ 119, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* USBHPWR2 */
    879 	{ 120, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* USBHPEN2 */
    880 #endif
    881 	{  -1 }
    882 };
    883 
    884 struct pxa2x0_gpioconf pxa27x_pcic_gpioconf[] = {
    885 	{  48, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPOE */
    886 	{  49, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPWE */
    887 	{  50, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPIOR */
    888 	{  51, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPIOW */
    889 	{  55, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPREG */
    890 	{  56, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* nPWAIT */
    891 	{  57, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* nIOIS16 */
    892 
    893 #if 0	/* We can select and/or. */
    894 	{  85, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* nPCE1 */
    895 	{  86, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* nPCE1 */
    896 	{ 102, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* nPCE1 */
    897 
    898 	{  54, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* nPCE2 */
    899 	{  78, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* nPCE2 */
    900 	{ 105, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* nPCE2 */
    901 
    902 	{  79, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* pSKTSEL */
    903 	{ 104, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* pSKTSEL */
    904 #endif
    905 
    906 	{  -1 }
    907 };
    908 
    909 struct pxa2x0_gpioconf pxa27x_pxaacu_gpioconf[] = {
    910 	{  28, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* BITCLK */
    911 	{  30, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* SDATA_OUT */
    912 
    913 #if 0	/* We can select and/or. */
    914 	{  31, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* SYNC */
    915 	{  94, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* SYNC */
    916 
    917 	{  29, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
    918 	{ 116, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* SDATA_IN0 */
    919 
    920 	{  32, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* SDATA_IN1 */
    921 	{  99, GPIO_CLR | GPIO_ALT_FN_2_IN },	/* SDATA_IN1 */
    922 
    923 	{  95, GPIO_CLR | GPIO_ALT_FN_1_OUT },	/* RESET_n */
    924 	{ 113, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* RESET_n */
    925 #endif
    926 
    927 	{  -1 }
    928 };
    929 
    930 struct pxa2x0_gpioconf pxa27x_pxamci_gpioconf[] = {
    931 	{  32, GPIO_CLR | GPIO_ALT_FN_2_OUT },	/* MMCLK */
    932 	{  92, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* MMDAT<0> */
    933 	{ 109, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* MMDAT<1> */
    934 	{ 110, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* MMDAT<2>/MMCCS<0> */
    935 	{ 111, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* MMDAT<3>/MMCCS<1> */
    936 	{ 112, GPIO_CLR | GPIO_ALT_FN_1_IN },	/* MMCMD */
    937 
    938 	{  -1 }
    939 };
    940 #endif
    941 
    942 void
    943 pxa2x0_gpio_config(struct pxa2x0_gpioconf **conflist)
    944 {
    945 	int i, j;
    946 
    947 	for (i = 0; conflist[i] != NULL; i++)
    948 		for (j = 0; conflist[i][j].pin != -1; j++)
    949 			pxa2x0_gpio_set_function(conflist[i][j].pin,
    950 			    conflist[i][j].value);
    951 }
    952