xref: /netbsd-src/sys/arch/arm/xscale/pxa2x0_gpio.c (revision e77448e07be3174235c13f58032a0d6d0ab7638d)
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