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
62struct 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
71struct 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
86static int	pxagpio_match(device_t, cfdata_t, void *);
87static void	pxagpio_attach(device_t, device_t, void *);
88
89#if NGPIO > 0
90static int	pxa2x0_gpio_pin_read(void *, int);
91static void	pxa2x0_gpio_pin_write(void *, int, int);
92static void	pxa2x0_gpio_pin_ctl(void *, int, int);
93#endif
94
95CFATTACH_DECL_NEW(pxagpio, sizeof(struct pxagpio_softc),
96    pxagpio_match, pxagpio_attach, NULL, NULL);
97
98static struct pxagpio_softc *pxagpio_softc;
99static vaddr_t pxagpio_regs;
100#define GPIO_BOOTSTRAP_REG(reg)	\
101	(*((volatile uint32_t *)(pxagpio_regs + (reg))))
102
103static int gpio_intr0(void *);
104static int gpio_intr1(void *);
105#ifdef PXAGPIO_HAS_GPION_INTRS
106static int gpio_dispatch(struct pxagpio_softc *, int);
107static int gpio_intrN(void *);
108#endif
109
110static inline uint32_t
111pxagpio_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
121static inline void
122pxagpio_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
134static int
135pxagpio_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
147static void
148pxagpio_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
243void
244pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
245{
246
247	pxagpio_regs = gpio_regs;
248}
249
250void *
251pxa2x0_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
330void
331pxa2x0_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
371static int
372gpio_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
389static int
390gpio_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
408static int
409gpio_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
477static int
478gpio_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
492u_int
493pxa2x0_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
514u_int
515pxa2x0_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 */
581int
582pxa2x0_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 */
597void
598pxa2x0_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 */
610void
611pxa2x0_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 */
623void
624pxa2x0_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 */
645void
646pxa2x0_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 */
658void
659pxa2x0_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 */
669void
670pxa2x0_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 */
680void
681pxa2x0_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 */
725static int
726pxa2x0_gpio_pin_read(void *arg, int pin)
727{
728	return pxa2x0_gpio_get_bit(pin);
729}
730
731static void
732pxa2x0_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
741static void
742pxa2x0_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 */
756struct 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
768struct 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
788struct 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
808struct 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
814struct pxa2x0_gpioconf pxa25x_i2c_gpioconf[] = {
815	{ -1 }
816};
817
818struct 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
827struct 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
845struct 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
858struct 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 */
881struct 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
893struct 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
933struct 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
939struct 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
945struct 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
954struct 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
964struct 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
989struct 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
1010struct 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
1022void
1023pxa2x0_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