2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
5 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
6 * Copyright (c) 2012 Luiz Otavio O Souza.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
40 #include <sys/mutex.h>
44 #include <machine/bus.h>
45 #include <machine/resource.h>
46 #include <machine/intr.h>
48 #include <dev/gpio/gpiobusvar.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51 #include <dev/fdt/fdt_pinctrl.h>
53 #include <arm/allwinner/aw_machdep.h>
54 #include <arm/allwinner/allwinner_pinctrl.h>
55 #include <dev/extres/clk/clk.h>
56 #include <dev/extres/hwreset/hwreset.h>
57 #include <dev/extres/regulator/regulator.h>
59 #if defined(__aarch64__)
66 #define AW_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
67 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
69 #define AW_GPIO_INTR_CAPS (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | \
70 GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
72 #define AW_GPIO_NONE 0
73 #define AW_GPIO_PULLUP 1
74 #define AW_GPIO_PULLDOWN 2
76 #define AW_GPIO_INPUT 0
77 #define AW_GPIO_OUTPUT 1
79 #define AW_GPIO_DRV_MASK 0x3
80 #define AW_GPIO_PUD_MASK 0x3
83 #define AW_R_PINCTRL 2
86 struct allwinner_padconf *padconf;
90 /* Defined in aw_padconf.c */
91 #ifdef SOC_ALLWINNER_A10
92 extern struct allwinner_padconf a10_padconf;
93 struct aw_gpio_conf a10_gpio_conf = {
94 .padconf = &a10_padconf,
99 /* Defined in a13_padconf.c */
100 #ifdef SOC_ALLWINNER_A13
101 extern struct allwinner_padconf a13_padconf;
102 struct aw_gpio_conf a13_gpio_conf = {
103 .padconf = &a13_padconf,
108 /* Defined in a20_padconf.c */
109 #ifdef SOC_ALLWINNER_A20
110 extern struct allwinner_padconf a20_padconf;
111 struct aw_gpio_conf a20_gpio_conf = {
112 .padconf = &a20_padconf,
113 .banks = "abcdefghi",
117 /* Defined in a31_padconf.c */
118 #ifdef SOC_ALLWINNER_A31
119 extern struct allwinner_padconf a31_padconf;
120 struct aw_gpio_conf a31_gpio_conf = {
121 .padconf = &a31_padconf,
126 /* Defined in a31s_padconf.c */
127 #ifdef SOC_ALLWINNER_A31S
128 extern struct allwinner_padconf a31s_padconf;
129 struct aw_gpio_conf a31s_gpio_conf = {
130 .padconf = &a31s_padconf,
135 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
136 extern struct allwinner_padconf a31_r_padconf;
137 struct aw_gpio_conf a31_r_gpio_conf = {
138 .padconf = &a31_r_padconf,
143 /* Defined in a33_padconf.c */
144 #ifdef SOC_ALLWINNER_A33
145 extern struct allwinner_padconf a33_padconf;
146 struct aw_gpio_conf a33_gpio_conf = {
147 .padconf = &a33_padconf,
152 /* Defined in h3_padconf.c */
153 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
154 extern struct allwinner_padconf h3_padconf;
155 extern struct allwinner_padconf h3_r_padconf;
156 struct aw_gpio_conf h3_gpio_conf = {
157 .padconf = &h3_padconf,
160 struct aw_gpio_conf h3_r_gpio_conf = {
161 .padconf = &h3_r_padconf,
166 /* Defined in a83t_padconf.c */
167 #ifdef SOC_ALLWINNER_A83T
168 extern struct allwinner_padconf a83t_padconf;
169 extern struct allwinner_padconf a83t_r_padconf;
170 struct aw_gpio_conf a83t_gpio_conf = {
171 .padconf = &a83t_padconf,
174 struct aw_gpio_conf a83t_r_gpio_conf = {
175 .padconf = &a83t_r_padconf,
180 /* Defined in a64_padconf.c */
181 #ifdef SOC_ALLWINNER_A64
182 extern struct allwinner_padconf a64_padconf;
183 extern struct allwinner_padconf a64_r_padconf;
184 struct aw_gpio_conf a64_gpio_conf = {
185 .padconf = &a64_padconf,
188 struct aw_gpio_conf a64_r_gpio_conf = {
189 .padconf = &a64_r_padconf,
194 /* Defined in h6_padconf.c */
195 #ifdef SOC_ALLWINNER_H6
196 extern struct allwinner_padconf h6_padconf;
197 extern struct allwinner_padconf h6_r_padconf;
198 struct aw_gpio_conf h6_gpio_conf = {
199 .padconf = &h6_padconf,
202 struct aw_gpio_conf h6_r_gpio_conf = {
203 .padconf = &h6_r_padconf,
208 static struct ofw_compat_data compat_data[] = {
209 #ifdef SOC_ALLWINNER_A10
210 {"allwinner,sun4i-a10-pinctrl", (uintptr_t)&a10_gpio_conf},
212 #ifdef SOC_ALLWINNER_A13
213 {"allwinner,sun5i-a13-pinctrl", (uintptr_t)&a13_gpio_conf},
215 #ifdef SOC_ALLWINNER_A20
216 {"allwinner,sun7i-a20-pinctrl", (uintptr_t)&a20_gpio_conf},
218 #ifdef SOC_ALLWINNER_A31
219 {"allwinner,sun6i-a31-pinctrl", (uintptr_t)&a31_gpio_conf},
221 #ifdef SOC_ALLWINNER_A31S
222 {"allwinner,sun6i-a31s-pinctrl", (uintptr_t)&a31s_gpio_conf},
224 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
225 {"allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&a31_r_gpio_conf},
227 #ifdef SOC_ALLWINNER_A33
228 {"allwinner,sun6i-a33-pinctrl", (uintptr_t)&a33_gpio_conf},
230 #ifdef SOC_ALLWINNER_A83T
231 {"allwinner,sun8i-a83t-pinctrl", (uintptr_t)&a83t_gpio_conf},
232 {"allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&a83t_r_gpio_conf},
234 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
235 {"allwinner,sun8i-h3-pinctrl", (uintptr_t)&h3_gpio_conf},
236 {"allwinner,sun50i-h5-pinctrl", (uintptr_t)&h3_gpio_conf},
237 {"allwinner,sun8i-h3-r-pinctrl", (uintptr_t)&h3_r_gpio_conf},
239 #ifdef SOC_ALLWINNER_A64
240 {"allwinner,sun50i-a64-pinctrl", (uintptr_t)&a64_gpio_conf},
241 {"allwinner,sun50i-a64-r-pinctrl", (uintptr_t)&a64_r_gpio_conf},
243 #ifdef SOC_ALLWINNER_H6
244 {"allwinner,sun50i-h6-pinctrl", (uintptr_t)&h6_gpio_conf},
245 {"allwinner,sun50i-h6-r-pinctrl", (uintptr_t)&h6_r_gpio_conf},
251 TAILQ_ENTRY(clk_list) next;
256 struct intr_irqsrc isrc;
267 #define AW_GPIO_MEMRES 0
268 #define AW_GPIO_IRQRES 1
269 #define AW_GPIO_RESSZ 2
271 struct aw_gpio_softc {
274 struct resource * sc_res[AW_GPIO_RESSZ];
276 struct resource * sc_mem_res;
277 struct resource * sc_irq_res;
279 struct aw_gpio_conf *conf;
280 TAILQ_HEAD(, clk_list) clk_list;
282 struct gpio_irqsrc *gpio_pic_irqsrc;
286 static struct resource_spec aw_gpio_res_spec[] = {
287 { SYS_RES_MEMORY, 0, RF_ACTIVE },
288 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
292 #define AW_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
293 #define AW_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
294 #define AW_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
296 #define AW_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2)
297 #define AW_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24)
298 #define AW_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2)
299 #define AW_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2)
301 #define AW_GPIO_GP_INT_BASE(_bank) (0x200 + 0x20 * _bank)
303 #define AW_GPIO_GP_INT_CFG(_bank, _pin) (AW_GPIO_GP_INT_BASE(_bank) + (0x4 * ((_pin) / 8)))
304 #define AW_GPIO_GP_INT_CTL(_bank) (AW_GPIO_GP_INT_BASE(_bank) + 0x10)
305 #define AW_GPIO_GP_INT_STA(_bank) (AW_GPIO_GP_INT_BASE(_bank) + 0x14)
306 #define AW_GPIO_GP_INT_DEB(_bank) (AW_GPIO_GP_INT_BASE(_bank) + 0x18)
308 #define AW_GPIO_INT_EDGE_POSITIVE 0x0
309 #define AW_GPIO_INT_EDGE_NEGATIVE 0x1
310 #define AW_GPIO_INT_LEVEL_HIGH 0x2
311 #define AW_GPIO_INT_LEVEL_LOW 0x3
312 #define AW_GPIO_INT_EDGE_BOTH 0x4
314 static char *aw_gpio_parse_function(phandle_t node);
315 static const char **aw_gpio_parse_pins(phandle_t node, int *pins_nb);
316 static uint32_t aw_gpio_parse_bias(phandle_t node);
317 static int aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive);
319 static int aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value);
320 static int aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
321 static int aw_gpio_pin_get_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int *value);
322 static int aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int value);
324 static void aw_gpio_intr(void *arg);
325 static void aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc);
326 static void aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc);
327 static void aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc);
328 static int aw_gpio_register_isrcs(struct aw_gpio_softc *sc);
330 #define AW_GPIO_WRITE(_sc, _off, _val) \
331 bus_write_4((_sc)->sc_res[AW_GPIO_MEMRES], _off, _val)
332 #define AW_GPIO_READ(_sc, _off) \
333 bus_read_4((_sc)->sc_res[AW_GPIO_MEMRES], _off)
336 aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin)
338 uint32_t bank, func, offset;
340 /* Must be called with lock held. */
341 AW_GPIO_LOCK_ASSERT(sc);
343 if (pin > sc->conf->padconf->npins)
345 bank = sc->conf->padconf->pins[pin].port;
346 pin = sc->conf->padconf->pins[pin].pin;
347 offset = ((pin & 0x07) << 2);
349 func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
351 return ((func >> offset) & 0x7);
355 aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f)
357 uint32_t bank, data, offset;
359 /* Check if the function exists in the padconf data */
360 if (sc->conf->padconf->pins[pin].functions[f] == NULL)
363 /* Must be called with lock held. */
364 AW_GPIO_LOCK_ASSERT(sc);
366 bank = sc->conf->padconf->pins[pin].port;
367 pin = sc->conf->padconf->pins[pin].pin;
368 offset = ((pin & 0x07) << 2);
370 data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
371 data &= ~(7 << offset);
372 data |= (f << offset);
373 AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data);
379 aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin)
381 uint32_t bank, offset, val;
383 /* Must be called with lock held. */
384 AW_GPIO_LOCK_ASSERT(sc);
386 bank = sc->conf->padconf->pins[pin].port;
387 pin = sc->conf->padconf->pins[pin].pin;
388 offset = ((pin & 0x0f) << 1);
390 val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
392 return ((val >> offset) & AW_GPIO_PUD_MASK);
396 aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state)
398 uint32_t bank, offset, val;
400 if (aw_gpio_get_pud(sc, pin) == state)
403 /* Must be called with lock held. */
404 AW_GPIO_LOCK_ASSERT(sc);
406 bank = sc->conf->padconf->pins[pin].port;
407 pin = sc->conf->padconf->pins[pin].pin;
408 offset = ((pin & 0x0f) << 1);
410 val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
411 val &= ~(AW_GPIO_PUD_MASK << offset);
412 val |= (state << offset);
413 AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val);
417 aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin)
419 uint32_t bank, offset, val;
421 /* Must be called with lock held. */
422 AW_GPIO_LOCK_ASSERT(sc);
424 bank = sc->conf->padconf->pins[pin].port;
425 pin = sc->conf->padconf->pins[pin].pin;
426 offset = ((pin & 0x0f) << 1);
428 val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
430 return ((val >> offset) & AW_GPIO_DRV_MASK);
434 aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive)
436 uint32_t bank, offset, val;
438 if (aw_gpio_get_drv(sc, pin) == drive)
441 /* Must be called with lock held. */
442 AW_GPIO_LOCK_ASSERT(sc);
444 bank = sc->conf->padconf->pins[pin].port;
445 pin = sc->conf->padconf->pins[pin].pin;
446 offset = ((pin & 0x0f) << 1);
448 val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
449 val &= ~(AW_GPIO_DRV_MASK << offset);
450 val |= (drive << offset);
451 AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(bank, pin >> 4), val);
455 aw_gpio_pin_configure(struct aw_gpio_softc *sc, uint32_t pin, uint32_t flags)
460 /* Must be called with lock held. */
461 AW_GPIO_LOCK_ASSERT(sc);
463 if (pin > sc->conf->padconf->npins)
466 /* Manage input/output. */
467 if (flags & GPIO_PIN_INPUT) {
468 err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
469 } else if ((flags & GPIO_PIN_OUTPUT) &&
470 aw_gpio_get_function(sc, pin) != AW_GPIO_OUTPUT) {
471 if (flags & GPIO_PIN_PRESET_LOW) {
472 aw_gpio_pin_set_locked(sc, pin, 0);
473 } else if (flags & GPIO_PIN_PRESET_HIGH) {
474 aw_gpio_pin_set_locked(sc, pin, 1);
476 /* Read the pin and preset output to current state. */
477 err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
479 aw_gpio_pin_get_locked(sc, pin, &val);
480 aw_gpio_pin_set_locked(sc, pin, val);
484 err = aw_gpio_set_function(sc, pin, AW_GPIO_OUTPUT);
490 /* Manage Pull-up/pull-down. */
491 if (flags & GPIO_PIN_PULLUP)
492 aw_gpio_set_pud(sc, pin, AW_GPIO_PULLUP);
493 else if (flags & GPIO_PIN_PULLDOWN)
494 aw_gpio_set_pud(sc, pin, AW_GPIO_PULLDOWN);
496 aw_gpio_set_pud(sc, pin, AW_GPIO_NONE);
502 aw_gpio_get_bus(device_t dev)
504 struct aw_gpio_softc *sc;
506 sc = device_get_softc(dev);
508 return (sc->sc_busdev);
512 aw_gpio_pin_max(device_t dev, int *maxpin)
514 struct aw_gpio_softc *sc;
516 sc = device_get_softc(dev);
518 *maxpin = sc->conf->padconf->npins - 1;
523 aw_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
525 struct aw_gpio_softc *sc;
527 sc = device_get_softc(dev);
528 if (pin >= sc->conf->padconf->npins)
531 *caps = AW_GPIO_DEFAULT_CAPS;
532 if (sc->conf->padconf->pins[pin].eint_func != 0)
533 *caps |= AW_GPIO_INTR_CAPS;
539 aw_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
541 struct aw_gpio_softc *sc;
545 sc = device_get_softc(dev);
546 if (pin >= sc->conf->padconf->npins)
550 func = aw_gpio_get_function(sc, pin);
553 *flags = GPIO_PIN_INPUT;
556 *flags = GPIO_PIN_OUTPUT;
563 pud = aw_gpio_get_pud(sc, pin);
565 case AW_GPIO_PULLDOWN:
566 *flags |= GPIO_PIN_PULLDOWN;
569 *flags |= GPIO_PIN_PULLUP;
581 aw_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
583 struct aw_gpio_softc *sc;
585 sc = device_get_softc(dev);
586 if (pin >= sc->conf->padconf->npins)
589 snprintf(name, GPIOMAXNAME - 1, "%s",
590 sc->conf->padconf->pins[pin].name);
591 name[GPIOMAXNAME - 1] = '\0';
597 aw_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
599 struct aw_gpio_softc *sc;
602 sc = device_get_softc(dev);
603 if (pin > sc->conf->padconf->npins)
607 err = aw_gpio_pin_configure(sc, pin, flags);
614 aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin,
619 AW_GPIO_LOCK_ASSERT(sc);
621 if (pin > sc->conf->padconf->npins)
624 bank = sc->conf->padconf->pins[pin].port;
625 pin = sc->conf->padconf->pins[pin].pin;
627 data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
632 AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
638 aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
640 struct aw_gpio_softc *sc;
643 sc = device_get_softc(dev);
646 ret = aw_gpio_pin_set_locked(sc, pin, value);
653 aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin,
656 uint32_t bank, reg_data;
658 AW_GPIO_LOCK_ASSERT(sc);
660 if (pin > sc->conf->padconf->npins)
663 bank = sc->conf->padconf->pins[pin].port;
664 pin = sc->conf->padconf->pins[pin].pin;
666 reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
667 *val = (reg_data & (1 << pin)) ? 1 : 0;
673 aw_gpio_parse_function(phandle_t node)
677 if (OF_getprop_alloc(node, "function",
678 (void **)&function) != -1)
680 if (OF_getprop_alloc(node, "allwinner,function",
681 (void **)&function) != -1)
688 aw_gpio_parse_pins(phandle_t node, int *pins_nb)
690 const char **pinlist;
692 *pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist);
696 *pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins",
705 aw_gpio_parse_bias(phandle_t node)
709 if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1)
711 if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1)
713 if (OF_hasprop(node, "bias-disable"))
714 return (AW_GPIO_NONE);
715 if (OF_hasprop(node, "bias-pull-up"))
716 return (AW_GPIO_PULLUP);
717 if (OF_hasprop(node, "bias-pull-down"))
718 return (AW_GPIO_PULLDOWN);
720 return (AW_GPIO_NONE);
724 aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive)
728 if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1)
730 if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1)
732 if (OF_getencprop(node, "drive-strength", &drive_str,
733 sizeof(drive_str)) != -1) {
734 *drive = (drive_str / 10) - 1;
742 aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
744 struct aw_gpio_softc *sc;
747 sc = device_get_softc(dev);
750 ret = aw_gpio_pin_get_locked(sc, pin, val);
757 aw_gpio_pin_toggle(device_t dev, uint32_t pin)
759 struct aw_gpio_softc *sc;
762 sc = device_get_softc(dev);
763 if (pin > sc->conf->padconf->npins)
766 bank = sc->conf->padconf->pins[pin].port;
767 pin = sc->conf->padconf->pins[pin].pin;
770 data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
771 if (data & (1 << pin))
775 AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
782 aw_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
783 uint32_t change_pins, uint32_t *orig_pins)
785 struct aw_gpio_softc *sc;
786 uint32_t bank, data, pin;
788 sc = device_get_softc(dev);
789 if (first_pin > sc->conf->padconf->npins)
793 * We require that first_pin refers to the first pin in a bank, because
794 * this API is not about convenience, it's for making a set of pins
795 * change simultaneously (required) with reasonably high performance
796 * (desired); we need to do a read-modify-write on a single register.
798 bank = sc->conf->padconf->pins[first_pin].port;
799 pin = sc->conf->padconf->pins[first_pin].pin;
804 data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
805 if ((clear_pins | change_pins) != 0)
806 AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank),
807 (data & ~clear_pins) ^ change_pins);
810 if (orig_pins != NULL)
817 aw_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
820 struct aw_gpio_softc *sc;
824 sc = device_get_softc(dev);
825 if (first_pin > sc->conf->padconf->npins)
828 if (sc->conf->padconf->pins[first_pin].pin != 0)
832 * The configuration for a bank of pins is scattered among several
833 * registers; we cannot g'tee to simultaneously change the state of all
834 * the pins in the flags array. So just loop through the array
835 * configuring each pin for now. If there was a strong need, it might
836 * be possible to support some limited simultaneous config, such as
837 * adjacent groups of 8 pins that line up the same as the config regs.
839 for (err = 0, pin = first_pin; err == 0 && pin < num_pins; ++pin) {
840 if (pin_flags[pin] & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
841 err = aw_gpio_pin_configure(sc, pin, pin_flags[pin]);
848 aw_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
849 pcell_t *gpios, uint32_t *pin, uint32_t *flags)
851 struct aw_gpio_softc *sc;
854 sc = device_get_softc(bus);
856 /* The GPIO pins are mapped as: <gpio-phandle bank pin flags>. */
857 for (i = 0; i < sc->conf->padconf->npins; i++)
858 if (sc->conf->padconf->pins[i].port == gpios[0] &&
859 sc->conf->padconf->pins[i].pin == gpios[1]) {
863 *flags = gpios[gcells - 1];
869 aw_find_pinnum_by_name(struct aw_gpio_softc *sc, const char *pinname)
873 for (i = 0; i < sc->conf->padconf->npins; i++)
874 if (!strcmp(pinname, sc->conf->padconf->pins[i].name))
881 aw_find_pin_func(struct aw_gpio_softc *sc, int pin, const char *func)
885 for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++)
886 if (sc->conf->padconf->pins[pin].functions[i] &&
887 !strcmp(func, sc->conf->padconf->pins[pin].functions[i]))
894 aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
896 struct aw_gpio_softc *sc;
898 const char **pinlist = NULL;
899 char *pin_function = NULL;
900 uint32_t pin_drive, pin_pull;
901 int pins_nb, pin_num, pin_func, i, ret;
904 sc = device_get_softc(dev);
905 node = OF_node_from_xref(cfgxref);
909 /* Getting all prop for configuring pins */
910 pinlist = aw_gpio_parse_pins(node, &pins_nb);
914 pin_function = aw_gpio_parse_function(node);
915 if (pin_function == NULL) {
920 if (aw_gpio_parse_drive_strength(node, &pin_drive) == 0)
923 pin_pull = aw_gpio_parse_bias(node);
925 /* Configure each pin to the correct function, drive and pull */
926 for (i = 0; i < pins_nb; i++) {
927 pin_num = aw_find_pinnum_by_name(sc, pinlist[i]);
932 pin_func = aw_find_pin_func(sc, pin_num, pin_function);
933 if (pin_func == -1) {
940 if (aw_gpio_get_function(sc, pin_num) != pin_func)
941 aw_gpio_set_function(sc, pin_num, pin_func);
943 aw_gpio_set_drv(sc, pin_num, pin_drive);
944 if (pin_pull != AW_GPIO_NONE)
945 aw_gpio_set_pud(sc, pin_num, pin_pull);
951 OF_prop_free(pinlist);
952 OF_prop_free(pin_function);
957 aw_gpio_enable_bank_supply(void *arg)
959 struct aw_gpio_softc *sc = arg;
960 regulator_t vcc_supply;
961 char bank_reg_name[16];
964 nbanks = strlen(sc->conf->banks);
965 for (i = 0; i < nbanks; i++) {
966 snprintf(bank_reg_name, sizeof(bank_reg_name), "vcc-p%c-supply",
969 if (regulator_get_by_ofw_property(sc->sc_dev, 0, bank_reg_name, &vcc_supply) == 0) {
971 device_printf(sc->sc_dev,
972 "Enabling regulator for gpio bank %c\n",
974 if (regulator_enable(vcc_supply) != 0) {
975 device_printf(sc->sc_dev,
976 "Cannot enable regulator for bank %c\n",
984 aw_gpio_probe(device_t dev)
987 if (!ofw_bus_status_okay(dev))
990 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
993 device_set_desc(dev, "Allwinner GPIO/Pinmux controller");
994 return (BUS_PROBE_DEFAULT);
998 aw_gpio_attach(device_t dev)
1002 struct aw_gpio_softc *sc;
1003 struct clk_list *clkp, *clkp_tmp;
1005 hwreset_t rst = NULL;
1006 int off, err, clkret;
1008 sc = device_get_softc(dev);
1011 mtx_init(&sc->sc_mtx, "aw gpio", "gpio", MTX_SPIN);
1013 if (bus_alloc_resources(dev, aw_gpio_res_spec, sc->sc_res) != 0) {
1014 device_printf(dev, "cannot allocate device resources\n");
1018 if (bus_setup_intr(dev, sc->sc_res[AW_GPIO_IRQRES],
1019 INTR_TYPE_CLK | INTR_MPSAFE, NULL, aw_gpio_intr, sc,
1020 &sc->sc_intrhand)) {
1021 device_printf(dev, "cannot setup interrupt handler\n");
1025 /* Find our node. */
1026 gpio = ofw_bus_get_node(sc->sc_dev);
1027 if (!OF_hasprop(gpio, "gpio-controller"))
1028 /* Node is not a GPIO controller. */
1031 /* Use the right pin data for the current SoC */
1032 sc->conf = (struct aw_gpio_conf *)ofw_bus_search_compatible(dev,
1033 compat_data)->ocd_data;
1035 if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
1036 error = hwreset_deassert(rst);
1038 device_printf(dev, "cannot de-assert reset\n");
1043 TAILQ_INIT(&sc->clk_list);
1044 for (off = 0, clkret = 0; clkret == 0; off++) {
1045 clkret = clk_get_by_ofw_index(dev, 0, off, &clk);
1048 err = clk_enable(clk);
1050 device_printf(dev, "Could not enable clock %s\n",
1054 clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO);
1056 TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
1058 if (clkret != 0 && clkret != ENOENT) {
1059 device_printf(dev, "Could not find clock at offset %d (%d)\n",
1064 aw_gpio_register_isrcs(sc);
1065 intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
1067 sc->sc_busdev = gpiobus_attach_bus(dev);
1068 if (sc->sc_busdev == NULL)
1072 * Register as a pinctrl device
1074 fdt_pinctrl_register(dev, "pins");
1075 fdt_pinctrl_configure_tree(dev);
1076 fdt_pinctrl_register(dev, "allwinner,pins");
1077 fdt_pinctrl_configure_tree(dev);
1079 config_intrhook_oneshot(aw_gpio_enable_bank_supply, sc);
1085 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
1087 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
1088 mtx_destroy(&sc->sc_mtx);
1091 TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
1092 err = clk_disable(clkp->clk);
1094 device_printf(dev, "Could not disable clock %s\n",
1095 clk_get_name(clkp->clk));
1096 err = clk_release(clkp->clk);
1098 device_printf(dev, "Could not release clock %s\n",
1099 clk_get_name(clkp->clk));
1100 TAILQ_REMOVE(&sc->clk_list, clkp, next);
1101 free(clkp, M_DEVBUF);
1106 hwreset_assert(rst);
1107 hwreset_release(rst);
1114 aw_gpio_detach(device_t dev)
1121 aw_gpio_intr(void *arg)
1123 struct aw_gpio_softc *sc;
1124 struct intr_irqsrc *isrc;
1128 sc = (struct aw_gpio_softc *)arg;
1131 for (irq = 0; irq < sc->nirqs; irq++) {
1132 if (!sc->gpio_pic_irqsrc[irq].enabled)
1135 reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_STA(sc->gpio_pic_irqsrc[irq].bank));
1136 if (!(reg & (1 << sc->gpio_pic_irqsrc[irq].intnum)))
1139 isrc = &sc->gpio_pic_irqsrc[irq].isrc;
1140 if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) {
1141 aw_gpio_pic_disable_intr_locked(sc, isrc);
1142 aw_gpio_pic_post_filter(sc->sc_dev, isrc);
1143 device_printf(sc->sc_dev, "Stray irq %u disabled\n", irq);
1150 * Interrupts support
1154 aw_gpio_register_isrcs(struct aw_gpio_softc *sc)
1161 name = device_get_nameunit(sc->sc_dev);
1163 for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
1164 if (sc->conf->padconf->pins[pin].eint_func == 0)
1170 sc->gpio_pic_irqsrc = malloc(sizeof(*sc->gpio_pic_irqsrc) * nirqs,
1171 M_DEVBUF, M_WAITOK | M_ZERO);
1172 for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
1173 if (sc->conf->padconf->pins[pin].eint_func == 0)
1176 sc->gpio_pic_irqsrc[nirqs].pin = pin;
1177 sc->gpio_pic_irqsrc[nirqs].bank = sc->conf->padconf->pins[pin].eint_bank;
1178 sc->gpio_pic_irqsrc[nirqs].intnum = sc->conf->padconf->pins[pin].eint_num;
1179 sc->gpio_pic_irqsrc[nirqs].intfunc = sc->conf->padconf->pins[pin].eint_func;
1180 sc->gpio_pic_irqsrc[nirqs].irq = nirqs;
1181 sc->gpio_pic_irqsrc[nirqs].mode = GPIO_INTR_CONFORM;
1183 err = intr_isrc_register(&sc->gpio_pic_irqsrc[nirqs].isrc,
1184 sc->sc_dev, 0, "%s,%s", name,
1185 sc->conf->padconf->pins[pin].functions[sc->conf->padconf->pins[pin].eint_func]);
1187 device_printf(sc->sc_dev, "intr_isrs_register failed for irq %d\n", nirqs);
1199 aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc)
1204 AW_GPIO_LOCK_ASSERT(sc);
1205 irq = ((struct gpio_irqsrc *)isrc)->irq;
1206 reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
1207 reg &= ~(1 << sc->gpio_pic_irqsrc[irq].intnum);
1208 AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
1210 sc->gpio_pic_irqsrc[irq].enabled = false;
1214 aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
1216 struct aw_gpio_softc *sc;
1218 sc = device_get_softc(dev);
1221 aw_gpio_pic_disable_intr_locked(sc, isrc);
1226 aw_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
1228 struct aw_gpio_softc *sc;
1232 sc = device_get_softc(dev);
1233 irq = ((struct gpio_irqsrc *)isrc)->irq;
1235 reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
1236 reg |= 1 << sc->gpio_pic_irqsrc[irq].intnum;
1237 AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
1240 sc->gpio_pic_irqsrc[irq].enabled = true;
1244 aw_gpio_pic_map_gpio(struct aw_gpio_softc *sc, struct intr_map_data_gpio *dag,
1245 u_int *irqp, u_int *mode)
1250 irq = dag->gpio_pin_num;
1252 for (pin = 0; pin < sc->nirqs; pin++)
1253 if (sc->gpio_pic_irqsrc[pin].pin == irq)
1255 if (pin == sc->nirqs) {
1256 device_printf(sc->sc_dev, "Invalid interrupt number %u\n", irq);
1260 switch (dag->gpio_intr_mode) {
1261 case GPIO_INTR_LEVEL_LOW:
1262 case GPIO_INTR_LEVEL_HIGH:
1263 case GPIO_INTR_EDGE_RISING:
1264 case GPIO_INTR_EDGE_FALLING:
1265 case GPIO_INTR_EDGE_BOTH:
1268 device_printf(sc->sc_dev, "Unsupported interrupt mode 0x%8x\n",
1269 dag->gpio_intr_mode);
1275 *mode = dag->gpio_intr_mode;
1281 aw_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
1282 struct intr_irqsrc **isrcp)
1284 struct aw_gpio_softc *sc;
1288 sc = device_get_softc(dev);
1289 switch (data->type) {
1290 case INTR_MAP_DATA_GPIO:
1291 err = aw_gpio_pic_map_gpio(sc,
1292 (struct intr_map_data_gpio *)data,
1300 *isrcp = &sc->gpio_pic_irqsrc[irq].isrc;
1305 aw_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
1306 struct resource *res, struct intr_map_data *data)
1308 struct aw_gpio_softc *sc;
1310 uint32_t pinidx, reg;
1314 sc = device_get_softc(dev);
1317 switch (data->type) {
1318 case INTR_MAP_DATA_GPIO:
1319 err = aw_gpio_pic_map_gpio(sc,
1320 (struct intr_map_data_gpio *)data,
1329 pinidx = (sc->gpio_pic_irqsrc[irq].intnum % 8) * 4;
1333 case GPIO_INTR_LEVEL_LOW:
1334 irqcfg = AW_GPIO_INT_LEVEL_LOW << pinidx;
1336 case GPIO_INTR_LEVEL_HIGH:
1337 irqcfg = AW_GPIO_INT_LEVEL_HIGH << pinidx;
1339 case GPIO_INTR_EDGE_RISING:
1340 irqcfg = AW_GPIO_INT_EDGE_POSITIVE << pinidx;
1342 case GPIO_INTR_EDGE_FALLING:
1343 irqcfg = AW_GPIO_INT_EDGE_NEGATIVE << pinidx;
1345 case GPIO_INTR_EDGE_BOTH:
1346 irqcfg = AW_GPIO_INT_EDGE_BOTH << pinidx;
1350 /* Switch the pin to interrupt mode */
1351 sc->gpio_pic_irqsrc[irq].oldfunc = aw_gpio_get_function(sc,
1352 sc->gpio_pic_irqsrc[irq].pin);
1353 aw_gpio_set_function(sc, sc->gpio_pic_irqsrc[irq].pin,
1354 sc->gpio_pic_irqsrc[irq].intfunc);
1356 /* Write interrupt mode */
1357 reg = AW_GPIO_READ(sc,
1358 AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
1359 sc->gpio_pic_irqsrc[irq].intnum));
1360 reg &= ~(0xF << pinidx);
1363 AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
1364 sc->gpio_pic_irqsrc[irq].intnum),
1373 aw_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
1374 struct resource *res, struct intr_map_data *data)
1376 struct aw_gpio_softc *sc;
1377 struct gpio_irqsrc *gi;
1379 sc = device_get_softc(dev);
1380 gi = (struct gpio_irqsrc *)isrc;
1382 /* Switch back the pin to it's original function */
1384 aw_gpio_set_function(sc, gi->pin, gi->oldfunc);
1391 aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
1393 struct aw_gpio_softc *sc;
1394 struct gpio_irqsrc *gi;
1396 sc = device_get_softc(dev);
1397 gi = (struct gpio_irqsrc *)isrc;
1399 arm_irq_memory_barrier(0);
1400 AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
1404 aw_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
1406 struct aw_gpio_softc *sc;
1407 struct gpio_irqsrc *gi;
1409 sc = device_get_softc(dev);
1410 gi = (struct gpio_irqsrc *)isrc;
1412 arm_irq_memory_barrier(0);
1413 AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
1414 aw_gpio_pic_enable_intr(dev, isrc);
1418 aw_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
1420 struct aw_gpio_softc *sc;
1422 sc = device_get_softc(dev);
1423 aw_gpio_pic_disable_intr_locked(sc, isrc);
1430 aw_gpio_get_node(device_t dev, device_t bus)
1433 /* We only have one child, the GPIO bus, which needs our own node. */
1434 return (ofw_bus_get_node(dev));
1437 static device_method_t aw_gpio_methods[] = {
1438 /* Device interface */
1439 DEVMETHOD(device_probe, aw_gpio_probe),
1440 DEVMETHOD(device_attach, aw_gpio_attach),
1441 DEVMETHOD(device_detach, aw_gpio_detach),
1443 /* Interrupt controller interface */
1444 DEVMETHOD(pic_disable_intr, aw_gpio_pic_disable_intr),
1445 DEVMETHOD(pic_enable_intr, aw_gpio_pic_enable_intr),
1446 DEVMETHOD(pic_map_intr, aw_gpio_pic_map_intr),
1447 DEVMETHOD(pic_setup_intr, aw_gpio_pic_setup_intr),
1448 DEVMETHOD(pic_teardown_intr, aw_gpio_pic_teardown_intr),
1449 DEVMETHOD(pic_post_filter, aw_gpio_pic_post_filter),
1450 DEVMETHOD(pic_post_ithread, aw_gpio_pic_post_ithread),
1451 DEVMETHOD(pic_pre_ithread, aw_gpio_pic_pre_ithread),
1454 DEVMETHOD(gpio_get_bus, aw_gpio_get_bus),
1455 DEVMETHOD(gpio_pin_max, aw_gpio_pin_max),
1456 DEVMETHOD(gpio_pin_getname, aw_gpio_pin_getname),
1457 DEVMETHOD(gpio_pin_getflags, aw_gpio_pin_getflags),
1458 DEVMETHOD(gpio_pin_getcaps, aw_gpio_pin_getcaps),
1459 DEVMETHOD(gpio_pin_setflags, aw_gpio_pin_setflags),
1460 DEVMETHOD(gpio_pin_get, aw_gpio_pin_get),
1461 DEVMETHOD(gpio_pin_set, aw_gpio_pin_set),
1462 DEVMETHOD(gpio_pin_toggle, aw_gpio_pin_toggle),
1463 DEVMETHOD(gpio_pin_access_32, aw_gpio_pin_access_32),
1464 DEVMETHOD(gpio_pin_config_32, aw_gpio_pin_config_32),
1465 DEVMETHOD(gpio_map_gpios, aw_gpio_map_gpios),
1467 /* ofw_bus interface */
1468 DEVMETHOD(ofw_bus_get_node, aw_gpio_get_node),
1470 /* fdt_pinctrl interface */
1471 DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins),
1476 static driver_t aw_gpio_driver = {
1479 sizeof(struct aw_gpio_softc),
1482 EARLY_DRIVER_MODULE(aw_gpio, simplebus, aw_gpio_driver, 0, 0,
1483 BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);