xref: /openbsd-src/sys/arch/armv7/omap/omgpio.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /* $OpenBSD: omgpio.c,v 1.10 2016/08/12 03:22:41 jsg Exp $ */
2 /*
3  * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/queue.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 #include <sys/evcount.h>
24 #include <sys/gpio.h>
25 
26 #include <arm/cpufunc.h>
27 
28 #include <machine/bus.h>
29 #include <machine/fdt.h>
30 #include <machine/intr.h>
31 
32 #include <dev/gpio/gpiovar.h>
33 
34 #include <armv7/armv7/armv7var.h>
35 #include <armv7/omap/prcmvar.h>
36 #include <armv7/omap/omgpiovar.h>
37 
38 #include <dev/ofw/fdt.h>
39 #include <dev/ofw/openfirm.h>
40 
41 #include "gpio.h"
42 
43 /* OMAP3 registers */
44 #define	GPIO3_REVISION		0x00
45 #define	GPIO3_SYSCONFIG		0x10
46 #define	GPIO3_SYSSTATUS		0x14
47 #define	GPIO3_IRQSTATUS1	0x18
48 #define	GPIO3_IRQENABLE1	0x1C
49 #define	GPIO3_WAKEUPENABLE	0x20
50 #define	GPIO3_IRQSTATUS2	0x28
51 #define	GPIO3_IRQENABLE2	0x2C
52 #define	GPIO3_CTRL		0x30
53 #define	GPIO3_OE		0x34
54 #define	GPIO3_DATAIN		0x38
55 #define	GPIO3_DATAOUT		0x3C
56 #define	GPIO3_LEVELDETECT0	0x40
57 #define	GPIO3_LEVELDETECT1	0x44
58 #define	GPIO3_RISINGDETECT	0x48
59 #define	GPIO3_FALLINGDETECT	0x4C
60 #define	GPIO3_DEBOUNCENABLE	0x50
61 #define	GPIO3_DEBOUNCINGTIME	0x54
62 #define	GPIO3_CLEARIRQENABLE1	0x60
63 #define	GPIO3_SETIRQENABLE1	0x64
64 #define	GPIO3_CLEARIRQENABLE2	0x70
65 #define	GPIO3_SETIRQENABLE2	0x74
66 #define	GPIO3_CLEARWKUENA	0x80
67 #define	GPIO3_SETWKUENA		0x84
68 #define	GPIO3_CLEARDATAOUT	0x90
69 #define	GPIO3_SETDATAOUT	0x94
70 
71 /* OMAP4 registers */
72 #define GPIO4_REVISION		0x00
73 #define GPIO4_SYSCONFIG		0x10
74 #define GPIO4_IRQSTATUS_RAW_0	0x24
75 #define GPIO4_IRQSTATUS_RAW_1	0x28
76 #define GPIO4_IRQSTATUS_0	0x2C
77 #define GPIO4_IRQSTATUS_1	0x30
78 #define GPIO4_IRQSTATUS_SET_0	0x34
79 #define GPIO4_IRQSTATUS_SET_1	0x38
80 #define GPIO4_IRQSTATUS_CLR_0	0x3C
81 #define GPIO4_IRQSTATUS_CLR_1	0x40
82 #define GPIO4_IRQWAKEN_0	0x44
83 #define GPIO4_IRQWAKEN_1	0x48
84 #define GPIO4_SYSSTATUS		0x114
85 #define GPIO4_WAKEUPENABLE	0x120
86 #define GPIO4_CTRL		0x130
87 #define GPIO4_OE		0x134
88 #define GPIO4_DATAIN		0x138
89 #define GPIO4_DATAOUT		0x13C
90 #define GPIO4_LEVELDETECT0	0x140
91 #define GPIO4_LEVELDETECT1	0x144
92 #define GPIO4_RISINGDETECT 	0x148
93 #define GPIO4_FALLINGDETECT	0x14C
94 #define GPIO4_DEBOUNCENABLE	0x150
95 #define GPIO4_DEBOUNCINGTIME	0x154
96 #define GPIO4_CLEARWKUPENA	0x180
97 #define GPIO4_SETWKUENA		0x184
98 #define GPIO4_CLEARDATAOUT	0x190
99 #define GPIO4_SETDATAOUT	0x194
100 
101 /* AM335X registers */
102 #define GPIO_AM335X_REVISION		0x00
103 #define GPIO_AM335X_SYSCONFIG		0x10
104 #define GPIO_AM335X_IRQSTATUS_RAW_0	0x24
105 #define GPIO_AM335X_IRQSTATUS_RAW_1	0x28
106 #define GPIO_AM335X_IRQSTATUS_0		0x2C
107 #define GPIO_AM335X_IRQSTATUS_1		0x30
108 #define GPIO_AM335X_IRQSTATUS_SET_0	0x34
109 #define GPIO_AM335X_IRQSTATUS_SET_1	0x38
110 #define GPIO_AM335X_IRQSTATUS_CLR_0	0x3c
111 #define GPIO_AM335X_IRQSTATUS_CLR_1	0x40
112 #define GPIO_AM335X_IRQWAKEN_0		0x44
113 #define GPIO_AM335X_IRQWAKEN_1		0x48
114 #define GPIO_AM335X_SYSSTATUS		0x114
115 #define GPIO_AM335X_CTRL		0x130
116 #define GPIO_AM335X_OE			0x134
117 #define GPIO_AM335X_DATAIN		0x138
118 #define GPIO_AM335X_DATAOUT		0x13C
119 #define GPIO_AM335X_LEVELDETECT0	0x140
120 #define GPIO_AM335X_LEVELDETECT1	0x144
121 #define GPIO_AM335X_RISINGDETECT	0x148
122 #define GPIO_AM335X_FALLINGDETECT	0x14C
123 #define GPIO_AM335X_DEBOUNCENABLE	0x150
124 #define GPIO_AM335X_DEBOUNCINGTIME	0x154
125 #define GPIO_AM335X_CLEARDATAOUT	0x190
126 #define GPIO_AM335X_SETDATAOUT		0x194
127 
128 #define GPIO_NUM_PINS		32
129 
130 struct intrhand {
131 	int (*ih_func)(void *);		/* handler */
132 	void *ih_arg;			/* arg for handler */
133 	int ih_ipl;			/* IPL_* */
134 	int ih_irq;			/* IRQ number */
135 	int ih_gpio;			/* gpio pin */
136 	struct evcount	ih_count;
137 	char *ih_name;
138 };
139 
140 struct omgpio_regs {
141 	u_int32_t	revision;
142 	u_int32_t	sysconfig;
143 	u_int32_t	irqstatus_raw0;		/* omap4/am335x only */
144 	u_int32_t	irqstatus_raw1;		/* omap4/am335x only */
145 	u_int32_t	irqstatus0;
146 	u_int32_t	irqstatus1;
147 	u_int32_t	irqstatus_set0;
148 	u_int32_t	irqstatus_set1;
149 	u_int32_t	irqstatus_clear0;
150 	u_int32_t	irqstatus_clear1;
151 	u_int32_t	irqwaken0;
152 	u_int32_t	irqwaken1;
153 	u_int32_t	sysstatus;
154 	u_int32_t	wakeupenable;		/* omap3/omap4 only */
155 	u_int32_t	ctrl;
156 	u_int32_t	oe;
157 	u_int32_t	datain;
158 	u_int32_t	dataout;
159 	u_int32_t	leveldetect0;
160 	u_int32_t	leveldetect1;
161 	u_int32_t	risingdetect;
162 	u_int32_t	fallingdetect;
163 	u_int32_t	debounceenable;
164 	u_int32_t	debouncingtime;
165 	u_int32_t	clearwkupena;		/* omap3/omap4 only */
166 	u_int32_t	setwkupena;		/* omap3/omap4 only */
167 	u_int32_t	cleardataout;
168 	u_int32_t	setdataout;
169 };
170 
171 struct omgpio_softc {
172 	struct device		sc_dev;
173 	bus_space_tag_t		sc_iot;
174 	bus_space_handle_t	sc_ioh;
175 	void			*sc_ih_h;
176 	void			*sc_ih_l;
177 	int 			sc_max_il;
178 	int 			sc_min_il;
179 	int			sc_node;
180 	struct intrhand		*sc_handlers[GPIO_NUM_PINS];
181 	int			sc_omap_ver;
182 	struct gpio_chipset_tag	sc_gpio_gc;
183 	gpio_pin_t		sc_gpio_pins[GPIO_NUM_PINS];
184 	struct omgpio_regs	sc_regs;
185 	int			(*sc_padconf_set_gpioflags)(uint32_t, uint32_t);
186 };
187 
188 #define GPIO_PIN_TO_INST(x)	((x) >> 5)
189 #define GPIO_PIN_TO_OFFSET(x)	((x) & 0x1f)
190 #define DEVNAME(sc)	((sc)->sc_dev.dv_xname)
191 #define READ4(sc, reg)		omgpio_read4(sc, reg)
192 #define WRITE4(sc, reg, val)	omgpio_write4(sc, reg, val)
193 
194 u_int32_t omgpio_read4(struct omgpio_softc *, u_int32_t);
195 void omgpio_write4(struct omgpio_softc *, u_int32_t, u_int32_t);
196 int omgpio_match(struct device *, void *, void *);
197 void omgpio_attach(struct device *, struct device *, void *);
198 void omgpio_recalc_interrupts(struct omgpio_softc *);
199 int omgpio_irq(void *);
200 int omgpio_irq_dummy(void *);
201 int omgpio_pin_dir_read(struct omgpio_softc *, unsigned int);
202 void omgpio_pin_dir_write(struct omgpio_softc *, unsigned int, unsigned int);
203 
204 struct cfattach omgpio_ca = {
205 	sizeof (struct omgpio_softc), omgpio_match, omgpio_attach
206 };
207 
208 struct cfdriver omgpio_cd = {
209 	NULL, "omgpio", DV_DULL
210 };
211 
212 const char *omgpio_compatible[] = {
213 	"ti,omap3-gpio",
214 	"ti,omap4-gpio",
215 	NULL
216 };
217 
218 u_int32_t
219 omgpio_read4(struct omgpio_softc *sc, u_int32_t reg)
220 {
221 	if(reg == -1)
222 		panic("%s: Invalid register address", DEVNAME(sc));
223 
224 	return bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg));
225 }
226 
227 void
228 omgpio_write4(struct omgpio_softc *sc, u_int32_t reg, u_int32_t val)
229 {
230 	if(reg == -1)
231 		panic("%s: Invalid register address", DEVNAME(sc));
232 
233 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val));
234 }
235 
236 int
237 omgpio_match(struct device *parent, void *match, void *aux)
238 {
239 	struct fdt_attach_args *faa = aux;
240 	int i;
241 
242 	for (i = 0; omgpio_compatible[i] != NULL; i++) {
243 		if (OF_is_compatible(faa->fa_node, omgpio_compatible[i]))
244 			return 1;
245 	}
246 	return 0;
247 }
248 
249 void
250 omgpio_attach(struct device *parent, struct device *self, void *aux)
251 {
252 	struct fdt_attach_args *faa = aux;
253 	struct omgpio_softc *sc = (struct omgpio_softc *) self;
254 	struct gpiobus_attach_args gba;
255 	u_int32_t	rev;
256 	int		i, len, unit;
257 	char		hwmods[64];
258 
259 	if (faa->fa_nreg < 1)
260 		return;
261 
262 	unit = 0;
263 	if ((len = OF_getprop(faa->fa_node, "ti,hwmods", hwmods,
264 	    sizeof(hwmods))) == 6) {
265 		if ((strncmp(hwmods, "gpio", 4) == 0) &&
266 		    (hwmods[4] > '0') && (hwmods[4] <= '9'))
267 			unit = hwmods[4] - '1';
268 	}
269 
270 	prcm_enablemodule(PRCM_GPIO0 + unit);
271 
272 	sc->sc_node = faa->fa_node;
273 	sc->sc_iot = faa->fa_iot;
274 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
275 	    faa->fa_reg[0].size, 0, &sc->sc_ioh))
276 		panic("%s: bus_space_map failed!", DEVNAME(sc));
277 
278 	if (OF_is_compatible(faa->fa_node, "ti,omap3-gpio")) {
279 		sc->sc_padconf_set_gpioflags = NULL;
280 		sc->sc_regs.revision = GPIO3_REVISION;
281 		sc->sc_regs.sysconfig = GPIO3_SYSCONFIG;
282 		sc->sc_regs.irqstatus_raw0 = -1;
283 		sc->sc_regs.irqstatus_raw1 = -1;
284 		sc->sc_regs.irqstatus0 = GPIO3_IRQSTATUS1;
285 		sc->sc_regs.irqstatus1 = GPIO3_IRQSTATUS2;
286 		sc->sc_regs.irqstatus_set0 = GPIO3_SETIRQENABLE1;
287 		sc->sc_regs.irqstatus_set1 = GPIO3_SETIRQENABLE2;
288 		sc->sc_regs.irqstatus_clear0 = GPIO3_CLEARIRQENABLE1;
289 		sc->sc_regs.irqstatus_clear1 = GPIO3_CLEARIRQENABLE2;
290 		sc->sc_regs.irqwaken0 = -1;
291 		sc->sc_regs.irqwaken1 = -1;
292 		sc->sc_regs.sysstatus = GPIO3_SYSSTATUS;
293 		sc->sc_regs.wakeupenable = GPIO3_WAKEUPENABLE;
294 		sc->sc_regs.ctrl = GPIO3_CTRL;
295 		sc->sc_regs.oe = GPIO3_OE;
296 		sc->sc_regs.datain = GPIO3_DATAIN;
297 		sc->sc_regs.dataout = GPIO3_DATAOUT;
298 		sc->sc_regs.leveldetect0 = GPIO3_LEVELDETECT0;
299 		sc->sc_regs.leveldetect1 = GPIO3_LEVELDETECT1;
300 		sc->sc_regs.risingdetect = GPIO3_RISINGDETECT;
301 		sc->sc_regs.fallingdetect = GPIO3_FALLINGDETECT;
302 		sc->sc_regs.debounceenable = GPIO3_DEBOUNCENABLE;
303 		sc->sc_regs.debouncingtime = GPIO3_DEBOUNCINGTIME;
304 		sc->sc_regs.clearwkupena = GPIO3_CLEARWKUENA;
305 		sc->sc_regs.setwkupena = GPIO3_SETWKUENA;
306 		sc->sc_regs.cleardataout = GPIO3_CLEARDATAOUT;
307 		sc->sc_regs.setdataout = GPIO3_SETDATAOUT;
308 	} else if (OF_is_compatible(faa->fa_node, "ti,omap4-gpio")) {
309 		sc->sc_padconf_set_gpioflags = NULL;
310 		sc->sc_regs.revision = GPIO4_REVISION;
311 		sc->sc_regs.sysconfig = GPIO4_SYSCONFIG;
312 		sc->sc_regs.irqstatus_raw0 = GPIO4_IRQSTATUS_RAW_0;
313 		sc->sc_regs.irqstatus_raw1 = GPIO4_IRQSTATUS_RAW_1;
314 		sc->sc_regs.irqstatus0 = GPIO4_IRQSTATUS_0;
315 		sc->sc_regs.irqstatus1 = GPIO4_IRQSTATUS_1;
316 		sc->sc_regs.irqstatus_set0 = GPIO4_IRQSTATUS_SET_0;
317 		sc->sc_regs.irqstatus_set1 = GPIO4_IRQSTATUS_SET_1;
318 		sc->sc_regs.irqstatus_clear0 = GPIO4_IRQSTATUS_CLR_0;
319 		sc->sc_regs.irqstatus_clear1 = GPIO4_IRQSTATUS_CLR_1;
320 		sc->sc_regs.irqwaken0 = GPIO4_IRQWAKEN_0;
321 		sc->sc_regs.irqwaken1 = GPIO4_IRQWAKEN_1;
322 		sc->sc_regs.sysstatus = GPIO4_SYSSTATUS;
323 		sc->sc_regs.wakeupenable = -1;
324 		sc->sc_regs.ctrl = GPIO4_CTRL;
325 		sc->sc_regs.oe = GPIO4_OE;
326 		sc->sc_regs.datain = GPIO4_DATAIN;
327 		sc->sc_regs.dataout = GPIO4_DATAOUT;
328 		sc->sc_regs.leveldetect0 = GPIO4_LEVELDETECT0;
329 		sc->sc_regs.leveldetect1 = GPIO4_LEVELDETECT1;
330 		sc->sc_regs.risingdetect = GPIO4_RISINGDETECT;
331 		sc->sc_regs.fallingdetect = GPIO4_FALLINGDETECT;
332 		sc->sc_regs.debounceenable = GPIO4_DEBOUNCENABLE;
333 		sc->sc_regs.debouncingtime = GPIO4_DEBOUNCINGTIME;
334 		sc->sc_regs.clearwkupena = -1;
335 		sc->sc_regs.setwkupena = -1;
336 		sc->sc_regs.cleardataout = GPIO4_CLEARDATAOUT;
337 		sc->sc_regs.setdataout = GPIO4_SETDATAOUT;
338 	} else
339 		panic("%s: could not find a compatible soc",
340 		    sc->sc_dev.dv_xname);
341 
342 	rev = READ4(sc, sc->sc_regs.revision);
343 
344 	printf(": rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf);
345 
346 	WRITE4(sc, sc->sc_regs.irqstatus_clear0, ~0);
347 	WRITE4(sc, sc->sc_regs.irqstatus_clear1, ~0);
348 
349 	/* XXX - SYSCONFIG */
350 	/* XXX - CTRL */
351 	/* XXX - DEBOUNCE */
352 
353 	for (i = 0; i < GPIO_NUM_PINS; i++) {
354 		sc->sc_gpio_pins[i].pin_num = i;
355 		sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
356 		    GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
357 		sc->sc_gpio_pins[i].pin_state = omgpio_pin_read(sc, i) ?
358 		    GPIO_PIN_HIGH : GPIO_PIN_LOW;
359 		sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_SET;
360 	}
361 
362 	sc->sc_gpio_gc.gp_cookie = sc;
363 	sc->sc_gpio_gc.gp_pin_read = omgpio_pin_read;
364 	sc->sc_gpio_gc.gp_pin_write = omgpio_pin_write;
365 	sc->sc_gpio_gc.gp_pin_ctl = omgpio_pin_ctl;
366 
367 	gba.gba_name = "gpio";
368 	gba.gba_gc = &sc->sc_gpio_gc;
369 	gba.gba_pins = sc->sc_gpio_pins;
370 	gba.gba_npins = GPIO_NUM_PINS;
371 
372 #if NGPIO > 0
373 	config_found(&sc->sc_dev, &gba, gpiobus_print);
374 #endif
375 }
376 
377 /* XXX - This assumes MCU INTERRUPTS are IRQ1, and DSP are IRQ2 */
378 
379 #if 0
380 /* XXX - FIND THESE REGISTERS !!! */
381 unsigned int
382 omgpio_get_function(unsigned int gpio, unsigned int fn)
383 {
384 	return 0;
385 }
386 
387 void
388 omgpio_set_function(unsigned int gpio, unsigned int fn)
389 {
390 }
391 #endif
392 
393 unsigned int
394 omgpio_get_bit(unsigned int gpio)
395 {
396 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
397 
398 	return omgpio_pin_read(sc, GPIO_PIN_TO_OFFSET(gpio));
399 }
400 
401 void
402 omgpio_set_bit(unsigned int gpio)
403 {
404 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
405 
406 	omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_HIGH);
407 }
408 
409 void
410 omgpio_clear_bit(unsigned int gpio)
411 {
412 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
413 
414 	omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_LOW);
415 }
416 
417 void
418 omgpio_set_dir(unsigned int gpio, unsigned int dir)
419 {
420 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
421 
422 	omgpio_pin_dir_write(sc, GPIO_PIN_TO_OFFSET(gpio), dir);
423 }
424 
425 int
426 omgpio_pin_read(void *arg, int pin)
427 {
428 	struct omgpio_softc *sc = arg;
429 	u_int32_t reg;
430 
431 	if(omgpio_pin_dir_read(sc, pin) == OMGPIO_DIR_IN)
432 		reg = READ4(sc, sc->sc_regs.datain);
433 	else
434 		reg = READ4(sc, sc->sc_regs.dataout);
435 	return (reg >> GPIO_PIN_TO_OFFSET(pin)) & 0x1;
436 }
437 
438 void
439 omgpio_pin_write(void *arg, int pin, int value)
440 {
441 	struct omgpio_softc *sc = arg;
442 
443 	if (value)
444 		WRITE4(sc, sc->sc_regs.setdataout,
445 		    1 << GPIO_PIN_TO_OFFSET(pin));
446 	else
447 		WRITE4(sc, sc->sc_regs.cleardataout,
448 		    1 << GPIO_PIN_TO_OFFSET(pin));
449 }
450 
451 void
452 omgpio_pin_ctl(void *arg, int pin, int flags)
453 {
454 	struct omgpio_softc *sc = arg;
455 
456 	if (flags & GPIO_PIN_INPUT)
457 		omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_IN);
458 	else if (flags & GPIO_PIN_OUTPUT)
459 		omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_OUT);
460 
461 	if (sc->sc_padconf_set_gpioflags)
462 		sc->sc_padconf_set_gpioflags(
463 		    sc->sc_dev.dv_unit * GPIO_NUM_PINS + pin, flags);
464 }
465 
466 void
467 omgpio_pin_dir_write(struct omgpio_softc *sc, unsigned int gpio,
468     unsigned int dir)
469 {
470 	int s;
471 	u_int32_t reg;
472 
473 	s = splhigh();
474 
475 	reg = READ4(sc, sc->sc_regs.oe);
476 	if (dir == OMGPIO_DIR_IN)
477 		reg |= 1 << GPIO_PIN_TO_OFFSET(gpio);
478 	else
479 		reg &= ~(1 << GPIO_PIN_TO_OFFSET(gpio));
480 	WRITE4(sc, sc->sc_regs.oe, reg);
481 
482 	splx(s);
483 }
484 
485 int
486 omgpio_pin_dir_read(struct omgpio_softc *sc, unsigned int gpio)
487 {
488 	u_int32_t reg;
489 	reg = READ4(sc, sc->sc_regs.oe);
490 	if (reg & (1 << GPIO_PIN_TO_OFFSET(gpio)))
491 		return OMGPIO_DIR_IN;
492 	else
493 		return OMGPIO_DIR_OUT;
494 }
495 
496 #if 0
497 void
498 omgpio_clear_intr(struct omgpio_softc *sc, unsigned int gpio)
499 {
500 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
501 
502 	WRITE4(sc, sc->sc_regs.irqstatus0, 1 << GPIO_PIN_TO_OFFSET(gpio));
503 }
504 
505 void
506 omgpio_intr_mask(struct omgpio_softc *sc, unsigned int gpio)
507 {
508 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
509 
510 	WRITE4(sc, sc->sc_regs.irqstatus_clear0, 1 << GPIO_PIN_TO_OFFSET(gpio));
511 }
512 
513 void
514 omgpio_intr_unmask(struct omgpio_softc *sc, unsigned int gpio)
515 {
516 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
517 
518 	WRITE4(sc, sc->sc_regs.irqstatus_set0, 1 << GPIO_PIN_TO_OFFSET(gpio));
519 }
520 
521 void
522 omgpio_intr_level(struct omgpio_softc *sc, unsigned int gpio, unsigned int level)
523 {
524 	u_int32_t fe, re, l0, l1, bit;
525 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
526 	int s;
527 
528 	s = splhigh();
529 
530 	fe = READ4(sc, sc->sc_regs.fallingdetect);
531 	re = READ4(sc, sc->sc_regs.risingdetect);
532 	l0 = READ4(sc, sc->sc_regs.leveldetect0);
533 	l1 = READ4(sc, sc->sc_regs.leveldetect1);
534 
535 	bit = 1 << GPIO_PIN_TO_OFFSET(gpio);
536 
537 	switch (level) {
538 	case IST_NONE:
539 		fe &= ~bit;
540 		re &= ~bit;
541 		l0 &= ~bit;
542 		l1 &= ~bit;
543 		break;
544 	case IST_EDGE_FALLING:
545 		fe |= bit;
546 		re &= ~bit;
547 		l0 &= ~bit;
548 		l1 &= ~bit;
549 		break;
550 	case IST_EDGE_RISING:
551 		fe &= ~bit;
552 		re |= bit;
553 		l0 &= ~bit;
554 		l1 &= ~bit;
555 		break;
556 	case IST_PULSE: /* XXX */
557 		/* FALLTHRU */
558 	case IST_EDGE_BOTH:
559 		fe |= bit;
560 		re |= bit;
561 		l0 &= ~bit;
562 		l1 &= ~bit;
563 		break;
564 	case IST_LEVEL_LOW:
565 		fe &= ~bit;
566 		re &= ~bit;
567 		l0 |= bit;
568 		l1 &= ~bit;
569 		break;
570 	case IST_LEVEL_HIGH:
571 		fe &= ~bit;
572 		re &= ~bit;
573 		l0 &= ~bit;
574 		l1 |= bit;
575 		break;
576 	default:
577 		panic("omgpio_intr_level: bad level: %d", level);
578 		break;
579 	}
580 
581 	WRITE4(sc, sc->sc_regs.fallingdetect, fe);
582 	WRITE4(sc, sc->sc_regs.risingdetect, re);
583 	WRITE4(sc, sc->sc_regs.leveldetect0, l0);
584 	WRITE4(sc, sc->sc_regs.leveldetect1, l1);
585 
586 	splx(s);
587 }
588 
589 void *
590 omgpio_intr_establish(struct omgpio_softc *sc, unsigned int gpio, int level, int spl,
591     int (*func)(void *), void *arg, char *name)
592 {
593 	int psw;
594 	struct intrhand *ih;
595 	struct omgpio_softc *sc;
596 
597 	/*
598 	 * XXX - is gpio here the pin or the interrupt number
599 	 * which is 96 + gpio pin?
600 	 */
601 
602 	if (GPIO_PIN_TO_INST(gpio) > omgpio_cd.cd_ndevs)
603 		panic("omgpio_intr_establish: bogus irqnumber %d: %s",
604 		    gpio, name);
605 
606 	sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
607 
608 	if (sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] != NULL)
609 		panic("omgpio_intr_establish: gpio pin busy %d old %s new %s",
610 		    gpio, sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)]->ih_name,
611 		    name);
612 
613 	psw = disable_interrupts(PSR_I);
614 
615 	ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK);
616 	ih->ih_func = func;
617 	ih->ih_arg = arg;
618 	ih->ih_ipl = level;
619 	ih->ih_gpio = gpio;
620 	ih->ih_irq = gpio + 512;
621 	ih->ih_name = name;
622 
623 	sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = ih;
624 
625 	evcount_attach(&ih->ih_count, name, &ih->ih_irq);
626 
627 	omgpio_intr_level(gpio, level);
628 	omgpio_intr_unmask(gpio);
629 
630 	omgpio_recalc_interrupts(sc);
631 
632 	restore_interrupts(psw);
633 
634 	return (ih);
635 }
636 
637 void
638 omgpio_intr_disestablish(struct omgpio_softc *sc, void *cookie)
639 {
640 	int psw;
641 	struct intrhand *ih = cookie;
642 	struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(ih->ih_gpio)];
643 	int gpio = ih->ih_gpio;
644 	psw = disable_interrupts(PSR_I);
645 
646 	ih = sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)];
647 	sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = NULL;
648 
649 	evcount_detach(&ih->ih_count);
650 
651 	free(ih, M_DEVBUF, 0);
652 
653 	omgpio_intr_level(gpio, IST_NONE);
654 	omgpio_intr_mask(gpio);
655 	omgpio_clear_intr(gpio); /* Just in case */
656 
657 	omgpio_recalc_interrupts(sc);
658 
659 	restore_interrupts(psw);
660 }
661 
662 int
663 omgpio_irq(void *v)
664 {
665 	struct omgpio_softc *sc = v;
666 	u_int32_t pending;
667 	struct intrhand *ih;
668 	int bit;
669 
670 	pending = READ4(sc, omgpio.irqstatus0);
671 
672 	while (pending != 0) {
673 		bit = ffs(pending) - 1;
674 		ih = sc->sc_handlers[bit];
675 
676 		if (ih != NULL) {
677 			if (ih->ih_func(ih->ih_arg))
678 				ih->ih_count.ec_count++;
679 			omgpio_clear_intr(ih->ih_gpio);
680 		} else {
681 			panic("omgpio: irq fired no handler, gpio %x %x %x",
682 				sc->sc_dev.dv_unit * 32 + bit, pending,
683 	READ4(sc, omgpio.irqstatus0)
684 
685 				);
686 		}
687 		pending &= ~(1 << bit);
688 	}
689 	return 1;
690 }
691 
692 int
693 omgpio_irq_dummy(void *v)
694 {
695 	return 0;
696 }
697 
698 void
699 omgpio_recalc_interrupts(struct omgpio_softc *sc)
700 {
701 	struct intrhand *ih;
702 	int max = IPL_NONE;
703 	int min = IPL_HIGH;
704 	int i;
705 
706 	for (i = 0; i < GPIO_NUM_PINS; i++) {
707 		ih = sc->sc_handlers[i];
708 		if (ih != NULL) {
709 			if (ih->ih_ipl > max)
710 				max = ih->ih_ipl;
711 
712 			if (ih->ih_ipl < min)
713 				min = ih->ih_ipl;
714 		}
715 	}
716 	if (max == IPL_NONE)
717 		min = IPL_NONE;
718 
719 #if 0
720 	if ((max == IPL_NONE || max != sc->sc_max_il) && sc->sc_ih_h != NULL)
721 		arm_intr_disestablish_fdt(sc->sc_ih_h);
722 
723 	if (max != IPL_NONE && max != sc->sc_max_il) {
724 		sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, max, omgpio_irq,
725 		    sc, NULL);
726 	}
727 #else
728 	if (sc->sc_ih_h != NULL)
729 		arm_intr_disestablish_fdt(sc->sc_ih_h);
730 
731 	if (max != IPL_NONE) {
732 		sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, max, omgpio_irq,
733 		    sc, NULL);
734 	}
735 #endif
736 
737 	sc->sc_max_il = max;
738 
739 	if (sc->sc_ih_l != NULL)
740 		arm_intr_disestablish_fdt(sc->sc_ih_l);
741 
742 	if (max != min) {
743 		sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, min,
744 		    omgpio_irq_dummy, sc, NULL);
745 	}
746 	sc->sc_min_il = min;
747 }
748 #endif
749