1 /* $NetBSD: pxa2x0_gpio.c,v 1.21 2021/08/07 16:18:46 thorpej 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.21 2021/08/07 16:18:46 thorpej Exp $");
40
41 #include "gpio.h"
42 #include "opt_pxa2x0_gpio.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
47 #include <sys/kmem.h>
48
49 #include <machine/intr.h>
50 #include <sys/bus.h>
51
52 #include <arm/xscale/pxa2x0cpu.h>
53 #include <arm/xscale/pxa2x0reg.h>
54 #include <arm/xscale/pxa2x0var.h>
55 #include <arm/xscale/pxa2x0_gpio.h>
56
57 #include "locators.h"
58
59 #include <sys/gpio.h>
60 #include <dev/gpio/gpiovar.h>
61
62 struct gpio_irq_handler {
63 struct gpio_irq_handler *gh_next;
64 int (*gh_func)(void *);
65 void *gh_arg;
66 int gh_spl;
67 u_int gh_gpio;
68 int gh_level;
69 };
70
71 struct pxagpio_softc {
72 device_t sc_dev;
73 bus_space_tag_t sc_bust;
74 bus_space_handle_t sc_bush;
75 void *sc_irqcookie[4];
76 uint32_t sc_mask[4];
77 #ifdef PXAGPIO_HAS_GPION_INTRS
78 struct gpio_irq_handler *sc_handlers[GPIO_NPINS];
79 #else
80 struct gpio_irq_handler *sc_handlers[2];
81 #endif
82 struct gpio_chipset_tag sc_gpio_gc;
83 gpio_pin_t sc_gpio_pins[GPIO_NPINS];
84 };
85
86 static int pxagpio_match(device_t, cfdata_t, void *);
87 static void pxagpio_attach(device_t, device_t, void *);
88
89 #if NGPIO > 0
90 static int pxa2x0_gpio_pin_read(void *, int);
91 static void pxa2x0_gpio_pin_write(void *, int, int);
92 static void pxa2x0_gpio_pin_ctl(void *, int, int);
93 #endif
94
95 CFATTACH_DECL_NEW(pxagpio, sizeof(struct pxagpio_softc),
96 pxagpio_match, pxagpio_attach, NULL, NULL);
97
98 static struct pxagpio_softc *pxagpio_softc;
99 static vaddr_t pxagpio_regs;
100 #define GPIO_BOOTSTRAP_REG(reg) \
101 (*((volatile uint32_t *)(pxagpio_regs + (reg))))
102
103 static int gpio_intr0(void *);
104 static int gpio_intr1(void *);
105 #ifdef PXAGPIO_HAS_GPION_INTRS
106 static int gpio_dispatch(struct pxagpio_softc *, int);
107 static int gpio_intrN(void *);
108 #endif
109
110 static inline uint32_t
pxagpio_reg_read(struct pxagpio_softc * sc,int reg)111 pxagpio_reg_read(struct pxagpio_softc *sc, int reg)
112 {
113 if (__predict_true(sc != NULL))
114 return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg));
115 else
116 if (pxagpio_regs)
117 return (GPIO_BOOTSTRAP_REG(reg));
118 panic("pxagpio_reg_read: not bootstrapped");
119 }
120
121 static inline void
pxagpio_reg_write(struct pxagpio_softc * sc,int reg,uint32_t val)122 pxagpio_reg_write(struct pxagpio_softc *sc, int reg, uint32_t val)
123 {
124 if (__predict_true(sc != NULL))
125 bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
126 else
127 if (pxagpio_regs)
128 GPIO_BOOTSTRAP_REG(reg) = val;
129 else
130 panic("pxagpio_reg_write: not bootstrapped");
131 return;
132 }
133
134 static int
pxagpio_match(device_t parent,cfdata_t cf,void * aux)135 pxagpio_match(device_t parent, cfdata_t cf, void *aux)
136 {
137 struct pxaip_attach_args *pxa = aux;
138
139 if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE)
140 return (0);
141
142 pxa->pxa_size = PXA2X0_GPIO_SIZE;
143
144 return (1);
145 }
146
147 static void
pxagpio_attach(device_t parent,device_t self,void * aux)148 pxagpio_attach(device_t parent, device_t self, void *aux)
149 {
150 struct pxagpio_softc *sc = device_private(self);
151 struct pxaip_attach_args *pxa = aux;
152 #if NGPIO > 0
153 struct gpiobus_attach_args gba;
154 int pin, maxpin;
155 u_int func;
156 #endif
157
158 sc->sc_dev = self;
159 sc->sc_bust = pxa->pxa_iot;
160
161 aprint_normal(": GPIO Controller\n");
162
163 if (bus_space_map(sc->sc_bust, pxa->pxa_addr, pxa->pxa_size, 0,
164 &sc->sc_bush)) {
165 aprint_error_dev(self, "Can't map registers!\n");
166 return;
167 }
168
169 pxagpio_regs = (vaddr_t)bus_space_vaddr(sc->sc_bust, sc->sc_bush);
170
171 memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));
172
173 /*
174 * Disable all GPIO interrupts
175 */
176 pxagpio_reg_write(sc, GPIO_GRER0, 0);
177 pxagpio_reg_write(sc, GPIO_GRER1, 0);
178 pxagpio_reg_write(sc, GPIO_GRER2, 0);
179 pxagpio_reg_write(sc, GPIO_GFER0, 0);
180 pxagpio_reg_write(sc, GPIO_GFER1, 0);
181 pxagpio_reg_write(sc, GPIO_GFER2, 0);
182 pxagpio_reg_write(sc, GPIO_GEDR0, ~0);
183 pxagpio_reg_write(sc, GPIO_GEDR1, ~0);
184 pxagpio_reg_write(sc, GPIO_GEDR2, ~0);
185 #ifdef CPU_XSCALE_PXA270
186 if (CPU_IS_PXA270) {
187 pxagpio_reg_write(sc, GPIO_GRER3, 0);
188 pxagpio_reg_write(sc, GPIO_GFER3, 0);
189 pxagpio_reg_write(sc, GPIO_GEDR3, ~0);
190 }
191 #endif
192
193 #ifdef PXAGPIO_HAS_GPION_INTRS
194 sc->sc_irqcookie[2] = pxa2x0_intr_establish(PXA2X0_INT_GPION, IPL_BIO,
195 gpio_intrN, sc);
196 if (sc->sc_irqcookie[2] == NULL) {
197 aprint_error_dev(self, "failed to hook main GPIO interrupt\n");
198 return;
199 }
200 #endif
201
202 sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;
203
204 pxagpio_softc = sc;
205 #if NGPIO > 0
206 #if defined(CPU_XSCALE_PXA250) && defined(CPU_XSCALE_PXA270)
207 maxpin = CPU_IS_PXA270 ? PXA270_GPIO_NPINS : PXA250_GPIO_NPINS;
208 #else
209 maxpin = GPIO_NPINS;
210 #endif
211 for (pin = 0; pin < maxpin; ++pin) {
212
213 sc->sc_gpio_pins[pin].pin_num = pin;
214 func = pxa2x0_gpio_get_function(pin);
215
216 if (GPIO_IS_GPIO(func)) {
217 sc->sc_gpio_pins[pin].pin_caps = GPIO_PIN_INPUT |
218 GPIO_PIN_OUTPUT;
219 sc->sc_gpio_pins[pin].pin_state =
220 pxa2x0_gpio_pin_read(sc, pin);
221 } else {
222 sc->sc_gpio_pins[pin].pin_caps = 0;
223 sc->sc_gpio_pins[pin].pin_state = 0;
224 }
225 }
226
227 /* create controller tag */
228 sc->sc_gpio_gc.gp_cookie = sc;
229 sc->sc_gpio_gc.gp_pin_read = pxa2x0_gpio_pin_read;
230 sc->sc_gpio_gc.gp_pin_write = pxa2x0_gpio_pin_write;
231 sc->sc_gpio_gc.gp_pin_ctl = pxa2x0_gpio_pin_ctl;
232
233 gba.gba_gc = &sc->sc_gpio_gc;
234 gba.gba_pins = sc->sc_gpio_pins;
235 gba.gba_npins = maxpin;
236
237 config_found(self, &gba, gpiobus_print, CFARGS_NONE);
238 #else
239 aprint_normal_dev(sc->sc_dev, "no GPIO configured in kernel\n");
240 #endif
241 }
242
243 void
pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)244 pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
245 {
246
247 pxagpio_regs = gpio_regs;
248 }
249
250 void *
pxa2x0_gpio_intr_establish(u_int gpio,int level,int spl,int (* func)(void *),void * arg)251 pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),
252 void *arg)
253 {
254 struct pxagpio_softc *sc = pxagpio_softc;
255 struct gpio_irq_handler *gh;
256 uint32_t bit, reg;
257
258 #ifdef PXAGPIO_HAS_GPION_INTRS
259 if (gpio >= GPIO_NPINS)
260 panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
261 #else
262 if (gpio > 1)
263 panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
264 #endif
265
266 if (!GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(gpio)))
267 panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio);
268
269 switch (level) {
270 case IST_EDGE_FALLING:
271 case IST_EDGE_RISING:
272 case IST_EDGE_BOTH:
273 break;
274
275 default:
276 panic("pxa2x0_gpio_intr_establish: bad level: %d", level);
277 break;
278 }
279
280 if (sc->sc_handlers[gpio] != NULL)
281 panic("pxa2x0_gpio_intr_establish: illegal shared interrupt");
282
283 gh = kmem_alloc(sizeof(*gh), KM_SLEEP);
284 gh->gh_func = func;
285 gh->gh_arg = arg;
286 gh->gh_spl = spl;
287 gh->gh_gpio = gpio;
288 gh->gh_level = level;
289 gh->gh_next = sc->sc_handlers[gpio];
290 sc->sc_handlers[gpio] = gh;
291
292 if (gpio == 0) {
293 KDASSERT(sc->sc_irqcookie[0] == NULL);
294 sc->sc_irqcookie[0] = pxa2x0_intr_establish(PXA2X0_INT_GPIO0,
295 spl, gpio_intr0, sc);
296 KDASSERT(sc->sc_irqcookie[0]);
297 } else
298 if (gpio == 1) {
299 KDASSERT(sc->sc_irqcookie[1] == NULL);
300 sc->sc_irqcookie[1] = pxa2x0_intr_establish(PXA2X0_INT_GPIO1,
301 spl, gpio_intr1, sc);
302 KDASSERT(sc->sc_irqcookie[1]);
303 }
304
305 bit = GPIO_BIT(gpio);
306 sc->sc_mask[GPIO_BANK(gpio)] |= bit;
307
308 switch (level) {
309 case IST_EDGE_FALLING:
310 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
311 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
312 break;
313
314 case IST_EDGE_RISING:
315 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
316 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
317 break;
318
319 case IST_EDGE_BOTH:
320 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
321 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
322 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
323 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
324 break;
325 }
326
327 return (gh);
328 }
329
330 void
pxa2x0_gpio_intr_disestablish(void * cookie)331 pxa2x0_gpio_intr_disestablish(void *cookie)
332 {
333 struct pxagpio_softc *sc = pxagpio_softc;
334 struct gpio_irq_handler *gh = cookie;
335 uint32_t bit, reg;
336
337 bit = GPIO_BIT(gh->gh_gpio);
338
339 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio));
340 reg &= ~bit;
341 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio), reg);
342 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio));
343 reg &= ~bit;
344 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio), reg);
345
346 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit);
347
348 sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit;
349 sc->sc_handlers[gh->gh_gpio] = NULL;
350
351 if (gh->gh_gpio == 0) {
352 #if 0
353 pxa2x0_intr_disestablish(sc->sc_irqcookie[0]);
354 sc->sc_irqcookie[0] = NULL;
355 #else
356 panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#0");
357 #endif
358 } else
359 if (gh->gh_gpio == 1) {
360 #if 0
361 pxa2x0_intr_disestablish(sc->sc_irqcookie[1]);
362 sc->sc_irqcookie[1] = NULL;
363 #else
364 panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#1");
365 #endif
366 }
367
368 kmem_free(gh, sizeof(*gh));
369 }
370
371 static int
gpio_intr0(void * arg)372 gpio_intr0(void *arg)
373 {
374 struct pxagpio_softc *sc = arg;
375
376 #ifdef DIAGNOSTIC
377 if (sc->sc_handlers[0] == NULL) {
378 aprint_error_dev(sc->sc_dev, "stray GPIO#0 edge interrupt\n");
379 return (0);
380 }
381 #endif
382
383 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0),
384 GPIO_BIT(0));
385
386 return ((sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg));
387 }
388
389 static int
gpio_intr1(void * arg)390 gpio_intr1(void *arg)
391 {
392 struct pxagpio_softc *sc = arg;
393
394 #ifdef DIAGNOSTIC
395 if (sc->sc_handlers[1] == NULL) {
396 aprint_error_dev(sc->sc_dev, "stray GPIO#1 edge interrupt\n");
397 return (0);
398 }
399 #endif
400
401 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1),
402 GPIO_BIT(1));
403
404 return ((sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg));
405 }
406
407 #ifdef PXAGPIO_HAS_GPION_INTRS
408 static int
gpio_dispatch(struct pxagpio_softc * sc,int gpio_base)409 gpio_dispatch(struct pxagpio_softc *sc, int gpio_base)
410 {
411 struct gpio_irq_handler **ghp, *gh;
412 int i, s, nhandled, handled, pins;
413 uint32_t gedr, mask;
414 int bank;
415
416 /* Fetch bitmap of pending interrupts on this GPIO bank */
417 gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base));
418
419 /* Don't handle GPIO 0/1 here */
420 if (gpio_base == 0)
421 gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1));
422
423 /* Bail early if there are no pending interrupts in this bank */
424 if (gedr == 0)
425 return (0);
426
427 /* Acknowledge pending interrupts. */
428 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr);
429
430 bank = GPIO_BANK(gpio_base);
431
432 /*
433 * We're only interested in those for which we have a handler
434 * registered
435 */
436 #ifdef DEBUG
437 if ((gedr & sc->sc_mask[bank]) == 0) {
438 aprint_error_dev(sc->sc_dev,
439 "stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n",
440 bank, gedr, sc->sc_mask[bank]);
441 return (1); /* XXX: Pretend we dealt with it */
442 }
443 #endif
444
445 gedr &= sc->sc_mask[bank];
446 ghp = &sc->sc_handlers[gpio_base];
447 if (CPU_IS_PXA270)
448 pins = (gpio_base < 96) ? 32 : 25;
449 else
450 pins = (gpio_base < 64) ? 32 : 17;
451 handled = 0;
452
453 for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) {
454 if ((gedr & mask) == 0)
455 continue;
456 gedr &= ~mask;
457
458 if ((gh = *ghp) == NULL) {
459 aprint_error_dev(sc->sc_dev,
460 "unhandled GPIO interrupt. GPIO#%d\n",
461 gpio_base + i);
462 continue;
463 }
464
465 s = _splraise(gh->gh_spl);
466 do {
467 nhandled = (gh->gh_func)(gh->gh_arg);
468 handled |= nhandled;
469 gh = gh->gh_next;
470 } while (gh != NULL);
471 splx(s);
472 }
473
474 return (handled);
475 }
476
477 static int
gpio_intrN(void * arg)478 gpio_intrN(void *arg)
479 {
480 struct pxagpio_softc *sc = arg;
481 int handled;
482
483 handled = gpio_dispatch(sc, 0);
484 handled |= gpio_dispatch(sc, 32);
485 handled |= gpio_dispatch(sc, 64);
486 if (CPU_IS_PXA270)
487 handled |= gpio_dispatch(sc, 96);
488 return (handled);
489 }
490 #endif /* PXAGPIO_HAS_GPION_INTRS */
491
492 u_int
pxa2x0_gpio_get_function(u_int gpio)493 pxa2x0_gpio_get_function(u_int gpio)
494 {
495 struct pxagpio_softc *sc = pxagpio_softc;
496 uint32_t rv, io;
497
498 KDASSERT(gpio < GPIO_NPINS);
499
500 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
501 rv = GPIO_FN(rv);
502
503 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio));
504 if (io & GPIO_BIT(gpio))
505 rv |= GPIO_OUT;
506
507 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio));
508 if (io & GPIO_BIT(gpio))
509 rv |= GPIO_SET;
510
511 return (rv);
512 }
513
514 u_int
pxa2x0_gpio_set_function(u_int gpio,u_int fn)515 pxa2x0_gpio_set_function(u_int gpio, u_int fn)
516 {
517 struct pxagpio_softc *sc = pxagpio_softc;
518 uint32_t rv, bit;
519 u_int oldfn;
520
521 KDASSERT(gpio < GPIO_NPINS);
522
523 oldfn = pxa2x0_gpio_get_function(gpio);
524
525 if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
526 GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
527 /*
528 * The pin's function is not changing.
529 * For Alternate Functions and GPIO input, we can just
530 * return now.
531 * For GPIO output pins, check the initial state is
532 * the same.
533 *
534 * Return 'fn' instead of 'oldfn' so the caller can
535 * reliably detect that we didn't change anything.
536 * (The initial state might be different for non-
537 * GPIO output pins).
538 */
539 if (!GPIO_IS_GPIO_OUT(fn) ||
540 GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
541 return (fn);
542 }
543
544 /*
545 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
546 * the correct procedure for changing GPIO pin functions.
547 */
548
549 bit = GPIO_BIT(gpio);
550
551 /*
552 * 1. Configure the correct set/clear state of the pin
553 */
554 if (GPIO_FN_IS_SET(fn))
555 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
556 else
557 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
558
559 /*
560 * 2. Configure the pin as an input or output as appropriate
561 */
562 rv = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
563 if (GPIO_FN_IS_OUT(fn))
564 rv |= bit;
565 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), rv);
566
567 /*
568 * 3. Configure the pin's function
569 */
570 bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
571 fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
572 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
573 pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
574
575 return (oldfn);
576 }
577
578 /*
579 * Quick function to read pin value
580 */
581 int
pxa2x0_gpio_get_bit(u_int gpio)582 pxa2x0_gpio_get_bit(u_int gpio)
583 {
584 struct pxagpio_softc *sc = pxagpio_softc;
585 int bit;
586
587 bit = GPIO_BIT(gpio);
588 if (pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio)) & bit)
589 return 1;
590 else
591 return 0;
592 }
593
594 /*
595 * Quick function to set pin to 1
596 */
597 void
pxa2x0_gpio_set_bit(u_int gpio)598 pxa2x0_gpio_set_bit(u_int gpio)
599 {
600 struct pxagpio_softc *sc = pxagpio_softc;
601 int bit;
602
603 bit = GPIO_BIT(gpio);
604 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
605 }
606
607 /*
608 * Quick function to set pin to 0
609 */
610 void
pxa2x0_gpio_clear_bit(u_int gpio)611 pxa2x0_gpio_clear_bit(u_int gpio)
612 {
613 struct pxagpio_softc *sc = pxagpio_softc;
614 int bit;
615
616 bit = GPIO_BIT(gpio);
617 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
618 }
619
620 /*
621 * Quick function to change pin direction
622 */
623 void
pxa2x0_gpio_set_dir(u_int gpio,int dir)624 pxa2x0_gpio_set_dir(u_int gpio, int dir)
625 {
626 struct pxagpio_softc *sc = pxagpio_softc;
627 int bit;
628 uint32_t reg;
629
630 bit = GPIO_BIT(gpio);
631
632 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
633 if (GPIO_FN_IS_OUT(dir))
634 reg |= bit;
635 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), reg);
636 }
637
638 /*
639 * Quick function to clear interrupt status on a pin
640 * GPIO pins may be toggle in an interrupt and we dont want
641 * extra spurious interrupts to occur.
642 * Suppose this causes a slight race if a key is pressed while
643 * the interrupt handler is running. (yes this is for the keyboard driver)
644 */
645 void
pxa2x0_gpio_clear_intr(u_int gpio)646 pxa2x0_gpio_clear_intr(u_int gpio)
647 {
648 struct pxagpio_softc *sc = pxagpio_softc;
649 int bit;
650
651 bit = GPIO_BIT(gpio);
652 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio), bit);
653 }
654
655 /*
656 * Quick function to mask (disable) a GPIO interrupt
657 */
658 void
pxa2x0_gpio_intr_mask(void * v)659 pxa2x0_gpio_intr_mask(void *v)
660 {
661 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
662
663 pxa2x0_gpio_set_intr_level(gh->gh_gpio, IPL_NONE);
664 }
665
666 /*
667 * Quick function to unmask (enable) a GPIO interrupt
668 */
669 void
pxa2x0_gpio_intr_unmask(void * v)670 pxa2x0_gpio_intr_unmask(void *v)
671 {
672 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v;
673
674 pxa2x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level);
675 }
676
677 /*
678 * Configure the edge sensitivity of interrupt pins
679 */
680 void
pxa2x0_gpio_set_intr_level(u_int gpio,int level)681 pxa2x0_gpio_set_intr_level(u_int gpio, int level)
682 {
683 struct pxagpio_softc *sc = pxagpio_softc;
684 uint32_t bit;
685 uint32_t gfer;
686 uint32_t grer;
687 int s;
688
689 s = splhigh();
690
691 bit = GPIO_BIT(gpio);
692 gfer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
693 grer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
694
695 switch (level) {
696 case IST_NONE:
697 gfer &= ~bit;
698 grer &= ~bit;
699 break;
700 case IST_EDGE_FALLING:
701 gfer |= bit;
702 grer &= ~bit;
703 break;
704 case IST_EDGE_RISING:
705 gfer &= ~bit;
706 grer |= bit;
707 break;
708 case IST_EDGE_BOTH:
709 gfer |= bit;
710 grer |= bit;
711 break;
712 default:
713 panic("pxa2x0_gpio_set_intr_level: bad level: %d", level);
714 break;
715 }
716
717 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), gfer);
718 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), grer);
719
720 splx(s);
721 }
722
723 #if NGPIO > 0
724 /* GPIO support functions */
725 static int
pxa2x0_gpio_pin_read(void * arg,int pin)726 pxa2x0_gpio_pin_read(void *arg, int pin)
727 {
728 return pxa2x0_gpio_get_bit(pin);
729 }
730
731 static void
pxa2x0_gpio_pin_write(void * arg,int pin,int value)732 pxa2x0_gpio_pin_write(void *arg, int pin, int value)
733 {
734 if (value == GPIO_PIN_HIGH) {
735 pxa2x0_gpio_set_bit(pin);
736 } else {
737 pxa2x0_gpio_clear_bit(pin);
738 }
739 }
740
741 static void
pxa2x0_gpio_pin_ctl(void * arg,int pin,int flags)742 pxa2x0_gpio_pin_ctl(void *arg, int pin, int flags)
743 {
744 if (flags & GPIO_PIN_OUTPUT) {
745 pxa2x0_gpio_set_function(pin, GPIO_OUT);
746 } else if (flags & GPIO_PIN_INPUT) {
747 pxa2x0_gpio_set_function(pin, GPIO_IN);
748 }
749 }
750 #endif
751
752 #if defined(CPU_XSCALE_PXA250)
753 /*
754 * Configurations of GPIO for PXA25x
755 */
756 struct pxa2x0_gpioconf pxa25x_com_btuart_gpioconf[] = {
757 { 42, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTRXD */
758 { 43, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTTXD */
759
760 #if 0 /* optional */
761 { 44, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTCTS */
762 { 45, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTRTS */
763 #endif
764
765 { -1 }
766 };
767
768 struct pxa2x0_gpioconf pxa25x_com_ffuart_gpioconf[] = {
769 { 34, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
770
771 #if 0 /* optional */
772 { 35, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* CTS */
773 { 36, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* DCD */
774 { 37, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* DSR */
775 { 38, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* RI */
776 #endif
777
778 { 39, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */
779
780 #if 0 /* optional */
781 { 40, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* DTR */
782 { 41, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* RTS */
783 #endif
784
785 { -1 }
786 };
787
788 struct pxa2x0_gpioconf pxa25x_com_hwuart_gpioconf[] = {
789 #if 0 /* We can select and/or. */
790 { 42, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWRXD */
791 { 49, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* HWRXD */
792
793 { 43, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWTXD */
794 { 48, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* HWTXD */
795
796 #if 0 /* optional */
797 { 44, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */
798 { 51, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */
799
800 { 45, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */
801 { 52, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */
802 #endif
803 #endif
804
805 { -1 }
806 };
807
808 struct pxa2x0_gpioconf pxa25x_com_stuart_gpioconf[] = {
809 { 46, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* RXD */
810 { 47, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* TXD */
811 { -1 }
812 };
813
814 struct pxa2x0_gpioconf pxa25x_i2c_gpioconf[] = {
815 { -1 }
816 };
817
818 struct pxa2x0_gpioconf pxa25x_i2s_gpioconf[] = {
819 { 28, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* BITCLK */
820 { 29, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN */
821 { 30, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SDATA_OUT */
822 { 31, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYNC */
823 { 32, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYSCLK */
824 { -1 }
825 };
826
827 struct pxa2x0_gpioconf pxa25x_pcic_gpioconf[] = {
828 { 48, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPOE */
829 { 49, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPWE */
830 { 50, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOR */
831 { 51, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOW */
832
833 #if 0 /* We can select and/or. */
834 { 52, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE1 */
835 { 53, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE2 */
836 #endif
837
838 { 54, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* pSKTSEL */
839 { 55, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPREG */
840 { 56, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nPWAIT */
841 { 57, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nIOIS16 */
842 { -1 }
843 };
844
845 struct pxa2x0_gpioconf pxa25x_pxaacu_gpioconf[] = {
846 { 28, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BITCLK */
847 { 30, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SDATA_OUT */
848 { 31, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SYNC */
849
850 #if 0 /* We can select and/or. */
851 { 29, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN0 */
852 { 32, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN1 */
853 #endif
854
855 { -1 }
856 };
857
858 struct pxa2x0_gpioconf pxa25x_pxamci_gpioconf[] = {
859 #if 0 /* We can select and/or. */
860 { 6, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */
861 { 53, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */
862 { 54, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */
863
864 { 8, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS0 */
865 { 34, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* MMCCS0 */
866 { 67, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS0 */
867
868 { 9, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */
869 { 39, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */
870 { 68, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */
871 #endif
872
873 { -1 }
874 };
875 #endif
876
877 #if defined(CPU_XSCALE_PXA270)
878 /*
879 * Configurations of GPIO for PXA27x
880 */
881 struct pxa2x0_gpioconf pxa27x_com_btuart_gpioconf[] = {
882 { 42, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTRXD */
883 { 43, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTTXD */
884
885 #if 0 /* optional */
886 { 44, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTCTS */
887 { 45, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTRTS */
888 #endif
889
890 { -1 }
891 };
892
893 struct pxa2x0_gpioconf pxa27x_com_ffuart_gpioconf[] = {
894 #if 0 /* We can select and/or. */
895 { 16, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */
896 { 37, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */
897 { 39, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */
898 { 83, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */
899 { 99, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */
900
901 { 19, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */
902 { 33, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
903 { 34, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
904 { 41, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
905 { 53, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
906 { 85, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */
907 { 96, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */
908 { 102, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */
909
910 { 9, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */
911 { 26, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */
912 { 35, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFCTS */
913 { 100, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */
914
915 { 27, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */
916 { 41, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFRTS */
917 { 83, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */
918 { 98, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */
919
920 { 40, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFDTR */
921 { 82, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFDTR */
922
923 { 36, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDCD */
924
925 { 33, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* FFDSR */
926 { 37, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDSR */
927
928 { 38, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRI */
929 #endif
930 { -1 }
931 };
932
933 struct pxa2x0_gpioconf pxa27x_com_stuart_gpioconf[] = {
934 { 46, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* STD_RXD */
935 { 47, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* STD_TXD */
936 { -1 }
937 };
938
939 struct pxa2x0_gpioconf pxa27x_i2c_gpioconf[] = {
940 { 117, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SCL */
941 { 118, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDA */
942 { -1 }
943 };
944
945 struct pxa2x0_gpioconf pxa27x_i2s_gpioconf[] = {
946 { 28, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_BITCLK */
947 { 29, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* I2S_SDATA_IN */
948 { 30, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SDATA_OUT */
949 { 31, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SYNC */
950 { 113, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SYSCLK */
951 { -1 }
952 };
953
954 struct pxa2x0_gpioconf pxa27x_ohci_gpioconf[] = {
955 #if 0 /* We can select and/or. */
956 { 88, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* USBHPWR1 */
957 { 89, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* USBHPEN1 */
958 { 119, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* USBHPWR2 */
959 { 120, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* USBHPEN2 */
960 #endif
961 { -1 }
962 };
963
964 struct pxa2x0_gpioconf pxa27x_pcic_gpioconf[] = {
965 { 48, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPOE */
966 { 49, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPWE */
967 { 50, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOR */
968 { 51, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOW */
969 { 55, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPREG */
970 { 56, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nPWAIT */
971 { 57, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nIOIS16 */
972
973 #if 0 /* We can select and/or. */
974 { 85, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */
975 { 86, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */
976 { 102, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */
977
978 { 54, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE2 */
979 { 78, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE2 */
980 { 105, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE2 */
981
982 { 79, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */
983 { 104, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */
984 #endif
985
986 { -1 }
987 };
988
989 struct pxa2x0_gpioconf pxa27x_pxaacu_gpioconf[] = {
990 { 28, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BITCLK */
991 { 30, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SDATA_OUT */
992
993 #if 0 /* We can select and/or. */
994 { 31, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SYNC */
995 { 94, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYNC */
996
997 { 29, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN0 */
998 { 116, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN0 */
999
1000 { 32, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN1 */
1001 { 99, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN1 */
1002
1003 { 95, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* RESET_n */
1004 { 113, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* RESET_n */
1005 #endif
1006
1007 { -1 }
1008 };
1009
1010 struct pxa2x0_gpioconf pxa27x_pxamci_gpioconf[] = {
1011 { 32, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* MMCLK */
1012 { 92, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<0> */
1013 { 109, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<1> */
1014 { 110, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<2>/MMCCS<0> */
1015 { 111, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<3>/MMCCS<1> */
1016 { 112, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMCMD */
1017
1018 { -1 }
1019 };
1020 #endif
1021
1022 void
pxa2x0_gpio_config(struct pxa2x0_gpioconf ** conflist)1023 pxa2x0_gpio_config(struct pxa2x0_gpioconf **conflist)
1024 {
1025 int i, j;
1026
1027 for (i = 0; conflist[i] != NULL; i++)
1028 for (j = 0; conflist[i][j].pin != -1; j++)
1029 pxa2x0_gpio_set_function(conflist[i][j].pin,
1030 conflist[i][j].value);
1031 }
1032