No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / arm / xscale / pxa2x0_gpio.c
blob67d8199095af8677895a85b54e6ecb8c05898bd6
1 /* $NetBSD: pxa2x0_gpio.c,v 1.12 2008/12/17 20:51:32 cegger Exp $ */
3 /*
4 * Copyright 2003 Wasabi Systems, Inc.
5 * All rights reserved.
7 * Written by Steve C. Woodford for Wasabi Systems, Inc.
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.
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.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_gpio.c,v 1.12 2008/12/17 20:51:32 cegger Exp $");
41 #include "opt_pxa2x0_gpio.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46 #include <sys/malloc.h>
48 #include <machine/intr.h>
49 #include <machine/bus.h>
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>
56 #include "locators.h"
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;
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
80 static int pxagpio_match(struct device *, struct cfdata *, void *);
81 static void pxagpio_attach(struct device *, struct device *, void *);
83 CFATTACH_DECL(pxagpio, sizeof(struct pxagpio_softc),
84 pxagpio_match, pxagpio_attach, NULL, NULL);
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))))
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
98 static inline u_int32_t
99 pxagpio_reg_read(struct pxagpio_softc *sc, int reg)
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");
109 static inline void
110 pxagpio_reg_write(struct pxagpio_softc *sc, int reg, u_int32_t val)
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;
122 static int
123 pxagpio_match(struct device *parent, struct cfdata *cf, void *aux)
125 struct pxaip_attach_args *pxa = aux;
127 if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE)
128 return (0);
130 pxa->pxa_size = PXA2X0_GPIO_SIZE;
132 return (1);
135 static void
136 pxagpio_attach(struct device *parent, struct device *self, void *aux)
138 struct pxagpio_softc *sc = (struct pxagpio_softc *)self;
139 struct pxaip_attach_args *pxa = aux;
141 sc->sc_bust = pxa->pxa_iot;
143 aprint_normal(": GPIO Controller\n");
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;
151 pxagpio_regs = (vaddr_t)bus_space_vaddr(sc->sc_bust, sc->sc_bush);
153 memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));
156 * Disable all GPIO interrupts
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);
173 #endif
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;
183 #endif
185 sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;
187 pxagpio_softc = sc;
190 void
191 pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
194 pxagpio_regs = gpio_regs;
197 void *
198 pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),
199 void *arg)
201 struct pxagpio_softc *sc = pxagpio_softc;
202 struct gpio_irq_handler *gh;
203 u_int32_t bit, reg;
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
213 if (!GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(gpio)))
214 panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio);
216 switch (level) {
217 case IST_EDGE_FALLING:
218 case IST_EDGE_RISING:
219 case IST_EDGE_BOTH:
220 break;
222 default:
223 panic("pxa2x0_gpio_intr_establish: bad level: %d", level);
224 break;
227 if (sc->sc_handlers[gpio] != NULL)
228 panic("pxa2x0_gpio_intr_establish: illegal shared interrupt");
230 gh = malloc(sizeof(struct gpio_irq_handler), M_DEVBUF, M_NOWAIT);
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;
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]);
253 bit = GPIO_BIT(gpio);
254 sc->sc_mask[GPIO_BANK(gpio)] |= bit;
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;
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;
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;
275 return (gh);
278 void
279 pxa2x0_gpio_intr_disestablish(void *cookie)
281 struct pxagpio_softc *sc = pxagpio_softc;
282 struct gpio_irq_handler *gh = cookie;
283 u_int32_t bit, reg;
285 bit = GPIO_BIT(gh->gh_gpio);
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);
294 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit);
296 sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit;
297 sc->sc_handlers[gh->gh_gpio] = NULL;
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
316 free(gh, M_DEVBUF);
319 static int
320 gpio_intr0(void *arg)
322 struct pxagpio_softc *sc = arg;
324 #ifdef DIAGNOSTIC
325 if (sc->sc_handlers[0] == NULL) {
326 printf("%s: stray GPIO#0 edge interrupt\n",
327 sc->sc_dev.dv_xname);
328 return (0);
330 #endif
332 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0),
333 GPIO_BIT(0));
335 return ((sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg));
338 static int
339 gpio_intr1(void *arg)
341 struct pxagpio_softc *sc = arg;
343 #ifdef DIAGNOSTIC
344 if (sc->sc_handlers[1] == NULL) {
345 printf("%s: stray GPIO#1 edge interrupt\n",
346 sc->sc_dev.dv_xname);
347 return (0);
349 #endif
351 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1),
352 GPIO_BIT(1));
354 return ((sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg));
357 #ifdef PXAGPIO_HAS_GPION_INTRS
358 static int
359 gpio_dispatch(struct pxagpio_softc *sc, int gpio_base)
361 struct gpio_irq_handler **ghp, *gh;
362 int i, s, nhandled, handled, pins;
363 u_int32_t gedr, mask;
364 int bank;
366 /* Fetch bitmap of pending interrupts on this GPIO bank */
367 gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base));
369 /* Don't handle GPIO 0/1 here */
370 if (gpio_base == 0)
371 gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1));
373 /* Bail early if there are no pending interrupts in this bank */
374 if (gedr == 0)
375 return (0);
377 /* Acknowledge pending interrupts. */
378 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr);
380 bank = GPIO_BANK(gpio_base);
383 * We're only interested in those for which we have a handler
384 * registered
386 #ifdef DEBUG
387 if ((gedr & sc->sc_mask[bank]) == 0) {
388 printf("%s: stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n",
389 sc->sc_dev.dv_xname, bank, gedr, sc->sc_mask[bank]);
390 return (1); /* XXX: Pretend we dealt with it */
392 #endif
394 gedr &= sc->sc_mask[bank];
395 ghp = &sc->sc_handlers[gpio_base];
396 if (CPU_IS_PXA270)
397 pins = (gpio_base < 96) ? 32 : 25;
398 else
399 pins = (gpio_base < 64) ? 32 : 17;
400 handled = 0;
402 for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) {
403 if ((gedr & mask) == 0)
404 continue;
405 gedr &= ~mask;
407 if ((gh = *ghp) == NULL) {
408 printf("%s: unhandled GPIO interrupt. GPIO#%d\n",
409 sc->sc_dev.dv_xname, gpio_base + i);
410 continue;
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);
422 return (handled);
425 static int
426 gpio_intrN(void *arg)
428 struct pxagpio_softc *sc = arg;
429 int handled;
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);
438 #endif /* PXAGPIO_HAS_GPION_INTRS */
440 u_int
441 pxa2x0_gpio_get_function(u_int gpio)
443 struct pxagpio_softc *sc = pxagpio_softc;
444 u_int32_t rv, io;
446 KDASSERT(gpio < GPIO_NPINS);
448 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
449 rv = GPIO_FN(rv);
451 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio));
452 if (io & GPIO_BIT(gpio))
453 rv |= GPIO_OUT;
455 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio));
456 if (io & GPIO_BIT(gpio))
457 rv |= GPIO_SET;
459 return (rv);
462 u_int
463 pxa2x0_gpio_set_function(u_int gpio, u_int fn)
465 struct pxagpio_softc *sc = pxagpio_softc;
466 u_int32_t rv, bit;
467 u_int oldfn;
469 KDASSERT(gpio < GPIO_NPINS);
471 oldfn = pxa2x0_gpio_get_function(gpio);
473 if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
474 GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
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.
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).
487 if (!GPIO_IS_GPIO_OUT(fn) ||
488 GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
489 return (fn);
493 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
494 * the correct procedure for changing GPIO pin functions.
497 bit = GPIO_BIT(gpio);
500 * 1. Configure the correct set/clear state of the pin
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);
508 * 2. Configure the pin as an input or output as appropriate
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);
516 * 3. Configure the pin's function
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);
523 return (oldfn);
527 * Quick function to read pin value
530 pxa2x0_gpio_get_bit(u_int gpio)
532 struct pxagpio_softc *sc = pxagpio_softc;
533 int bit;
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;
543 * Quick function to set pin to 1
545 void
546 pxa2x0_gpio_set_bit(u_int gpio)
548 struct pxagpio_softc *sc = pxagpio_softc;
549 int bit;
551 bit = GPIO_BIT(gpio);
552 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
556 * Quick function to set pin to 0
558 void
559 pxa2x0_gpio_clear_bit(u_int gpio)
561 struct pxagpio_softc *sc = pxagpio_softc;
562 int bit;
564 bit = GPIO_BIT(gpio);
565 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
569 * Quick function to change pin direction
571 void
572 pxa2x0_gpio_set_dir(u_int gpio, int dir)
574 struct pxagpio_softc *sc = pxagpio_softc;
575 int bit;
576 u_int32_t reg;
578 bit = GPIO_BIT(gpio);
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);
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)
593 void
594 pxa2x0_gpio_clear_intr(u_int gpio)
596 struct pxagpio_softc *sc = pxagpio_softc;
597 int bit;
599 bit = GPIO_BIT(gpio);
600 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio), bit);
604 * Quick function to mask (disable) a GPIO interrupt
606 void
607 pxa2x0_gpio_intr_mask(void *v)
609 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
611 pxa2x0_gpio_set_intr_level(gh->gh_gpio, IPL_NONE);
615 * Quick function to unmask (enable) a GPIO interrupt
617 void
618 pxa2x0_gpio_intr_unmask(void *v)
620 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
622 pxa2x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level);
626 * Configure the edge sensitivity of interrupt pins
628 void
629 pxa2x0_gpio_set_intr_level(u_int gpio, int level)
631 struct pxagpio_softc *sc = pxagpio_softc;
632 u_int32_t bit;
633 u_int32_t gfer;
634 u_int32_t grer;
635 int s;
637 s = splhigh();
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));
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;
665 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), gfer);
666 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), grer);
668 splx(s);
672 #if defined(CPU_XSCALE_PXA250)
674 * Configurations of GPIO for PXA25x
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 */
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
685 { -1 }
688 struct pxa2x0_gpioconf pxa25x_com_ffuart_gpioconf[] = {
689 { 34, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
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
698 { 39, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */
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
705 { -1 }
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 */
713 { 43, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWTXD */
714 { 48, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* HWTXD */
716 #if 0 /* optional */
717 { 44, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */
718 { 51, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */
720 { 45, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */
721 { 52, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */
722 #endif
723 #endif
725 { -1 }
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 }
734 struct pxa2x0_gpioconf pxa25x_i2c_gpioconf[] = {
735 { -1 }
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 }
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 */
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
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 }
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 */
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
775 { -1 }
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 */
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 */
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
793 { -1 }
795 #endif
797 #if defined(CPU_XSCALE_PXA270)
799 * Configurations of GPIO for PXA27x
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 */
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
810 { -1 }
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 */
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 */
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 */
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 */
840 { 40, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFDTR */
841 { 82, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFDTR */
843 { 36, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDCD */
845 { 33, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* FFDSR */
846 { 37, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDSR */
848 { 38, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRI */
849 #endif
850 { -1 }
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 }
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 }
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 }
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 }
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 */
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 */
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 */
902 { 79, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */
903 { 104, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */
904 #endif
906 { -1 }
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 */
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 */
917 { 29, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN0 */
918 { 116, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN0 */
920 { 32, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN1 */
921 { 99, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN1 */
923 { 95, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* RESET_n */
924 { 113, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* RESET_n */
925 #endif
927 { -1 }
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 */
938 { -1 }
940 #endif
942 void
943 pxa2x0_gpio_config(struct pxa2x0_gpioconf **conflist)
945 int i, j;
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);