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