diff options
Diffstat (limited to 'sys/arm/broadcom/bcm2835/bcm2835_gpio.c')
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 9ddb44b..26d2359 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> +#include <arm/broadcom/bcm2835/bcm2835_gpio.h> + #include "gpio_if.h" #undef DEBUG @@ -87,17 +89,6 @@ struct bcm_gpio_softc { struct bcm_gpio_sysctl sc_sysctl[BCM_GPIO_PINS]; }; -enum bcm_gpio_fsel { - BCM_GPIO_INPUT, - BCM_GPIO_OUTPUT, - BCM_GPIO_ALT5, - BCM_GPIO_ALT4, - BCM_GPIO_ALT0, - BCM_GPIO_ALT1, - BCM_GPIO_ALT2, - BCM_GPIO_ALT3, -}; - enum bcm_gpio_pud { BCM_GPIO_NONE, BCM_GPIO_PULLDOWN, @@ -257,6 +248,32 @@ bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state) BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0); } +void +bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc) +{ + struct bcm_gpio_softc *sc; + int i; + + sc = device_get_softc(dev); + BCM_GPIO_LOCK(sc); + + /* Disable pull-up or pull-down on pin. */ + bcm_gpio_set_pud(sc, pin, BCM_GPIO_NONE); + + /* And now set the pin function. */ + bcm_gpio_set_function(sc, pin, nfunc); + + /* Update the pin flags. */ + 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) + sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc); + + BCM_GPIO_UNLOCK(sc); +} + static void bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin, unsigned int flags) @@ -535,7 +552,7 @@ bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS) struct bcm_gpio_softc *sc; struct bcm_gpio_sysctl *sc_sysctl; uint32_t nfunc; - int i, error; + int error; sc_sysctl = arg1; sc = sc_sysctl->sc; @@ -552,23 +569,8 @@ bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS) if (bcm_gpio_str_func(buf, &nfunc) != 0) return (EINVAL); - BCM_GPIO_LOCK(sc); - - /* Disable pull-up or pull-down on pin. */ - bcm_gpio_set_pud(sc, sc_sysctl->pin, BCM_GPIO_NONE); - - /* And now set the pin function. */ - bcm_gpio_set_function(sc, sc_sysctl->pin, nfunc); - - /* Update the pin flags. */ - for (i = 0; i < sc->sc_gpio_npins; i++) { - if (sc->sc_gpio_pins[i].gp_pin == sc_sysctl->pin) - break; - } - if (i < sc->sc_gpio_npins) - sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc); - - BCM_GPIO_UNLOCK(sc); + /* Update the pin alternate function. */ + bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc); return (0); } @@ -729,7 +731,7 @@ bcm_gpio_attach(device_t dev) goto fail; /* Initialize the software controlled pins. */ - for (i = 0, j = 0; j < BCM_GPIO_PINS - 1; j++) { + for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) { if (bcm_gpio_pin_is_ro(sc, j)) continue; snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, |