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