1 /*-
2 * Copyright 2015 Alexander Kabaev <kan@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 #include "opt_platform.h"
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/conf.h>
33 #include <sys/bus.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/lock.h>
37 #include <sys/mutex.h>
38 #include <sys/proc.h>
39 #include <sys/resource.h>
40 #include <sys/gpio.h>
41
42 #include <machine/bus.h>
43 #include <machine/intr.h>
44
45 #include <dev/gpio/gpiobusvar.h>
46
47 #include <dev/fdt/fdt_common.h>
48 #include <dev/ofw/ofw_bus.h>
49 #include <dev/ofw/ofw_bus_subr.h>
50
51 #include <mips/ingenic/jz4780_regs.h>
52 #include <dt-bindings/interrupt-controller/irq.h>
53
54 #include "jz4780_gpio_if.h"
55 #include "gpio_if.h"
56 #include "pic_if.h"
57
58 #define JZ4780_GPIO_PINS 32
59
60 enum pin_function {
61 JZ_FUNC_DEV_0,
62 JZ_FUNC_DEV_1,
63 JZ_FUNC_DEV_2,
64 JZ_FUNC_DEV_3,
65 JZ_FUNC_GPIO,
66 JZ_FUNC_INTR,
67 };
68
69 struct jz4780_gpio_pin {
70 struct intr_irqsrc pin_irqsrc;
71 enum intr_trigger intr_trigger;
72 enum intr_polarity intr_polarity;
73 enum pin_function pin_func;
74 uint32_t pin_caps;
75 uint32_t pin_flags;
76 uint32_t pin_num;
77 char pin_name[GPIOMAXNAME];
78 };
79
80 struct jz4780_gpio_softc {
81 device_t dev;
82 device_t busdev;
83 struct resource *res[2];
84 struct mtx mtx;
85 struct jz4780_gpio_pin pins[JZ4780_GPIO_PINS];
86 void *intrhand;
87 };
88
89 static struct resource_spec jz4780_gpio_spec[] = {
90 { SYS_RES_MEMORY, 0, RF_ACTIVE },
91 { SYS_RES_IRQ, 0, RF_ACTIVE },
92 { -1, 0 }
93 };
94
95 static int jz4780_gpio_probe(device_t dev);
96 static int jz4780_gpio_attach(device_t dev);
97 static int jz4780_gpio_detach(device_t dev);
98 static int jz4780_gpio_intr(void *arg);
99
100 #define JZ4780_GPIO_LOCK(sc) mtx_lock_spin(&(sc)->mtx)
101 #define JZ4780_GPIO_UNLOCK(sc) mtx_unlock_spin(&(sc)->mtx)
102 #define JZ4780_GPIO_LOCK_INIT(sc) \
103 mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
104 "jz4780_gpio", MTX_SPIN)
105 #define JZ4780_GPIO_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx);
106
107 #define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
108 #define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg))
109
110 static int
jz4780_gpio_probe(device_t dev)111 jz4780_gpio_probe(device_t dev)
112 {
113 phandle_t node;
114
115 if (!ofw_bus_status_okay(dev))
116 return (ENXIO);
117
118 /* We only like particular parent */
119 if (!ofw_bus_is_compatible(device_get_parent(dev),
120 "ingenic,jz4780-pinctrl"))
121 return (ENXIO);
122
123 /* ... and only specific children os that parent */
124 node = ofw_bus_get_node(dev);
125 if (!OF_hasprop(node, "gpio-controller"))
126 return (ENXIO);
127
128 device_set_desc(dev, "Ingenic JZ4780 GPIO Controller");
129
130 return (BUS_PROBE_DEFAULT);
131 }
132
133 static int
jz4780_gpio_pin_set_func(struct jz4780_gpio_softc * sc,uint32_t pin,uint32_t func)134 jz4780_gpio_pin_set_func(struct jz4780_gpio_softc *sc, uint32_t pin,
135 uint32_t func)
136 {
137 uint32_t mask = (1u << pin);
138
139 if (func > (uint32_t)JZ_FUNC_DEV_3)
140 return (EINVAL);
141
142 CSR_WRITE_4(sc, JZ_GPIO_INTC, mask);
143 CSR_WRITE_4(sc, JZ_GPIO_MASKC, mask);
144 if (func & 2)
145 CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask);
146 else
147 CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask);
148 if (func & 1)
149 CSR_WRITE_4(sc, JZ_GPIO_PAT0S, mask);
150 else
151 CSR_WRITE_4(sc, JZ_GPIO_PAT0C, mask);
152
153 sc->pins[pin].pin_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
154 sc->pins[pin].pin_func = (enum pin_function)func;
155 return (0);
156 }
157
158 static int
jz4780_gpio_pin_set_direction(struct jz4780_gpio_softc * sc,uint32_t pin,uint32_t dir)159 jz4780_gpio_pin_set_direction(struct jz4780_gpio_softc *sc,
160 uint32_t pin, uint32_t dir)
161 {
162 uint32_t mask = (1u << pin);
163
164 switch (dir) {
165 case GPIO_PIN_OUTPUT:
166 if (sc->pins[pin].pin_caps & dir)
167 CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask);
168 else
169 return (EINVAL);
170 break;
171 case GPIO_PIN_INPUT:
172 if (sc->pins[pin].pin_caps & dir)
173 CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask);
174 else
175 return (EINVAL);
176 break;
177 }
178
179 sc->pins[pin].pin_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
180 sc->pins[pin].pin_flags |= dir;
181 return (0);
182 }
183
184 static int
jz4780_gpio_pin_set_bias(struct jz4780_gpio_softc * sc,uint32_t pin,uint32_t bias)185 jz4780_gpio_pin_set_bias(struct jz4780_gpio_softc *sc,
186 uint32_t pin, uint32_t bias)
187 {
188 uint32_t mask = (1u << pin);
189
190 switch (bias) {
191 case GPIO_PIN_PULLUP:
192 case GPIO_PIN_PULLDOWN:
193 if (sc->pins[pin].pin_caps & bias)
194 CSR_WRITE_4(sc, JZ_GPIO_DPULLC, mask);
195 else
196 return (EINVAL);
197 break;
198 case 0:
199 CSR_WRITE_4(sc, JZ_GPIO_DPULLS, mask);
200 break;
201 default:
202 return (ENOTSUP);
203 }
204
205 sc->pins[pin].pin_flags &= ~(GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
206 sc->pins[pin].pin_flags |= bias;
207 return (0);
208 }
209
210 /*
211 * Decode pin configuration using this map
212 */
213 #if 0
214 INT MASK PAT1 PAT0
215 1 x 0 0 /* intr, level, low */
216 1 x 0 1 /* intr, level, high */
217 1 x 1 0 /* intr, edge, falling */
218 1 x 1 1 /* intr, edge, rising */
219 0 0 0 0 /* function, func 0 */
220 0 0 0 1 /* function, func 1 */
221 0 0 1 0 /* function, func 2 */
222 0 0 1 0 /* function, func 3 */
223 0 1 0 0 /* gpio, output 0 */
224 0 1 0 1 /* gpio, output 1 */
225 0 1 1 x /* gpio, input */
226 #endif
227
228 static void
jz4780_gpio_pin_probe(struct jz4780_gpio_softc * sc,uint32_t pin)229 jz4780_gpio_pin_probe(struct jz4780_gpio_softc *sc, uint32_t pin)
230 {
231 uint32_t mask = (1u << pin);
232 uint32_t val;
233
234 /* Clear cached gpio config */
235 sc->pins[pin].pin_flags = 0;
236
237 /* First check if pin is in interrupt mode */
238 val = CSR_READ_4(sc, JZ_GPIO_INT);
239 if (val & mask) {
240 /* Pin is in interrupt mode, decode interrupt triggering mode */
241 val = CSR_READ_4(sc, JZ_GPIO_PAT1);
242 if (val & mask)
243 sc->pins[pin].intr_trigger = INTR_TRIGGER_EDGE;
244 else
245 sc->pins[pin].intr_trigger = INTR_TRIGGER_LEVEL;
246 /* Decode interrupt polarity */
247 val = CSR_READ_4(sc, JZ_GPIO_PAT0);
248 if (val & mask)
249 sc->pins[pin].intr_polarity = INTR_POLARITY_HIGH;
250 else
251 sc->pins[pin].intr_polarity = INTR_POLARITY_LOW;
252
253 sc->pins[pin].pin_func = JZ_FUNC_INTR;
254 sc->pins[pin].pin_flags = 0;
255 return;
256 }
257 /* Next check if pin is in gpio mode */
258 val = CSR_READ_4(sc, JZ_GPIO_MASK);
259 if (val & mask) {
260 /* Pin is in gpio mode, decode direction and bias */
261 val = CSR_READ_4(sc, JZ_GPIO_PAT1);
262 if (val & mask)
263 sc->pins[pin].pin_flags |= GPIO_PIN_INPUT;
264 else
265 sc->pins[pin].pin_flags |= GPIO_PIN_OUTPUT;
266 /* Check for bias */
267 val = CSR_READ_4(sc, JZ_GPIO_DPULL);
268 if ((val & mask) == 0)
269 sc->pins[pin].pin_flags |= sc->pins[pin].pin_caps &
270 (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
271 sc->pins[pin].pin_func = JZ_FUNC_GPIO;
272 return;
273 }
274 /* By exclusion, pin is in alternate function mode */
275 val = CSR_READ_4(sc, JZ_GPIO_DPULL);
276 if ((val & mask) == 0)
277 sc->pins[pin].pin_flags = sc->pins[pin].pin_caps &
278 (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
279 val = ((CSR_READ_4(sc, JZ_GPIO_PAT1) & mask) >> pin) << 1;
280 val = val | ((CSR_READ_4(sc, JZ_GPIO_PAT1) & mask) >> pin);
281 sc->pins[pin].pin_func = (enum pin_function)val;
282 }
283
284 static int
jz4780_gpio_register_isrcs(struct jz4780_gpio_softc * sc)285 jz4780_gpio_register_isrcs(struct jz4780_gpio_softc *sc)
286 {
287 int error;
288 uint32_t irq, i;
289 struct intr_irqsrc *isrc;
290 const char *name;
291
292 name = device_get_nameunit(sc->dev);
293 for (irq = 0; irq < JZ4780_GPIO_PINS; irq++) {
294 isrc = &sc->pins[irq].pin_irqsrc;
295 error = intr_isrc_register(isrc, sc->dev, 0, "%s,%d",
296 name, irq);
297 if (error != 0) {
298 for (i = 0; i < irq; i++)
299 intr_isrc_deregister(&sc->pins[i].pin_irqsrc);
300 device_printf(sc->dev, "%s failed", __func__);
301 return (error);
302 }
303 }
304
305 return (0);
306 }
307
308 static int
jz4780_gpio_attach(device_t dev)309 jz4780_gpio_attach(device_t dev)
310 {
311 struct jz4780_gpio_softc *sc = device_get_softc(dev);
312 phandle_t node;
313 uint32_t i, pd_pins, pu_pins;
314
315 sc->dev = dev;
316
317 if (bus_alloc_resources(dev, jz4780_gpio_spec, sc->res)) {
318 device_printf(dev, "could not allocate resources for device\n");
319 return (ENXIO);
320 }
321
322 JZ4780_GPIO_LOCK_INIT(sc);
323
324 node = ofw_bus_get_node(dev);
325 OF_getencprop(node, "ingenic,pull-ups", &pu_pins, sizeof(pu_pins));
326 OF_getencprop(node, "ingenic,pull-downs", &pd_pins, sizeof(pd_pins));
327
328 for (i = 0; i < JZ4780_GPIO_PINS; i++) {
329 sc->pins[i].pin_num = i;
330 sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
331 if (pu_pins & (1 << i))
332 sc->pins[i].pin_caps |= GPIO_PIN_PULLUP;
333 if (pd_pins & (1 << i))
334 sc->pins[i].pin_caps |= GPIO_PIN_PULLDOWN;
335 sc->pins[i].intr_polarity = INTR_POLARITY_CONFORM;
336 sc->pins[i].intr_trigger = INTR_TRIGGER_CONFORM;
337
338 snprintf(sc->pins[i].pin_name, GPIOMAXNAME - 1, "gpio%c%d",
339 device_get_unit(dev) + 'a', i);
340 sc->pins[i].pin_name[GPIOMAXNAME - 1] = '\0';
341
342 jz4780_gpio_pin_probe(sc, i);
343 }
344
345 if (jz4780_gpio_register_isrcs(sc) != 0)
346 goto fail;
347
348 if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
349 device_printf(dev, "could not register PIC\n");
350 goto fail;
351 }
352
353 if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
354 jz4780_gpio_intr, NULL, sc, &sc->intrhand) != 0)
355 goto fail_pic;
356
357 sc->busdev = gpiobus_attach_bus(dev);
358 if (sc->busdev == NULL)
359 goto fail_pic;
360
361 return (0);
362 fail_pic:
363 intr_pic_deregister(dev, OF_xref_from_node(node));
364 fail:
365 if (sc->intrhand != NULL)
366 bus_teardown_intr(dev, sc->res[1], sc->intrhand);
367 bus_release_resources(dev, jz4780_gpio_spec, sc->res);
368 JZ4780_GPIO_LOCK_DESTROY(sc);
369 return (ENXIO);
370 }
371
372 static int
jz4780_gpio_detach(device_t dev)373 jz4780_gpio_detach(device_t dev)
374 {
375 struct jz4780_gpio_softc *sc = device_get_softc(dev);
376
377 bus_release_resources(dev, jz4780_gpio_spec, sc->res);
378 JZ4780_GPIO_LOCK_DESTROY(sc);
379 return (0);
380 }
381
382 static int
jz4780_gpio_configure_pin(device_t dev,uint32_t pin,uint32_t func,uint32_t flags)383 jz4780_gpio_configure_pin(device_t dev, uint32_t pin, uint32_t func,
384 uint32_t flags)
385 {
386 struct jz4780_gpio_softc *sc;
387 int retval;
388
389 if (pin >= JZ4780_GPIO_PINS)
390 return (EINVAL);
391
392 sc = device_get_softc(dev);
393 JZ4780_GPIO_LOCK(sc);
394 retval = jz4780_gpio_pin_set_func(sc, pin, func);
395 if (retval == 0)
396 retval = jz4780_gpio_pin_set_bias(sc, pin, flags);
397 JZ4780_GPIO_UNLOCK(sc);
398 return (retval);
399 }
400
401 static device_t
jz4780_gpio_get_bus(device_t dev)402 jz4780_gpio_get_bus(device_t dev)
403 {
404 struct jz4780_gpio_softc *sc;
405
406 sc = device_get_softc(dev);
407
408 return (sc->busdev);
409 }
410
411 static int
jz4780_gpio_pin_max(device_t dev,int * maxpin)412 jz4780_gpio_pin_max(device_t dev, int *maxpin)
413 {
414
415 *maxpin = JZ4780_GPIO_PINS - 1;
416 return (0);
417 }
418
419 static int
jz4780_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)420 jz4780_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
421 {
422 struct jz4780_gpio_softc *sc;
423
424 if (pin >= JZ4780_GPIO_PINS)
425 return (EINVAL);
426
427 sc = device_get_softc(dev);
428 JZ4780_GPIO_LOCK(sc);
429 *caps = sc->pins[pin].pin_caps;
430 JZ4780_GPIO_UNLOCK(sc);
431
432 return (0);
433 }
434
435 static int
jz4780_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * flags)436 jz4780_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
437 {
438 struct jz4780_gpio_softc *sc;
439
440 if (pin >= JZ4780_GPIO_PINS)
441 return (EINVAL);
442
443 sc = device_get_softc(dev);
444 JZ4780_GPIO_LOCK(sc);
445 *flags = sc->pins[pin].pin_flags;
446 JZ4780_GPIO_UNLOCK(sc);
447
448 return (0);
449 }
450
451 static int
jz4780_gpio_pin_getname(device_t dev,uint32_t pin,char * name)452 jz4780_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
453 {
454 struct jz4780_gpio_softc *sc;
455
456 if (pin >= JZ4780_GPIO_PINS)
457 return (EINVAL);
458
459 sc = device_get_softc(dev);
460 strncpy(name, sc->pins[pin].pin_name, GPIOMAXNAME - 1);
461 name[GPIOMAXNAME - 1] = '\0';
462
463 return (0);
464 }
465
466 static int
jz4780_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)467 jz4780_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
468 {
469 struct jz4780_gpio_softc *sc;
470 int retval;
471
472 if (pin >= JZ4780_GPIO_PINS)
473 return (EINVAL);
474
475 sc = device_get_softc(dev);
476 JZ4780_GPIO_LOCK(sc);
477 retval = jz4780_gpio_pin_set_direction(sc, pin,
478 flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT));
479 if (retval == 0)
480 retval = jz4780_gpio_pin_set_bias(sc, pin,
481 flags & (GPIO_PIN_PULLDOWN | GPIO_PIN_PULLUP));
482 JZ4780_GPIO_UNLOCK(sc);
483
484 return (retval);
485 }
486
487 static int
jz4780_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)488 jz4780_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
489 {
490 struct jz4780_gpio_softc *sc;
491 uint32_t mask;
492 int retval;
493
494 if (pin >= JZ4780_GPIO_PINS)
495 return (EINVAL);
496
497 retval = EINVAL;
498 mask = (1u << pin);
499 sc = device_get_softc(dev);
500 JZ4780_GPIO_LOCK(sc);
501 if (sc->pins[pin].pin_func == JZ_FUNC_GPIO) {
502 CSR_WRITE_4(sc, value ? JZ_GPIO_PAT0S : JZ_GPIO_PAT0C, mask);
503 retval = 0;
504 }
505 JZ4780_GPIO_UNLOCK(sc);
506
507 return (retval);
508 }
509
510 static int
jz4780_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * val)511 jz4780_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
512 {
513 struct jz4780_gpio_softc *sc;
514 uint32_t data, mask;
515
516 if (pin >= JZ4780_GPIO_PINS)
517 return (EINVAL);
518
519 mask = (1u << pin);
520 sc = device_get_softc(dev);
521 JZ4780_GPIO_LOCK(sc);
522 data = CSR_READ_4(sc, JZ_GPIO_PIN);
523 JZ4780_GPIO_UNLOCK(sc);
524 *val = (data & mask) ? 1 : 0;
525
526 return (0);
527 }
528
529 static int
jz4780_gpio_pin_toggle(device_t dev,uint32_t pin)530 jz4780_gpio_pin_toggle(device_t dev, uint32_t pin)
531 {
532 struct jz4780_gpio_softc *sc;
533 uint32_t data, mask;
534 int retval;
535
536 if (pin >= JZ4780_GPIO_PINS)
537 return (EINVAL);
538
539 retval = EINVAL;
540 mask = (1u << pin);
541 sc = device_get_softc(dev);
542 JZ4780_GPIO_LOCK(sc);
543 if (sc->pins[pin].pin_func == JZ_FUNC_GPIO &&
544 sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT) {
545 data = CSR_READ_4(sc, JZ_GPIO_PIN);
546 CSR_WRITE_4(sc, (data & mask) ? JZ_GPIO_PAT0C : JZ_GPIO_PAT0S,
547 mask);
548 retval = 0;
549 }
550 JZ4780_GPIO_UNLOCK(sc);
551
552 return (retval);
553 }
554
555 #ifdef FDT
556 static int
jz_gpio_map_intr_fdt(device_t dev,struct intr_map_data * data,u_int * irqp,enum intr_polarity * polp,enum intr_trigger * trigp)557 jz_gpio_map_intr_fdt(device_t dev, struct intr_map_data *data, u_int *irqp,
558 enum intr_polarity *polp, enum intr_trigger *trigp)
559 {
560 struct jz4780_gpio_softc *sc;
561 struct intr_map_data_fdt *daf;
562
563 sc = device_get_softc(dev);
564 daf = (struct intr_map_data_fdt *)data;
565
566 if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
567 daf->ncells == 0 || daf->ncells > 2)
568 return (EINVAL);
569
570 *irqp = daf->cells[0];
571 if (daf->ncells == 1) {
572 *trigp = INTR_TRIGGER_CONFORM;
573 *polp = INTR_POLARITY_CONFORM;
574 return (0);
575 }
576
577 switch (daf->cells[1])
578 {
579 case IRQ_TYPE_EDGE_RISING:
580 *trigp = INTR_TRIGGER_EDGE;
581 *polp = INTR_POLARITY_HIGH;
582 break;
583 case IRQ_TYPE_EDGE_FALLING:
584 *trigp = INTR_TRIGGER_EDGE;
585 *polp = INTR_POLARITY_LOW;
586 break;
587 case IRQ_TYPE_LEVEL_HIGH:
588 *trigp = INTR_TRIGGER_LEVEL;
589 *polp = INTR_POLARITY_HIGH;
590 break;
591 case IRQ_TYPE_LEVEL_LOW:
592 *trigp = INTR_TRIGGER_LEVEL;
593 *polp = INTR_POLARITY_LOW;
594 break;
595 default:
596 device_printf(sc->dev, "unsupported trigger/polarity 0x%2x\n",
597 daf->cells[1]);
598 return (ENOTSUP);
599 }
600
601 return (0);
602 }
603 #endif
604
605 static int
jz_gpio_map_intr(device_t dev,struct intr_map_data * data,u_int * irqp,enum intr_polarity * polp,enum intr_trigger * trigp)606 jz_gpio_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
607 enum intr_polarity *polp, enum intr_trigger *trigp)
608 {
609 struct jz4780_gpio_softc *sc;
610 enum intr_polarity pol;
611 enum intr_trigger trig;
612 u_int irq;
613
614 sc = device_get_softc(dev);
615 switch (data->type) {
616 #ifdef FDT
617 case INTR_MAP_DATA_FDT:
618 if (jz_gpio_map_intr_fdt(dev, data, &irq, &pol, &trig) != 0)
619 return (EINVAL);
620 break;
621 #endif
622 default:
623 return (EINVAL);
624 }
625
626 if (irq >= nitems(sc->pins))
627 return (EINVAL);
628
629 *irqp = irq;
630 if (polp != NULL)
631 *polp = pol;
632 if (trigp != NULL)
633 *trigp = trig;
634 return (0);
635 }
636
637 static int
jz4780_gpio_pic_map_intr(device_t dev,struct intr_map_data * data,struct intr_irqsrc ** isrcp)638 jz4780_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
639 struct intr_irqsrc **isrcp)
640 {
641 struct jz4780_gpio_softc *sc;
642 int retval;
643 u_int irq;
644
645 retval = jz_gpio_map_intr(dev, data, &irq, NULL, NULL);
646 if (retval == 0) {
647 sc = device_get_softc(dev);
648 *isrcp = &sc->pins[irq].pin_irqsrc;
649 }
650 return (retval);
651 }
652
653 static int
jz4780_gpio_pic_setup_intr(device_t dev,struct intr_irqsrc * isrc,struct resource * res,struct intr_map_data * data)654 jz4780_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
655 struct resource *res, struct intr_map_data *data)
656 {
657 struct jz4780_gpio_softc *sc;
658 struct jz4780_gpio_pin *pin;
659 enum intr_polarity pol;
660 enum intr_trigger trig;
661 uint32_t mask, irq;
662
663 if (data == NULL)
664 return (ENOTSUP);
665
666 /* Get config for resource. */
667 if (jz_gpio_map_intr(dev, data, &irq, &pol, &trig))
668 return (EINVAL);
669
670 pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc);
671 if (isrc != &pin->pin_irqsrc)
672 return (EINVAL);
673
674 /* Compare config if this is not first setup. */
675 if (isrc->isrc_handlers != 0) {
676 if ((pol != INTR_POLARITY_CONFORM && pol != pin->intr_polarity) ||
677 (trig != INTR_TRIGGER_CONFORM && trig != pin->intr_trigger))
678 return (EINVAL);
679 else
680 return (0);
681 }
682
683 if (pol == INTR_POLARITY_CONFORM)
684 pol = INTR_POLARITY_LOW; /* just pick some */
685 if (trig == INTR_TRIGGER_CONFORM)
686 trig = INTR_TRIGGER_EDGE; /* just pick some */
687
688 sc = device_get_softc(dev);
689 mask = 1u << pin->pin_num;
690
691 JZ4780_GPIO_LOCK(sc);
692 CSR_WRITE_4(sc, JZ_GPIO_MASKS, mask);
693 CSR_WRITE_4(sc, JZ_GPIO_INTS, mask);
694
695 if (trig == INTR_TRIGGER_LEVEL)
696 CSR_WRITE_4(sc, JZ_GPIO_PAT1C, mask);
697 else
698 CSR_WRITE_4(sc, JZ_GPIO_PAT1S, mask);
699
700 if (pol == INTR_POLARITY_LOW)
701 CSR_WRITE_4(sc, JZ_GPIO_PAT0C, mask);
702 else
703 CSR_WRITE_4(sc, JZ_GPIO_PAT0S, mask);
704
705 pin->pin_func = JZ_FUNC_INTR;
706 pin->intr_trigger = trig;
707 pin->intr_polarity = pol;
708
709 CSR_WRITE_4(sc, JZ_GPIO_FLAGC, mask);
710 CSR_WRITE_4(sc, JZ_GPIO_MASKC, mask);
711 JZ4780_GPIO_UNLOCK(sc);
712 return (0);
713 }
714
715 static void
jz4780_gpio_pic_enable_intr(device_t dev,struct intr_irqsrc * isrc)716 jz4780_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
717 {
718 struct jz4780_gpio_softc *sc;
719 struct jz4780_gpio_pin *pin;
720
721 sc = device_get_softc(dev);
722 pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc);
723
724 CSR_WRITE_4(sc, JZ_GPIO_MASKC, 1u << pin->pin_num);
725 }
726
727 static void
jz4780_gpio_pic_disable_intr(device_t dev,struct intr_irqsrc * isrc)728 jz4780_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
729 {
730 struct jz4780_gpio_softc *sc;
731 struct jz4780_gpio_pin *pin;
732
733 sc = device_get_softc(dev);
734 pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc);
735
736 CSR_WRITE_4(sc, JZ_GPIO_MASKS, 1u << pin->pin_num);
737 }
738
739 static void
jz4780_gpio_pic_pre_ithread(device_t dev,struct intr_irqsrc * isrc)740 jz4780_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
741 {
742
743 jz4780_gpio_pic_disable_intr(dev, isrc);
744 }
745
746 static void
jz4780_gpio_pic_post_ithread(device_t dev,struct intr_irqsrc * isrc)747 jz4780_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
748 {
749
750 jz4780_gpio_pic_enable_intr(dev, isrc);
751 }
752
753 static void
jz4780_gpio_pic_post_filter(device_t dev,struct intr_irqsrc * isrc)754 jz4780_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
755 {
756 struct jz4780_gpio_softc *sc;
757 struct jz4780_gpio_pin *pin;
758
759 sc = device_get_softc(dev);
760 pin = __containerof(isrc, struct jz4780_gpio_pin, pin_irqsrc);
761
762 CSR_WRITE_4(sc, JZ_GPIO_FLAGC, 1u << pin->pin_num);
763 }
764
765 static int
jz4780_gpio_intr(void * arg)766 jz4780_gpio_intr(void *arg)
767 {
768 struct jz4780_gpio_softc *sc;
769 uint32_t i, interrupts;
770
771 sc = arg;
772 interrupts = CSR_READ_4(sc, JZ_GPIO_FLAG);
773
774 for (i = 0; interrupts != 0; i++, interrupts >>= 1) {
775 if ((interrupts & 0x1) == 0)
776 continue;
777 if (intr_isrc_dispatch(&sc->pins[i].pin_irqsrc,
778 curthread->td_intr_frame) != 0) {
779 device_printf(sc->dev, "spurious interrupt %d\n", i);
780 PIC_DISABLE_INTR(sc->dev, &sc->pins[i].pin_irqsrc);
781 }
782 }
783
784 return (FILTER_HANDLED);
785 }
786
787 static phandle_t
jz4780_gpio_bus_get_node(device_t bus,device_t dev)788 jz4780_gpio_bus_get_node(device_t bus, device_t dev)
789 {
790
791 return (ofw_bus_get_node(bus));
792 }
793
794 static device_method_t jz4780_gpio_methods[] = {
795 /* Device interface */
796 DEVMETHOD(device_probe, jz4780_gpio_probe),
797 DEVMETHOD(device_attach, jz4780_gpio_attach),
798 DEVMETHOD(device_detach, jz4780_gpio_detach),
799
800 /* GPIO protocol */
801 DEVMETHOD(gpio_get_bus, jz4780_gpio_get_bus),
802 DEVMETHOD(gpio_pin_max, jz4780_gpio_pin_max),
803 DEVMETHOD(gpio_pin_getname, jz4780_gpio_pin_getname),
804 DEVMETHOD(gpio_pin_getflags, jz4780_gpio_pin_getflags),
805 DEVMETHOD(gpio_pin_getcaps, jz4780_gpio_pin_getcaps),
806 DEVMETHOD(gpio_pin_setflags, jz4780_gpio_pin_setflags),
807 DEVMETHOD(gpio_pin_get, jz4780_gpio_pin_get),
808 DEVMETHOD(gpio_pin_set, jz4780_gpio_pin_set),
809 DEVMETHOD(gpio_pin_toggle, jz4780_gpio_pin_toggle),
810
811 /* Custom interface to set pin function */
812 DEVMETHOD(jz4780_gpio_configure_pin, jz4780_gpio_configure_pin),
813
814 /* Interrupt controller interface */
815 DEVMETHOD(pic_setup_intr, jz4780_gpio_pic_setup_intr),
816 DEVMETHOD(pic_enable_intr, jz4780_gpio_pic_enable_intr),
817 DEVMETHOD(pic_disable_intr, jz4780_gpio_pic_disable_intr),
818 DEVMETHOD(pic_map_intr, jz4780_gpio_pic_map_intr),
819 DEVMETHOD(pic_post_filter, jz4780_gpio_pic_post_filter),
820 DEVMETHOD(pic_post_ithread, jz4780_gpio_pic_post_ithread),
821 DEVMETHOD(pic_pre_ithread, jz4780_gpio_pic_pre_ithread),
822
823 /* ofw_bus interface */
824 DEVMETHOD(ofw_bus_get_node, jz4780_gpio_bus_get_node),
825
826 DEVMETHOD_END
827 };
828
829 static driver_t jz4780_gpio_driver = {
830 "gpio",
831 jz4780_gpio_methods,
832 sizeof(struct jz4780_gpio_softc),
833 };
834
835 static devclass_t jz4780_gpio_devclass;
836
837 EARLY_DRIVER_MODULE(jz4780_gpio, simplebus, jz4780_gpio_driver,
838 jz4780_gpio_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
839