1*5bae2aceSJari Sihvola /* 2*5bae2aceSJari Sihvola * SPDX-License-Identifier: BSD-2-Clause 3*5bae2aceSJari Sihvola * 4*5bae2aceSJari Sihvola * Copyright (c) 2023 Jari Sihvola <jsihv@gmx.com> 5*5bae2aceSJari Sihvola */ 6*5bae2aceSJari Sihvola 7*5bae2aceSJari Sihvola #include <sys/cdefs.h> 8*5bae2aceSJari Sihvola 9*5bae2aceSJari Sihvola #include <sys/param.h> 10*5bae2aceSJari Sihvola #include <sys/systm.h> 11*5bae2aceSJari Sihvola #include <sys/bus.h> 12*5bae2aceSJari Sihvola 13*5bae2aceSJari Sihvola #include <sys/gpio.h> 14*5bae2aceSJari Sihvola #include <sys/kernel.h> 15*5bae2aceSJari Sihvola #include <sys/lock.h> 16*5bae2aceSJari Sihvola #include <sys/module.h> 17*5bae2aceSJari Sihvola #include <sys/mutex.h> 18*5bae2aceSJari Sihvola #include <sys/rman.h> 19*5bae2aceSJari Sihvola 20*5bae2aceSJari Sihvola #include <machine/bus.h> 21*5bae2aceSJari Sihvola #include <machine/intr.h> 22*5bae2aceSJari Sihvola #include <machine/resource.h> 23*5bae2aceSJari Sihvola 24*5bae2aceSJari Sihvola #include <dev/clk/clk.h> 25*5bae2aceSJari Sihvola #include <dev/gpio/gpiobusvar.h> 26*5bae2aceSJari Sihvola #include <dev/ofw/ofw_bus.h> 27*5bae2aceSJari Sihvola #include <dev/ofw/ofw_bus_subr.h> 28*5bae2aceSJari Sihvola 29*5bae2aceSJari Sihvola #include "gpio_if.h" 30*5bae2aceSJari Sihvola 31*5bae2aceSJari Sihvola #define GPIO_PINS 64 32*5bae2aceSJari Sihvola #define GPIO_REGS 2 33*5bae2aceSJari Sihvola 34*5bae2aceSJari Sihvola #define GP0_DOEN_CFG 0x0 35*5bae2aceSJari Sihvola #define GP0_DOUT_CFG 0x40 36*5bae2aceSJari Sihvola #define GPIOEN 0xdc 37*5bae2aceSJari Sihvola #define GPIOE_0 0x100 38*5bae2aceSJari Sihvola #define GPIOE_1 0x104 39*5bae2aceSJari Sihvola #define GPIO_DIN_LOW 0x118 40*5bae2aceSJari Sihvola #define GPIO_DIN_HIGH 0x11c 41*5bae2aceSJari Sihvola #define IOMUX_SYSCFG_288 0x120 42*5bae2aceSJari Sihvola 43*5bae2aceSJari Sihvola #define PAD_INPUT_EN (1 << 0) 44*5bae2aceSJari Sihvola #define PAD_PULLUP (1 << 3) 45*5bae2aceSJari Sihvola #define PAD_PULLDOWN (1 << 4) 46*5bae2aceSJari Sihvola #define PAD_HYST (1 << 6) 47*5bae2aceSJari Sihvola 48*5bae2aceSJari Sihvola #define ENABLE_MASK 0x3f 49*5bae2aceSJari Sihvola #define DATA_OUT_MASK 0x7f 50*5bae2aceSJari Sihvola #define DIROUT_DISABLE 1 51*5bae2aceSJari Sihvola 52*5bae2aceSJari Sihvola struct jh7110_gpio_softc { 53*5bae2aceSJari Sihvola device_t dev; 54*5bae2aceSJari Sihvola device_t busdev; 55*5bae2aceSJari Sihvola struct mtx mtx; 56*5bae2aceSJari Sihvola struct resource *res; 57*5bae2aceSJari Sihvola clk_t clk; 58*5bae2aceSJari Sihvola }; 59*5bae2aceSJari Sihvola 60*5bae2aceSJari Sihvola static struct ofw_compat_data compat_data[] = { 61*5bae2aceSJari Sihvola {"starfive,jh7110-sys-pinctrl", 1}, 62*5bae2aceSJari Sihvola {NULL, 0} 63*5bae2aceSJari Sihvola }; 64*5bae2aceSJari Sihvola 65*5bae2aceSJari Sihvola static struct resource_spec jh7110_gpio_spec[] = { 66*5bae2aceSJari Sihvola { SYS_RES_MEMORY, 0, RF_ACTIVE }, 67*5bae2aceSJari Sihvola { -1, 0 } 68*5bae2aceSJari Sihvola }; 69*5bae2aceSJari Sihvola 70*5bae2aceSJari Sihvola #define GPIO_RW_OFFSET(_val) (_val & ~3) 71*5bae2aceSJari Sihvola #define GPIO_SHIFT(_val) ((_val & 3) * 8) 72*5bae2aceSJari Sihvola #define PAD_OFFSET(_val) (_val * 4) 73*5bae2aceSJari Sihvola 74*5bae2aceSJari Sihvola #define JH7110_GPIO_LOCK(_sc) mtx_lock(&(_sc)->mtx) 75*5bae2aceSJari Sihvola #define JH7110_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) 76*5bae2aceSJari Sihvola 77*5bae2aceSJari Sihvola #define JH7110_GPIO_READ(sc, reg) bus_read_4((sc)->res, (reg)) 78*5bae2aceSJari Sihvola #define JH7110_GPIO_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) 79*5bae2aceSJari Sihvola 80*5bae2aceSJari Sihvola static device_t 81*5bae2aceSJari Sihvola jh7110_gpio_get_bus(device_t dev) 82*5bae2aceSJari Sihvola { 83*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 84*5bae2aceSJari Sihvola 85*5bae2aceSJari Sihvola sc = device_get_softc(dev); 86*5bae2aceSJari Sihvola 87*5bae2aceSJari Sihvola return (sc->busdev); 88*5bae2aceSJari Sihvola } 89*5bae2aceSJari Sihvola 90*5bae2aceSJari Sihvola static int 91*5bae2aceSJari Sihvola jh7110_gpio_pin_max(device_t dev, int *maxpin) 92*5bae2aceSJari Sihvola { 93*5bae2aceSJari Sihvola *maxpin = GPIO_PINS - 1; 94*5bae2aceSJari Sihvola 95*5bae2aceSJari Sihvola return (0); 96*5bae2aceSJari Sihvola } 97*5bae2aceSJari Sihvola 98*5bae2aceSJari Sihvola static int 99*5bae2aceSJari Sihvola jh7110_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 100*5bae2aceSJari Sihvola { 101*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 102*5bae2aceSJari Sihvola uint32_t reg; 103*5bae2aceSJari Sihvola 104*5bae2aceSJari Sihvola sc = device_get_softc(dev); 105*5bae2aceSJari Sihvola 106*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 107*5bae2aceSJari Sihvola return (EINVAL); 108*5bae2aceSJari Sihvola 109*5bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc); 110*5bae2aceSJari Sihvola if (pin < GPIO_PINS / GPIO_REGS) { 111*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GPIO_DIN_LOW); 112*5bae2aceSJari Sihvola *val = (reg >> pin) & 0x1; 113*5bae2aceSJari Sihvola } else { 114*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GPIO_DIN_HIGH); 115*5bae2aceSJari Sihvola *val = (reg >> (pin - GPIO_PINS / GPIO_REGS)) & 0x1; 116*5bae2aceSJari Sihvola } 117*5bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc); 118*5bae2aceSJari Sihvola 119*5bae2aceSJari Sihvola return (0); 120*5bae2aceSJari Sihvola } 121*5bae2aceSJari Sihvola 122*5bae2aceSJari Sihvola static int 123*5bae2aceSJari Sihvola jh7110_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 124*5bae2aceSJari Sihvola { 125*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 126*5bae2aceSJari Sihvola uint32_t reg; 127*5bae2aceSJari Sihvola 128*5bae2aceSJari Sihvola sc = device_get_softc(dev); 129*5bae2aceSJari Sihvola 130*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 131*5bae2aceSJari Sihvola return (EINVAL); 132*5bae2aceSJari Sihvola 133*5bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc); 134*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin)); 135*5bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin)); 136*5bae2aceSJari Sihvola if (value) 137*5bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin); 138*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg); 139*5bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc); 140*5bae2aceSJari Sihvola 141*5bae2aceSJari Sihvola return (0); 142*5bae2aceSJari Sihvola } 143*5bae2aceSJari Sihvola 144*5bae2aceSJari Sihvola static int 145*5bae2aceSJari Sihvola jh7110_gpio_pin_toggle(device_t dev, uint32_t pin) 146*5bae2aceSJari Sihvola { 147*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 148*5bae2aceSJari Sihvola uint32_t reg; 149*5bae2aceSJari Sihvola 150*5bae2aceSJari Sihvola sc = device_get_softc(dev); 151*5bae2aceSJari Sihvola 152*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 153*5bae2aceSJari Sihvola return (EINVAL); 154*5bae2aceSJari Sihvola 155*5bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc); 156*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin)); 157*5bae2aceSJari Sihvola if (reg & 0x1 << GPIO_SHIFT(pin)) { 158*5bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin)); 159*5bae2aceSJari Sihvola } else { 160*5bae2aceSJari Sihvola reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin)); 161*5bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin); 162*5bae2aceSJari Sihvola } 163*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg); 164*5bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc); 165*5bae2aceSJari Sihvola 166*5bae2aceSJari Sihvola return (0); 167*5bae2aceSJari Sihvola } 168*5bae2aceSJari Sihvola 169*5bae2aceSJari Sihvola static int 170*5bae2aceSJari Sihvola jh7110_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 171*5bae2aceSJari Sihvola { 172*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 173*5bae2aceSJari Sihvola return (EINVAL); 174*5bae2aceSJari Sihvola 175*5bae2aceSJari Sihvola *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); 176*5bae2aceSJari Sihvola 177*5bae2aceSJari Sihvola return (0); 178*5bae2aceSJari Sihvola } 179*5bae2aceSJari Sihvola 180*5bae2aceSJari Sihvola static int 181*5bae2aceSJari Sihvola jh7110_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 182*5bae2aceSJari Sihvola { 183*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 184*5bae2aceSJari Sihvola return (EINVAL); 185*5bae2aceSJari Sihvola 186*5bae2aceSJari Sihvola snprintf(name, GPIOMAXNAME, "GPIO%d", pin); 187*5bae2aceSJari Sihvola 188*5bae2aceSJari Sihvola return (0); 189*5bae2aceSJari Sihvola } 190*5bae2aceSJari Sihvola 191*5bae2aceSJari Sihvola static int 192*5bae2aceSJari Sihvola jh7110_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 193*5bae2aceSJari Sihvola { 194*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 195*5bae2aceSJari Sihvola uint32_t reg; 196*5bae2aceSJari Sihvola 197*5bae2aceSJari Sihvola sc = device_get_softc(dev); 198*5bae2aceSJari Sihvola 199*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 200*5bae2aceSJari Sihvola return (EINVAL); 201*5bae2aceSJari Sihvola 202*5bae2aceSJari Sihvola /* Reading the direction */ 203*5bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc); 204*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin)); 205*5bae2aceSJari Sihvola if ((reg & ENABLE_MASK << GPIO_SHIFT(pin)) == 0) 206*5bae2aceSJari Sihvola *flags |= GPIO_PIN_OUTPUT; 207*5bae2aceSJari Sihvola else 208*5bae2aceSJari Sihvola *flags |= GPIO_PIN_INPUT; 209*5bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc); 210*5bae2aceSJari Sihvola 211*5bae2aceSJari Sihvola return (0); 212*5bae2aceSJari Sihvola } 213*5bae2aceSJari Sihvola 214*5bae2aceSJari Sihvola static int 215*5bae2aceSJari Sihvola jh7110_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 216*5bae2aceSJari Sihvola { 217*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 218*5bae2aceSJari Sihvola uint32_t reg; 219*5bae2aceSJari Sihvola 220*5bae2aceSJari Sihvola sc = device_get_softc(dev); 221*5bae2aceSJari Sihvola 222*5bae2aceSJari Sihvola if (pin >= GPIO_PINS) 223*5bae2aceSJari Sihvola return (EINVAL); 224*5bae2aceSJari Sihvola 225*5bae2aceSJari Sihvola /* Setting the direction, enable or disable output, configuring pads */ 226*5bae2aceSJari Sihvola 227*5bae2aceSJari Sihvola JH7110_GPIO_LOCK(sc); 228*5bae2aceSJari Sihvola 229*5bae2aceSJari Sihvola if (flags & GPIO_PIN_INPUT) { 230*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin)); 231*5bae2aceSJari Sihvola reg |= (PAD_INPUT_EN | PAD_HYST); 232*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin), reg); 233*5bae2aceSJari Sihvola } 234*5bae2aceSJari Sihvola 235*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin)); 236*5bae2aceSJari Sihvola reg &= ~(ENABLE_MASK << GPIO_SHIFT(pin)); 237*5bae2aceSJari Sihvola if (flags & GPIO_PIN_INPUT) { 238*5bae2aceSJari Sihvola reg |= DIROUT_DISABLE << GPIO_SHIFT(pin); 239*5bae2aceSJari Sihvola } 240*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOEN_CFG + GPIO_RW_OFFSET(pin), reg); 241*5bae2aceSJari Sihvola 242*5bae2aceSJari Sihvola if (flags & GPIO_PIN_OUTPUT) { 243*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin)); 244*5bae2aceSJari Sihvola reg &= ~(ENABLE_MASK << GPIO_SHIFT(pin)); 245*5bae2aceSJari Sihvola reg |= 0x1 << GPIO_SHIFT(pin); 246*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + GPIO_RW_OFFSET(pin), reg); 247*5bae2aceSJari Sihvola 248*5bae2aceSJari Sihvola reg = JH7110_GPIO_READ(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin)); 249*5bae2aceSJari Sihvola reg &= ~(PAD_INPUT_EN | PAD_PULLUP | PAD_PULLDOWN | PAD_HYST); 250*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, IOMUX_SYSCFG_288 + PAD_OFFSET(pin), reg); 251*5bae2aceSJari Sihvola } 252*5bae2aceSJari Sihvola 253*5bae2aceSJari Sihvola JH7110_GPIO_UNLOCK(sc); 254*5bae2aceSJari Sihvola 255*5bae2aceSJari Sihvola return (0); 256*5bae2aceSJari Sihvola } 257*5bae2aceSJari Sihvola 258*5bae2aceSJari Sihvola static int 259*5bae2aceSJari Sihvola jh7110_gpio_probe(device_t dev) 260*5bae2aceSJari Sihvola { 261*5bae2aceSJari Sihvola if (!ofw_bus_status_okay(dev)) 262*5bae2aceSJari Sihvola return (ENXIO); 263*5bae2aceSJari Sihvola 264*5bae2aceSJari Sihvola if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 265*5bae2aceSJari Sihvola return (ENXIO); 266*5bae2aceSJari Sihvola 267*5bae2aceSJari Sihvola device_set_desc(dev, "StarFive JH7110 GPIO controller"); 268*5bae2aceSJari Sihvola 269*5bae2aceSJari Sihvola return (BUS_PROBE_DEFAULT); 270*5bae2aceSJari Sihvola } 271*5bae2aceSJari Sihvola 272*5bae2aceSJari Sihvola static int 273*5bae2aceSJari Sihvola jh7110_gpio_detach(device_t dev) 274*5bae2aceSJari Sihvola { 275*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 276*5bae2aceSJari Sihvola 277*5bae2aceSJari Sihvola sc = device_get_softc(dev); 278*5bae2aceSJari Sihvola 279*5bae2aceSJari Sihvola bus_release_resources(dev, jh7110_gpio_spec, &sc->res); 280*5bae2aceSJari Sihvola if (sc->busdev != NULL) 281*5bae2aceSJari Sihvola gpiobus_detach_bus(dev); 282*5bae2aceSJari Sihvola if (sc->clk != NULL) 283*5bae2aceSJari Sihvola clk_release(sc->clk); 284*5bae2aceSJari Sihvola mtx_destroy(&sc->mtx); 285*5bae2aceSJari Sihvola 286*5bae2aceSJari Sihvola return (0); 287*5bae2aceSJari Sihvola } 288*5bae2aceSJari Sihvola 289*5bae2aceSJari Sihvola static int 290*5bae2aceSJari Sihvola jh7110_gpio_attach(device_t dev) 291*5bae2aceSJari Sihvola { 292*5bae2aceSJari Sihvola struct jh7110_gpio_softc *sc; 293*5bae2aceSJari Sihvola 294*5bae2aceSJari Sihvola sc = device_get_softc(dev); 295*5bae2aceSJari Sihvola sc->dev = dev; 296*5bae2aceSJari Sihvola 297*5bae2aceSJari Sihvola mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); 298*5bae2aceSJari Sihvola 299*5bae2aceSJari Sihvola if (bus_alloc_resources(dev, jh7110_gpio_spec, &sc->res) != 0) { 300*5bae2aceSJari Sihvola device_printf(dev, "Could not allocate resources\n"); 301*5bae2aceSJari Sihvola bus_release_resources(dev, jh7110_gpio_spec, &sc->res); 302*5bae2aceSJari Sihvola mtx_destroy(&sc->mtx); 303*5bae2aceSJari Sihvola return (ENXIO); 304*5bae2aceSJari Sihvola } 305*5bae2aceSJari Sihvola 306*5bae2aceSJari Sihvola if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) != 0) { 307*5bae2aceSJari Sihvola device_printf(dev, "Cannot get clock\n"); 308*5bae2aceSJari Sihvola jh7110_gpio_detach(dev); 309*5bae2aceSJari Sihvola return (ENXIO); 310*5bae2aceSJari Sihvola } 311*5bae2aceSJari Sihvola 312*5bae2aceSJari Sihvola if (clk_enable(sc->clk) != 0) { 313*5bae2aceSJari Sihvola device_printf(dev, "Could not enable clock %s\n", 314*5bae2aceSJari Sihvola clk_get_name(sc->clk)); 315*5bae2aceSJari Sihvola jh7110_gpio_detach(dev); 316*5bae2aceSJari Sihvola return (ENXIO); 317*5bae2aceSJari Sihvola } 318*5bae2aceSJari Sihvola 319*5bae2aceSJari Sihvola /* Reseting GPIO interrupts */ 320*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOE_0, 0); 321*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOE_1, 0); 322*5bae2aceSJari Sihvola JH7110_GPIO_WRITE(sc, GPIOEN, 1); 323*5bae2aceSJari Sihvola 324*5bae2aceSJari Sihvola sc->busdev = gpiobus_attach_bus(dev); 325*5bae2aceSJari Sihvola if (sc->busdev == NULL) { 326*5bae2aceSJari Sihvola device_printf(dev, "Cannot attach gpiobus\n"); 327*5bae2aceSJari Sihvola jh7110_gpio_detach(dev); 328*5bae2aceSJari Sihvola return (ENXIO); 329*5bae2aceSJari Sihvola } 330*5bae2aceSJari Sihvola 331*5bae2aceSJari Sihvola return (0); 332*5bae2aceSJari Sihvola } 333*5bae2aceSJari Sihvola 334*5bae2aceSJari Sihvola static phandle_t 335*5bae2aceSJari Sihvola jh7110_gpio_get_node(device_t bus, device_t dev) 336*5bae2aceSJari Sihvola { 337*5bae2aceSJari Sihvola return (ofw_bus_get_node(bus)); 338*5bae2aceSJari Sihvola } 339*5bae2aceSJari Sihvola 340*5bae2aceSJari Sihvola static device_method_t jh7110_gpio_methods[] = { 341*5bae2aceSJari Sihvola /* Device interface */ 342*5bae2aceSJari Sihvola DEVMETHOD(device_probe, jh7110_gpio_probe), 343*5bae2aceSJari Sihvola DEVMETHOD(device_attach, jh7110_gpio_attach), 344*5bae2aceSJari Sihvola DEVMETHOD(device_detach, jh7110_gpio_detach), 345*5bae2aceSJari Sihvola 346*5bae2aceSJari Sihvola /* GPIO protocol */ 347*5bae2aceSJari Sihvola DEVMETHOD(gpio_get_bus, jh7110_gpio_get_bus), 348*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_max, jh7110_gpio_pin_max), 349*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_get, jh7110_gpio_pin_get), 350*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_set, jh7110_gpio_pin_set), 351*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_toggle, jh7110_gpio_pin_toggle), 352*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getflags, jh7110_gpio_pin_getflags), 353*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_setflags, jh7110_gpio_pin_setflags), 354*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getcaps, jh7110_gpio_pin_getcaps), 355*5bae2aceSJari Sihvola DEVMETHOD(gpio_pin_getname, jh7110_gpio_pin_getname), 356*5bae2aceSJari Sihvola 357*5bae2aceSJari Sihvola /* ofw_bus interface */ 358*5bae2aceSJari Sihvola DEVMETHOD(ofw_bus_get_node, jh7110_gpio_get_node), 359*5bae2aceSJari Sihvola 360*5bae2aceSJari Sihvola DEVMETHOD_END 361*5bae2aceSJari Sihvola }; 362*5bae2aceSJari Sihvola 363*5bae2aceSJari Sihvola DEFINE_CLASS_0(gpio, jh7110_gpio_driver, jh7110_gpio_methods, 364*5bae2aceSJari Sihvola sizeof(struct jh7110_gpio_softc)); 365*5bae2aceSJari Sihvola EARLY_DRIVER_MODULE(jh7110_gpio, simplebus, jh7110_gpio_driver, 0, 0, 366*5bae2aceSJari Sihvola BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); 367*5bae2aceSJari Sihvola MODULE_DEPEND(jh7110_gpio, gpiobus, 1, 1, 1); 368