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