xref: /NextBSD/sys/arm/xscale/pxa/pxa_gpio.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*-
2  * Copyright (c) 2006 Benno Rice.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 #include <sys/cdefs.h>
26 __FBSDID("$FreeBSD$");
27 
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/bus.h>
31 #include <sys/kernel.h>
32 #include <sys/lock.h>
33 #include <sys/interrupt.h>
34 #include <sys/module.h>
35 #include <sys/malloc.h>
36 #include <sys/mutex.h>
37 #include <sys/rman.h>
38 #include <sys/queue.h>
39 #include <sys/taskqueue.h>
40 #include <sys/timetc.h>
41 #include <machine/bus.h>
42 #include <machine/intr.h>
43 
44 #include <arm/xscale/pxa/pxavar.h>
45 #include <arm/xscale/pxa/pxareg.h>
46 
47 struct pxa_gpio_softc {
48 	struct resource *	pg_res[4];
49 	bus_space_tag_t		pg_bst;
50 	bus_space_handle_t	pg_bsh;
51 	struct mtx		pg_mtx;
52 
53 	uint32_t		pg_intr[3];
54 };
55 
56 static struct resource_spec pxa_gpio_spec[] = {
57 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
58 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
59 	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
60 	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
61 	{ -1, 0 }
62 };
63 
64 static struct pxa_gpio_softc *pxa_gpio_softc = NULL;
65 
66 static int	pxa_gpio_probe(device_t);
67 static int	pxa_gpio_attach(device_t);
68 
69 static driver_filter_t	pxa_gpio_intr0;
70 static driver_filter_t	pxa_gpio_intr1;
71 static driver_filter_t	pxa_gpio_intrN;
72 
73 static int
pxa_gpio_probe(device_t dev)74 pxa_gpio_probe(device_t dev)
75 {
76 
77 	device_set_desc(dev, "GPIO Controller");
78 	return (0);
79 }
80 
81 static int
pxa_gpio_attach(device_t dev)82 pxa_gpio_attach(device_t dev)
83 {
84 	int	error;
85 	void	*ihl;
86 	struct	pxa_gpio_softc *sc;
87 
88 	sc = (struct pxa_gpio_softc *)device_get_softc(dev);
89 
90 	if (pxa_gpio_softc != NULL)
91 		return (ENXIO);
92 	pxa_gpio_softc = sc;
93 
94 	error = bus_alloc_resources(dev, pxa_gpio_spec, sc->pg_res);
95 	if (error) {
96 		device_printf(dev, "could not allocate resources\n");
97 		return (ENXIO);
98 	}
99 
100 	sc->pg_bst = rman_get_bustag(sc->pg_res[0]);
101 	sc->pg_bsh = rman_get_bushandle(sc->pg_res[0]);
102 
103 	/* Disable and clear all interrupts. */
104 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER0, 0);
105 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER1, 0);
106 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER2, 0);
107 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER0, 0);
108 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER1, 0);
109 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER2, 0);
110 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, ~0);
111 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, ~0);
112 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, ~0);
113 
114 	mtx_init(&sc->pg_mtx, "GPIO mutex", NULL, MTX_SPIN);
115 
116 	if (bus_setup_intr(dev, sc->pg_res[1], INTR_TYPE_MISC|INTR_MPSAFE,
117 	    pxa_gpio_intr0, NULL, sc, &ihl) != 0) {
118 		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
119 		device_printf(dev, "could not set up intr0\n");
120 		return (ENXIO);
121 	}
122 
123 	if (bus_setup_intr(dev, sc->pg_res[2], INTR_TYPE_MISC|INTR_MPSAFE,
124 	    pxa_gpio_intr1, NULL, sc, &ihl) != 0) {
125 		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
126 		device_printf(dev, "could not set up intr1\n");
127 		return (ENXIO);
128 	}
129 
130 	if (bus_setup_intr(dev, sc->pg_res[3], INTR_TYPE_MISC|INTR_MPSAFE,
131 	    pxa_gpio_intrN, NULL, sc, &ihl) != 0) {
132 		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
133 		device_printf(dev, "could not set up intrN\n");
134 		return (ENXIO);
135 	}
136 
137 	return (0);
138 }
139 
140 static int
pxa_gpio_intr0(void * arg)141 pxa_gpio_intr0(void *arg)
142 {
143 	struct	pxa_gpio_softc *sc;
144 
145 	sc = (struct pxa_gpio_softc *)arg;
146 
147 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x1);
148 	sc->pg_intr[0] |= 1;
149 
150 	return (FILTER_HANDLED);
151 }
152 
153 static int
pxa_gpio_intr1(void * arg)154 pxa_gpio_intr1(void *arg)
155 {
156 	struct	pxa_gpio_softc *sc;
157 
158 	sc = (struct pxa_gpio_softc *)arg;
159 
160 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x2);
161 	sc->pg_intr[1] |= 2;
162 
163 	return (FILTER_HANDLED);
164 }
165 
166 static int
pxa_gpio_intrN(void * arg)167 pxa_gpio_intrN(void *arg)
168 {
169 	uint32_t	gedr0, gedr1, gedr2;
170 	struct		pxa_gpio_softc *sc;
171 
172 	sc = (struct pxa_gpio_softc *)arg;
173 
174 	gedr0 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0);
175 	gedr0 &= 0xfffffffc;
176 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, gedr0);
177 
178 	gedr1 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1);
179 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, gedr1);
180 
181 	gedr2 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2);
182 	gedr2 &= 0x001fffff;
183 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, gedr2);
184 
185 	sc->pg_intr[0] |= gedr0;
186 	sc->pg_intr[1] |= gedr1;
187 	sc->pg_intr[2] |= gedr2;
188 
189 	return (FILTER_HANDLED);
190 }
191 
192 static device_method_t pxa_gpio_methods[] = {
193 	DEVMETHOD(device_probe, pxa_gpio_probe),
194 	DEVMETHOD(device_attach, pxa_gpio_attach),
195 
196 	{0, 0}
197 };
198 
199 static driver_t pxa_gpio_driver = {
200 	"gpio",
201 	pxa_gpio_methods,
202 	sizeof(struct pxa_gpio_softc),
203 };
204 
205 static devclass_t pxa_gpio_devclass;
206 
207 DRIVER_MODULE(pxagpio, pxa, pxa_gpio_driver, pxa_gpio_devclass, 0, 0);
208 
209 #define	pxagpio_reg_read(softc, reg)		\
210 	bus_space_read_4(sc->pg_bst, sc->pg_bsh, reg)
211 #define	pxagpio_reg_write(softc, reg, val)	\
212 	bus_space_write_4(sc->pg_bst, sc->pg_bsh, reg, val)
213 
214 uint32_t
pxa_gpio_get_function(int gpio)215 pxa_gpio_get_function(int gpio)
216 {
217 	struct		pxa_gpio_softc *sc;
218 	uint32_t	rv, io;
219 
220 	sc = pxa_gpio_softc;
221 
222 	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
223 	rv = GPIO_FN(rv);
224 
225 	io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio));
226 	if (io & GPIO_BIT(gpio))
227 		rv |= GPIO_OUT;
228 
229 	io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPLR0, gpio));
230 	if (io & GPIO_BIT(gpio))
231 		rv |= GPIO_SET;
232 
233 	return (rv);
234 }
235 
236 uint32_t
pxa_gpio_set_function(int gpio,uint32_t fn)237 pxa_gpio_set_function(int gpio, uint32_t fn)
238 {
239 	struct		pxa_gpio_softc *sc;
240 	uint32_t	rv, bit, oldfn;
241 
242 	sc = pxa_gpio_softc;
243 
244 	oldfn = pxa_gpio_get_function(gpio);
245 
246 	if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
247 	    GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
248 		/*
249 		 * The pin's function is not changing.
250 		 * For Alternate Functions and GPIO input, we can just
251 		 * return now.
252 		 * For GPIO output pins, check the initial state is
253 		 * the same.
254 		 *
255 		 * Return 'fn' instead of 'oldfn' so the caller can
256 		 * reliably detect that we didn't change anything.
257 		 * (The initial state might be different for non-
258 		 * GPIO output pins).
259 		 */
260 		if (!GPIO_IS_GPIO_OUT(fn) ||
261 		    GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
262 			return (fn);
263 	}
264 
265 	/*
266 	 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
267 	 * the correct procedure for changing GPIO pin functions.
268 	 */
269 
270 	bit = GPIO_BIT(gpio);
271 
272 	/*
273 	 * 1. Configure the correct set/clear state of the pin
274 	 */
275 	if (GPIO_FN_IS_SET(fn))
276 		pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPSR0, gpio), bit);
277 	else
278 		pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPCR0, gpio), bit);
279 
280 	/*
281 	 * 2. Configure the pin as an input or output as appropriate
282 	 */
283 	rv = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
284 	if (GPIO_FN_IS_OUT(fn))
285 		rv |= bit;
286 	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio), rv);
287 
288 	/*
289 	 * 3. Configure the pin's function
290 	 */
291 	bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
292 	fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
293 	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
294 	pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
295 
296 	return (oldfn);
297 }
298 
299 /*
300  * GPIO "interrupt" handling.
301  */
302 
303 void
pxa_gpio_mask_irq(int irq)304 pxa_gpio_mask_irq(int irq)
305 {
306 	uint32_t	val;
307 	struct		pxa_gpio_softc *sc;
308 	int		gpio;
309 
310 	sc = pxa_gpio_softc;
311 	gpio = IRQ_TO_GPIO(irq);
312 
313 	val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
314 	val &= ~GPIO_BIT(gpio);
315 	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
316 }
317 
318 void
pxa_gpio_unmask_irq(int irq)319 pxa_gpio_unmask_irq(int irq)
320 {
321 	uint32_t	val;
322 	struct		pxa_gpio_softc *sc;
323 	int		gpio;
324 
325 	sc = pxa_gpio_softc;
326 	gpio = IRQ_TO_GPIO(irq);
327 
328 	val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
329 	val |= GPIO_BIT(gpio);
330 	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
331 }
332 
333 int
pxa_gpio_get_next_irq()334 pxa_gpio_get_next_irq()
335 {
336 	struct  pxa_gpio_softc *sc;
337 	int     gpio;
338 
339 	sc = pxa_gpio_softc;
340 
341 	if (sc->pg_intr[0] != 0) {
342 		gpio = ffs(sc->pg_intr[0]) - 1;
343 		sc->pg_intr[0] &= ~(1 << gpio);
344 		return (GPIO_TO_IRQ(gpio));
345 	}
346 	if (sc->pg_intr[1] != 0) {
347 		gpio = ffs(sc->pg_intr[1]) - 1;
348 		sc->pg_intr[1] &= ~(1 << gpio);
349 		return (GPIO_TO_IRQ(gpio + 32));
350 	}
351 	if (sc->pg_intr[2] != 0) {
352 		gpio = ffs(sc->pg_intr[2]) - 1;
353 		sc->pg_intr[2] &= ~(1 << gpio);
354 		return (GPIO_TO_IRQ(gpio + 64));
355 	}
356 
357 	return (-1);
358 }
359