static int gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, struct thread *td) { device_t bus; int max_pin, res; struct gpioc_softc *sc = cdev->si_drv1; struct gpio_pin pin; struct gpio_req req; struct gpio_access_32 *a32; struct gpio_config_32 *c32; uint32_t caps; bus = GPIO_GET_BUS(sc->sc_pdev); if (bus == NULL) return (EINVAL); switch (cmd) { case GPIOMAXPIN: max_pin = -1; res = GPIO_PIN_MAX(sc->sc_pdev, &max_pin); bcopy(&max_pin, arg, sizeof(max_pin)); break; case GPIOGETCONFIG: bcopy(arg, &pin, sizeof(pin)); dprintf("get config pin %d\n", pin.gp_pin); res = GPIO_PIN_GETFLAGS(sc->sc_pdev, pin.gp_pin, &pin.gp_flags); /* Fail early */ if (res) break; GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &pin.gp_caps); GPIOBUS_PIN_GETNAME(bus, pin.gp_pin, pin.gp_name); bcopy(&pin, arg, sizeof(pin)); break; case GPIOSETCONFIG: bcopy(arg, &pin, sizeof(pin)); dprintf("set config pin %d\n", pin.gp_pin); res = GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &caps); if (res == 0) res = gpio_check_flags(caps, pin.gp_flags); if (res == 0) res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin, pin.gp_flags); break; case GPIOGET: bcopy(arg, &req, sizeof(req)); res = GPIO_PIN_GET(sc->sc_pdev, req.gp_pin, &req.gp_value); dprintf("read pin %d -> %d\n", req.gp_pin, req.gp_value); bcopy(&req, arg, sizeof(req)); break; case GPIOSET: bcopy(arg, &req, sizeof(req)); res = GPIO_PIN_SET(sc->sc_pdev, req.gp_pin, req.gp_value); dprintf("write pin %d -> %d\n", req.gp_pin, req.gp_value); break; case GPIOTOGGLE: bcopy(arg, &req, sizeof(req)); dprintf("toggle pin %d\n", req.gp_pin); res = GPIO_PIN_TOGGLE(sc->sc_pdev, req.gp_pin); break; case GPIOSETNAME: bcopy(arg, &pin, sizeof(pin)); dprintf("set name on pin %d\n", pin.gp_pin); res = GPIOBUS_PIN_SETNAME(bus, pin.gp_pin, pin.gp_name); break; case GPIOACCESS32: a32 = (struct gpio_access_32 *)arg; res = GPIO_PIN_ACCESS_32(sc->sc_pdev, a32->first_pin, a32->clear_pins, a32->orig_pins, &a32->orig_pins); break; case GPIOCONFIG32: c32 = (struct gpio_config_32 *)arg; res = GPIO_PIN_CONFIG_32(sc->sc_pdev, c32->first_pin, c32->num_pins, c32->pin_flags); break; default: return (ENOTTY); break; } return (res); }
static int gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, struct thread *td) { int max_pin, res; struct gpioc_softc *sc = cdev->si_drv1; struct gpio_pin pin; struct gpio_req req; switch (cmd) { case GPIOMAXPIN: max_pin = -1; res = GPIO_PIN_MAX(sc->sc_pdev, &max_pin); bcopy(&max_pin, arg, sizeof(max_pin)); break; case GPIOGETCONFIG: bcopy(arg, &pin, sizeof(pin)); dprintf("get config pin %d\n", pin.gp_pin); res = GPIO_PIN_GETFLAGS(sc->sc_pdev, pin.gp_pin, &pin.gp_flags); /* Fail early */ if (res) break; GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &pin.gp_caps); GPIO_PIN_GETNAME(sc->sc_pdev, pin.gp_pin, pin.gp_name); bcopy(&pin, arg, sizeof(pin)); break; case GPIOSETCONFIG: bcopy(arg, &pin, sizeof(pin)); dprintf("set config pin %d\n", pin.gp_pin); res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin, pin.gp_flags); break; case GPIOGET: bcopy(arg, &req, sizeof(req)); res = GPIO_PIN_GET(sc->sc_pdev, req.gp_pin, &req.gp_value); dprintf("read pin %d -> %d\n", req.gp_pin, req.gp_value); bcopy(&req, arg, sizeof(req)); break; case GPIOSET: bcopy(arg, &req, sizeof(req)); res = GPIO_PIN_SET(sc->sc_pdev, req.gp_pin, req.gp_value); dprintf("write pin %d -> %d\n", req.gp_pin, req.gp_value); break; case GPIOTOGGLE: bcopy(arg, &req, sizeof(req)); dprintf("toggle pin %d\n", req.gp_pin); res = GPIO_PIN_TOGGLE(sc->sc_pdev, req.gp_pin); break; default: return (ENOTTY); break; } return (res); }