static int wiigpio_attach(device_t dev) { struct wiigpio_softc *sc; int i; uint32_t d; sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_rrid = 0; sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid, RF_ACTIVE); if (sc->sc_rres == NULL) { device_printf(dev, "could not alloc mem resource\n"); return (ENXIO); } sc->sc_bt = rman_get_bustag(sc->sc_rres); sc->sc_bh = rman_get_bushandle(sc->sc_rres); mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); #ifdef WIIGPIO_DEBUG device_printf(dev, "dir bank0=0x%08x bank1=0x%08x\n", wiigpio_dir_read(sc, 0), wiigpio_dir_read(sc, 1)); device_printf(dev, "val bank0=0x%08x bank1=0x%08x\n", wiigpio_read(sc, 0), wiigpio_read(sc, 1)); #endif for (i = 0; i < WIIGPIO_NPINS; i++) { sc->sc_pins[i].gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; sc->sc_pins[i].gp_pin = i; d = wiigpio_dir_read(sc, WIIGPIO_PINBANK(i)); if (d & WIIGPIO_PINMASK(i)) sc->sc_pins[i].gp_flags = GPIO_PIN_OUTPUT; else sc->sc_pins[i].gp_flags = GPIO_PIN_INPUT; snprintf(sc->sc_pins[i].gp_name, GPIOMAXNAME, "PIN %d", i); #ifdef WIIGPIO_DEBUG device_printf(dev, "PIN %d state %d flag %s\n", i, wiigpio_read(sc, WIIGPIO_PINBANK(i)) >> (i % (WIIGPIO_NPINS / 2)) & 1, sc->sc_pins[i].gp_flags == GPIO_PIN_INPUT ? "GPIO_PIN_INPUT" : "GPIO_PIN_OUTPUT"); #endif } device_add_child(dev, "gpioc", -1); device_add_child(dev, "gpiobus", -1); /* * We will be responsible for powering off the system. */ EVENTHANDLER_REGISTER(shutdown_final, wiigpio_shutdown, dev, SHUTDOWN_PRI_LAST); return (bus_generic_attach(dev)); }
static int wiigpio_pin_toggle(device_t dev, uint32_t pin) { struct wiigpio_softc *sc; uint32_t val, pinmask = 1 << pin; sc = device_get_softc(dev); WIIGPIO_LOCK(sc); val = wiigpio_read(sc) & pinmask; if (val) wiigpio_write(sc, wiigpio_read(sc) & ~pinmask); else wiigpio_write(sc, wiigpio_read(sc) | pinmask); WIIGPIO_UNLOCK(sc); return (0); }
static int wiigpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct wiigpio_softc *sc; uint32_t reg; if (pin >= WIIGPIO_NPINS) return (EINVAL); sc = device_get_softc(dev); WIIGPIO_LOCK(sc); reg = wiigpio_read(sc); *val = !!(reg & (1 << pin)); WIIGPIO_UNLOCK(sc); return (0); }
static int wiigpio_pin_set(device_t dev, uint32_t pin, unsigned int value) { struct wiigpio_softc *sc; uint32_t reg, pinmask = 1 << pin; if (pin >= WIIGPIO_NPINS) return (EINVAL); sc = device_get_softc(dev); WIIGPIO_LOCK(sc); reg = wiigpio_read(sc) & ~pinmask; if (value) reg |= pinmask; wiigpio_write(sc, reg); WIIGPIO_UNLOCK(sc); return (0); }
static int wiigpio_pin_toggle(device_t dev, uint32_t pin) { struct wiigpio_softc *sc; uint32_t val, pinbank, pinmask; if (pin >= WIIGPIO_NPINS) return (EINVAL); sc = device_get_softc(dev); pinbank = WIIGPIO_PINBANK(pin); pinmask = WIIGPIO_PINMASK(pin); WIIGPIO_LOCK(sc); val = wiigpio_read(sc, pinbank); if (val & pinmask) wiigpio_write(sc, pinbank, val & ~pinmask); else wiigpio_write(sc, pinbank, val | pinmask); WIIGPIO_UNLOCK(sc); return (0); }