15bae2aceSJari Sihvola /*
25bae2aceSJari Sihvola * SPDX-License-Identifier: BSD-2-Clause
35bae2aceSJari Sihvola *
45bae2aceSJari Sihvola * Copyright (c) 2023 Jari Sihvola <jsihv@gmx.com>
55bae2aceSJari Sihvola */
65bae2aceSJari Sihvola
75bae2aceSJari Sihvola #include <sys/cdefs.h>
85bae2aceSJari Sihvola
95bae2aceSJari Sihvola #include <sys/param.h>
105bae2aceSJari Sihvola #include <sys/systm.h>
115bae2aceSJari Sihvola #include <sys/bus.h>
125bae2aceSJari Sihvola
135bae2aceSJari Sihvola #include <sys/gpio.h>
145bae2aceSJari Sihvola #include <sys/kernel.h>
155bae2aceSJari Sihvola #include <sys/lock.h>
165bae2aceSJari Sihvola #include <sys/module.h>
175bae2aceSJari Sihvola #include <sys/mutex.h>
185bae2aceSJari Sihvola #include <sys/rman.h>
195bae2aceSJari Sihvola
205bae2aceSJari Sihvola #include <machine/bus.h>
215bae2aceSJari Sihvola #include <machine/intr.h>
225bae2aceSJari Sihvola #include <machine/resource.h>
235bae2aceSJari Sihvola
245bae2aceSJari Sihvola #include <dev/clk/clk.h>
255bae2aceSJari Sihvola #include <dev/gpio/gpiobusvar.h>
265bae2aceSJari Sihvola #include <dev/ofw/ofw_bus.h>
275bae2aceSJari Sihvola #include <dev/ofw/ofw_bus_subr.h>
285bae2aceSJari Sihvola
295bae2aceSJari Sihvola #include "gpio_if.h"
305bae2aceSJari Sihvola
315bae2aceSJari Sihvola #define GPIO_PINS 64
325bae2aceSJari Sihvola #define GPIO_REGS 2
335bae2aceSJari Sihvola
345bae2aceSJari Sihvola #define GP0_DOEN_CFG 0x0
355bae2aceSJari Sihvola #define GP0_DOUT_CFG 0x40
365bae2aceSJari Sihvola #define GPIOEN 0xdc
375bae2aceSJari Sihvola #define GPIOE_0 0x100
385bae2aceSJari Sihvola #define GPIOE_1 0x104
395bae2aceSJari Sihvola #define GPIO_DIN_LOW 0x118
405bae2aceSJari Sihvola #define GPIO_DIN_HIGH 0x11c
415bae2aceSJari Sihvola #define IOMUX_SYSCFG_288 0x120
425bae2aceSJari Sihvola
435bae2aceSJari Sihvola #define PAD_INPUT_EN (1 << 0)
445bae2aceSJari Sihvola #define PAD_PULLUP (1 << 3)
455bae2aceSJari Sihvola #define PAD_PULLDOWN (1 << 4)
465bae2aceSJari Sihvola #define PAD_HYST (1 << 6)
475bae2aceSJari Sihvola
485bae2aceSJari Sihvola #define ENABLE_MASK 0x3f
495bae2aceSJari Sihvola #define DATA_OUT_MASK 0x7f
505bae2aceSJari Sihvola #define DIROUT_DISABLE 1
515bae2aceSJari Sihvola
525bae2aceSJari Sihvola struct jh7110_gpio_softc {
535bae2aceSJari Sihvola device_t dev;
545bae2aceSJari Sihvola device_t busdev;
555bae2aceSJari Sihvola struct mtx mtx;
565bae2aceSJari Sihvola struct resource *res;
575bae2aceSJari Sihvola clk_t clk;
585bae2aceSJari Sihvola };
595bae2aceSJari Sihvola
605bae2aceSJari Sihvola static struct ofw_compat_data compat_data[] = {
615bae2aceSJari Sihvola {"starfive,jh7110-sys-pinctrl", 1},
625bae2aceSJari Sihvola {NULL, 0}
635bae2aceSJari Sihvola };
645bae2aceSJari Sihvola
655bae2aceSJari Sihvola static struct resource_spec jh7110_gpio_spec[] = {
665bae2aceSJari Sihvola { SYS_RES_MEMORY, 0, RF_ACTIVE },
675bae2aceSJari Sihvola { -1, 0 }
685bae2aceSJari Sihvola };
695bae2aceSJari Sihvola
705bae2aceSJari Sihvola #define GPIO_RW_OFFSET(_val) (_val & ~3)
715bae2aceSJari Sihvola #define GPIO_SHIFT(_val) ((_val & 3) * 8)
725bae2aceSJari Sihvola #define PAD_OFFSET(_val) (_val * 4)
735bae2aceSJari Sihvola
745bae2aceSJari Sihvola #define JH7110_GPIO_LOCK(_sc) mtx_lock(&(_sc)->mtx)
755bae2aceSJari Sihvola #define JH7110_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
765bae2aceSJari Sihvola
775bae2aceSJari Sihvola #define JH7110_GPIO_READ(sc, reg) bus_read_4((sc)->res, (reg))
785bae2aceSJari Sihvola #define JH7110_GPIO_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val))
795bae2aceSJari Sihvola
805bae2aceSJari Sihvola static device_t
jh7110_gpio_get_bus(device_t dev)815bae2aceSJari Sihvola jh7110_gpio_get_bus(device_t dev)
825bae2aceSJari Sihvola {
835bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
845bae2aceSJari Sihvola
855bae2aceSJari Sihvola sc = device_get_softc(dev);
865bae2aceSJari Sihvola
875bae2aceSJari Sihvola return (sc->busdev);
885bae2aceSJari Sihvola }
895bae2aceSJari Sihvola
905bae2aceSJari Sihvola static int
jh7110_gpio_pin_max(device_t dev,int * maxpin)915bae2aceSJari Sihvola jh7110_gpio_pin_max(device_t dev, int *maxpin)
925bae2aceSJari Sihvola {
935bae2aceSJari Sihvola *maxpin = GPIO_PINS - 1;
945bae2aceSJari Sihvola
955bae2aceSJari Sihvola return (0);
965bae2aceSJari Sihvola }
975bae2aceSJari Sihvola
985bae2aceSJari Sihvola static int
jh7110_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * val)995bae2aceSJari Sihvola jh7110_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
1005bae2aceSJari Sihvola {
1015bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
1025bae2aceSJari Sihvola uint32_t reg;
1035bae2aceSJari Sihvola
1045bae2aceSJari Sihvola sc = device_get_softc(dev);
1055bae2aceSJari Sihvola
1065bae2aceSJari Sihvola if (pin >= GPIO_PINS)
1075bae2aceSJari Sihvola return (EINVAL);
1085bae2aceSJari Sihvola
1095bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc);
1105bae2aceSJari Sihvola if (pin < GPIO_PINS / GPIO_REGS) {
1115bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GPIO_DIN_LOW);
1125bae2aceSJari Sihvola *val = (reg >> pin) & 0x1;
1135bae2aceSJari Sihvola } else {
1145bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GPIO_DIN_HIGH);
1155bae2aceSJari Sihvola *val = (reg >> (pin - GPIO_PINS / GPIO_REGS)) & 0x1;
1165bae2aceSJari Sihvola }
1175bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc);
1185bae2aceSJari Sihvola
1195bae2aceSJari Sihvola return (0);
1205bae2aceSJari Sihvola }
1215bae2aceSJari Sihvola
1225bae2aceSJari Sihvola static int
jh7110_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)1235bae2aceSJari Sihvola jh7110_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
1245bae2aceSJari Sihvola {
1255bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
1265bae2aceSJari Sihvola uint32_t reg;
1275bae2aceSJari Sihvola
1285bae2aceSJari Sihvola sc = device_get_softc(dev);
1295bae2aceSJari Sihvola
1305bae2aceSJari Sihvola if (pin >= GPIO_PINS)
1315bae2aceSJari Sihvola return (EINVAL);
1325bae2aceSJari Sihvola
1335bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc);
1345bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin));
1355bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
1365bae2aceSJari Sihvola if (value)
1375bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin);
1385bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg);
1395bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc);
1405bae2aceSJari Sihvola
1415bae2aceSJari Sihvola return (0);
1425bae2aceSJari Sihvola }
1435bae2aceSJari Sihvola
1445bae2aceSJari Sihvola static int
jh7110_gpio_pin_toggle(device_t dev,uint32_t pin)1455bae2aceSJari Sihvola jh7110_gpio_pin_toggle(device_t dev, uint32_t pin)
1465bae2aceSJari Sihvola {
1475bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
1485bae2aceSJari Sihvola uint32_t reg;
1495bae2aceSJari Sihvola
1505bae2aceSJari Sihvola sc = device_get_softc(dev);
1515bae2aceSJari Sihvola
1525bae2aceSJari Sihvola if (pin >= GPIO_PINS)
1535bae2aceSJari Sihvola return (EINVAL);
1545bae2aceSJari Sihvola
1555bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc);
1565bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin));
1575bae2aceSJari Sihvola if (reg & 0x1 << GPIO_SHIFT(pin)) {
1585bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
1595bae2aceSJari Sihvola } else {
1605bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
1615bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin);
1625bae2aceSJari Sihvola }
1635bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg);
1645bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc);
1655bae2aceSJari Sihvola
1665bae2aceSJari Sihvola return (0);
1675bae2aceSJari Sihvola }
1685bae2aceSJari Sihvola
1695bae2aceSJari Sihvola static int
jh7110_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)1705bae2aceSJari Sihvola jh7110_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
1715bae2aceSJari Sihvola {
1725bae2aceSJari Sihvola if (pin >= GPIO_PINS)
1735bae2aceSJari Sihvola return (EINVAL);
1745bae2aceSJari Sihvola
1755bae2aceSJari Sihvola *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
1765bae2aceSJari Sihvola
1775bae2aceSJari Sihvola return (0);
1785bae2aceSJari Sihvola }
1795bae2aceSJari Sihvola
1805bae2aceSJari Sihvola static int
jh7110_gpio_pin_getname(device_t dev,uint32_t pin,char * name)1815bae2aceSJari Sihvola jh7110_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
1825bae2aceSJari Sihvola {
1835bae2aceSJari Sihvola if (pin >= GPIO_PINS)
1845bae2aceSJari Sihvola return (EINVAL);
1855bae2aceSJari Sihvola
1865bae2aceSJari Sihvola snprintf(name, GPIOMAXNAME, "GPIO%d", pin);
1875bae2aceSJari Sihvola
1885bae2aceSJari Sihvola return (0);
1895bae2aceSJari Sihvola }
1905bae2aceSJari Sihvola
1915bae2aceSJari Sihvola static int
jh7110_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * flags)1925bae2aceSJari Sihvola jh7110_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
1935bae2aceSJari Sihvola {
1945bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
1955bae2aceSJari Sihvola uint32_t reg;
1965bae2aceSJari Sihvola
1975bae2aceSJari Sihvola sc = device_get_softc(dev);
1985bae2aceSJari Sihvola
1995bae2aceSJari Sihvola if (pin >= GPIO_PINS)
2005bae2aceSJari Sihvola return (EINVAL);
2015bae2aceSJari Sihvola
2025bae2aceSJari Sihvola /* Reading the direction */
2035bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc);
2045bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin));
2055bae2aceSJari Sihvola if ((reg & ENABLE_MASK << GPIO_SHIFT(pin)) == 0)
2065bae2aceSJari Sihvola *flags |= GPIO_PIN_OUTPUT;
2075bae2aceSJari Sihvola else
2085bae2aceSJari Sihvola *flags |= GPIO_PIN_INPUT;
2095bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc);
2105bae2aceSJari Sihvola
2115bae2aceSJari Sihvola return (0);
2125bae2aceSJari Sihvola }
2135bae2aceSJari Sihvola
2145bae2aceSJari Sihvola static int
jh7110_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)2155bae2aceSJari Sihvola jh7110_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
2165bae2aceSJari Sihvola {
2175bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
2185bae2aceSJari Sihvola uint32_t reg;
2195bae2aceSJari Sihvola
2205bae2aceSJari Sihvola sc = device_get_softc(dev);
2215bae2aceSJari Sihvola
2225bae2aceSJari Sihvola if (pin >= GPIO_PINS)
2235bae2aceSJari Sihvola return (EINVAL);
2245bae2aceSJari Sihvola
2255bae2aceSJari Sihvola /* Setting the direction, enable or disable output, configuring pads */
2265bae2aceSJari Sihvola
2275bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc);
2285bae2aceSJari Sihvola
2295bae2aceSJari Sihvola if (flags & GPIO_PIN_INPUT) {
2305bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin));
2315bae2aceSJari Sihvola reg |= (PAD_INPUT_EN | PAD_HYST);
2325bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin), reg);
2335bae2aceSJari Sihvola }
2345bae2aceSJari Sihvola
2355bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin));
2365bae2aceSJari Sihvola reg &= ~(ENABLE_MASK << GPIO_SHIFT(pin));
2375bae2aceSJari Sihvola if (flags & GPIO_PIN_INPUT) {
2385bae2aceSJari Sihvola reg |= DIROUT_DISABLE << GPIO_SHIFT(pin);
2395bae2aceSJari Sihvola }
2405bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin), reg);
2415bae2aceSJari Sihvola
2425bae2aceSJari Sihvola if (flags & GPIO_PIN_OUTPUT) {
2435bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin));
2445bae2aceSJari Sihvola reg &= ~(ENABLE_MASK << GPIO_SHIFT(pin));
2455bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin);
2465bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg);
2475bae2aceSJari Sihvola
2485bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin));
2495bae2aceSJari Sihvola reg &= ~(PAD_INPUT_EN | PAD_PULLUP | PAD_PULLDOWN | PAD_HYST);
2505bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin), reg);
2515bae2aceSJari Sihvola }
2525bae2aceSJari Sihvola
2535bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc);
2545bae2aceSJari Sihvola
2555bae2aceSJari Sihvola return (0);
2565bae2aceSJari Sihvola }
2575bae2aceSJari Sihvola
2585bae2aceSJari Sihvola static int
jh7110_gpio_probe(device_t dev)2595bae2aceSJari Sihvola jh7110_gpio_probe(device_t dev)
2605bae2aceSJari Sihvola {
2615bae2aceSJari Sihvola if (!ofw_bus_status_okay(dev))
2625bae2aceSJari Sihvola return (ENXIO);
2635bae2aceSJari Sihvola
2645bae2aceSJari Sihvola if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
2655bae2aceSJari Sihvola return (ENXIO);
2665bae2aceSJari Sihvola
2675bae2aceSJari Sihvola device_set_desc(dev, "StarFive JH7110 GPIO controller");
2685bae2aceSJari Sihvola
2695bae2aceSJari Sihvola return (BUS_PROBE_DEFAULT);
2705bae2aceSJari Sihvola }
2715bae2aceSJari Sihvola
2725bae2aceSJari Sihvola static int
jh7110_gpio_detach(device_t dev)2735bae2aceSJari Sihvola jh7110_gpio_detach(device_t dev)
2745bae2aceSJari Sihvola {
2755bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
2765bae2aceSJari Sihvola
2775bae2aceSJari Sihvola sc = device_get_softc(dev);
2785bae2aceSJari Sihvola
2795bae2aceSJari Sihvola bus_release_resources(dev, jh7110_gpio_spec, &sc->res);
2805bae2aceSJari Sihvola if (sc->busdev != NULL)
2815bae2aceSJari Sihvola gpiobus_detach_bus(dev);
2825bae2aceSJari Sihvola if (sc->clk != NULL)
2835bae2aceSJari Sihvola clk_release(sc->clk);
2845bae2aceSJari Sihvola mtx_destroy(&sc->mtx);
2855bae2aceSJari Sihvola
2865bae2aceSJari Sihvola return (0);
2875bae2aceSJari Sihvola }
2885bae2aceSJari Sihvola
2895bae2aceSJari Sihvola static int
jh7110_gpio_attach(device_t dev)2905bae2aceSJari Sihvola jh7110_gpio_attach(device_t dev)
2915bae2aceSJari Sihvola {
2925bae2aceSJari Sihvola struct jh7110_gpio_softc *sc;
2935bae2aceSJari Sihvola
2945bae2aceSJari Sihvola sc = device_get_softc(dev);
2955bae2aceSJari Sihvola sc->dev = dev;
2965bae2aceSJari Sihvola
2975bae2aceSJari Sihvola mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF);
2985bae2aceSJari Sihvola
2995bae2aceSJari Sihvola if (bus_alloc_resources(dev, jh7110_gpio_spec, &sc->res) != 0) {
3005bae2aceSJari Sihvola device_printf(dev, "Could not allocate resources\n");
3015bae2aceSJari Sihvola bus_release_resources(dev, jh7110_gpio_spec, &sc->res);
3025bae2aceSJari Sihvola mtx_destroy(&sc->mtx);
3035bae2aceSJari Sihvola return (ENXIO);
3045bae2aceSJari Sihvola }
3055bae2aceSJari Sihvola
3065bae2aceSJari Sihvola if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) != 0) {
3075bae2aceSJari Sihvola device_printf(dev, "Cannot get clock\n");
3085bae2aceSJari Sihvola jh7110_gpio_detach(dev);
3095bae2aceSJari Sihvola return (ENXIO);
3105bae2aceSJari Sihvola }
3115bae2aceSJari Sihvola
3125bae2aceSJari Sihvola if (clk_enable(sc->clk) != 0) {
3135bae2aceSJari Sihvola device_printf(dev, "Could not enable clock %s\n",
3145bae2aceSJari Sihvola clk_get_name(sc->clk));
3155bae2aceSJari Sihvola jh7110_gpio_detach(dev);
3165bae2aceSJari Sihvola return (ENXIO);
3175bae2aceSJari Sihvola }
3185bae2aceSJari Sihvola
3195bae2aceSJari Sihvola /* Reseting GPIO interrupts */
3205bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOE_0, 0);
3215bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOE_1, 0);
3225bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOEN, 1);
3235bae2aceSJari Sihvola
324*c063fb7aSAhmad Khalifa sc->busdev = gpiobus_add_bus(dev);
3255bae2aceSJari Sihvola if (sc->busdev == NULL) {
3265bae2aceSJari Sihvola device_printf(dev, "Cannot attach gpiobus\n");
3275bae2aceSJari Sihvola jh7110_gpio_detach(dev);
3285bae2aceSJari Sihvola return (ENXIO);
3295bae2aceSJari Sihvola }
3305bae2aceSJari Sihvola
331*c063fb7aSAhmad Khalifa bus_attach_children(dev);
3325bae2aceSJari Sihvola return (0);
3335bae2aceSJari Sihvola }
3345bae2aceSJari Sihvola
3355bae2aceSJari Sihvola static phandle_t
jh7110_gpio_get_node(device_t bus,device_t dev)3365bae2aceSJari Sihvola jh7110_gpio_get_node(device_t bus, device_t dev)
3375bae2aceSJari Sihvola {
3385bae2aceSJari Sihvola return (ofw_bus_get_node(bus));
3395bae2aceSJari Sihvola }
3405bae2aceSJari Sihvola
3415bae2aceSJari Sihvola static device_method_t jh7110_gpio_methods[] = {
3425bae2aceSJari Sihvola /* Device interface */
3435bae2aceSJari Sihvola DEVMETHOD(device_probe, jh7110_gpio_probe),
3445bae2aceSJari Sihvola DEVMETHOD(device_attach, jh7110_gpio_attach),
3455bae2aceSJari Sihvola DEVMETHOD(device_detach, jh7110_gpio_detach),
3465bae2aceSJari Sihvola
3475bae2aceSJari Sihvola /* GPIO protocol */
3485bae2aceSJari Sihvola DEVMETHOD(gpio_get_bus, jh7110_gpio_get_bus),
3495bae2aceSJari Sihvola DEVMETHOD(gpio_pin_max, jh7110_gpio_pin_max),
3505bae2aceSJari Sihvola DEVMETHOD(gpio_pin_get, jh7110_gpio_pin_get),
3515bae2aceSJari Sihvola DEVMETHOD(gpio_pin_set, jh7110_gpio_pin_set),
3525bae2aceSJari Sihvola DEVMETHOD(gpio_pin_toggle, jh7110_gpio_pin_toggle),
3535bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getflags, jh7110_gpio_pin_getflags),
3545bae2aceSJari Sihvola DEVMETHOD(gpio_pin_setflags, jh7110_gpio_pin_setflags),
3555bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getcaps, jh7110_gpio_pin_getcaps),
3565bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getname, jh7110_gpio_pin_getname),
3575bae2aceSJari Sihvola
3585bae2aceSJari Sihvola /* ofw_bus interface */
3595bae2aceSJari Sihvola DEVMETHOD(ofw_bus_get_node, jh7110_gpio_get_node),
3605bae2aceSJari Sihvola
3615bae2aceSJari Sihvola DEVMETHOD_END
3625bae2aceSJari Sihvola };
3635bae2aceSJari Sihvola
3645bae2aceSJari Sihvola DEFINE_CLASS_0(gpio, jh7110_gpio_driver, jh7110_gpio_methods,
3655bae2aceSJari Sihvola sizeof(struct jh7110_gpio_softc));
3665bae2aceSJari Sihvola EARLY_DRIVER_MODULE(jh7110_gpio, simplebus, jh7110_gpio_driver, 0, 0,
3675bae2aceSJari Sihvola BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
3685bae2aceSJari Sihvola MODULE_DEPEND(jh7110_gpio, gpiobus, 1, 1, 1);
369