static int rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) { struct rk30_gpio_softc *sc = device_get_softc(dev); uint32_t bank, offset, data; int i; for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); bank = pin / 32; pin = pin % 32; offset = 1 << pin; RK30_GPIO_LOCK(sc); data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); data |= offset; RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); if (value) data |= offset; else data &= ~offset; RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); RK30_GPIO_UNLOCK(sc); return (0); }
static int rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct rk30_gpio_softc *sc = device_get_softc(dev); uint32_t bank, offset, reg_data; int i; for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); bank = pin / 32; pin = pin % 32; offset = 1 << pin; RK30_GPIO_LOCK(sc); reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT); RK30_GPIO_UNLOCK(sc); *val = (reg_data & offset) ? 1 : 0; return (0); }
static int rk30_gpio_pin_toggle(device_t dev, uint32_t pin) { int i; struct rk30_gpio_softc *sc; uint32_t data; sc = device_get_softc(dev); for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); RK30_GPIO_LOCK(sc); data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); if (data & (1U << pin)) data &= ~(1U << pin); else data |= (1U << pin); RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); RK30_GPIO_UNLOCK(sc); return (0); }
static void rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin, unsigned int flags) { RK30_GPIO_LOCK(sc); /* * Manage input/output. */ if (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) { pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); if (flags & GPIO_PIN_OUTPUT) pin->gp_flags |= GPIO_PIN_OUTPUT; else pin->gp_flags |= GPIO_PIN_INPUT; rk30_gpio_set_function(sc, pin->gp_pin, pin->gp_flags); } /* Manage Pull-up/pull-down. */ pin->gp_flags &= ~(GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); if (flags & (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)) { if (flags & GPIO_PIN_PULLUP) pin->gp_flags |= GPIO_PIN_PULLUP; else pin->gp_flags |= GPIO_PIN_PULLDOWN; } rk30_gpio_set_pud(sc, pin->gp_pin, pin->gp_flags); RK30_GPIO_UNLOCK(sc); }
static int rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name) { struct rk30_gpio_softc *sc = device_get_softc(dev); int i; for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); RK30_GPIO_LOCK(sc); memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME); RK30_GPIO_UNLOCK(sc); return (0); }
static int rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) { struct rk30_gpio_softc *sc = device_get_softc(dev); int i; for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); RK30_GPIO_LOCK(sc); *flags = sc->sc_gpio_pins[i].gp_flags; RK30_GPIO_UNLOCK(sc); return (0); }
static int rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { int i; struct rk30_gpio_softc *sc; uint32_t data; sc = device_get_softc(dev); for (i = 0; i < sc->sc_gpio_npins; i++) { if (sc->sc_gpio_pins[i].gp_pin == pin) break; } if (i >= sc->sc_gpio_npins) return (EINVAL); RK30_GPIO_LOCK(sc); data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT); RK30_GPIO_UNLOCK(sc); *val = (data & (1U << pin)) ? 1 : 0; return (0); }