pxa2x0_gpio.c revision 1.16 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