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