diff options
author | loos <loos@FreeBSD.org> | 2013-09-07 18:48:15 +0000 |
---|---|---|
committer | loos <loos@FreeBSD.org> | 2013-09-07 18:48:15 +0000 |
commit | b8f3cdb508d7d303d69e22ec5efefeb0df381609 (patch) | |
tree | 5da602d8be56b5804331fb9b25c25c1ce601f91a /sys/arm | |
parent | e50a38ba7d89531f414524bd714e30fce12441da (diff) | |
download | FreeBSD-src-b8f3cdb508d7d303d69e22ec5efefeb0df381609.zip FreeBSD-src-b8f3cdb508d7d303d69e22ec5efefeb0df381609.tar.gz |
Export a function to allow BCM2835's peripheral devices to enable their
altenate pin function (from GPIO pins) as needed.
Approved by: adrian (mentor)
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 60 | ||||
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_gpio.h | 44 |
2 files changed, 75 insertions, 29 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 267e3f9..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); } diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.h b/sys/arm/broadcom/bcm2835/bcm2835_gpio.h new file mode 100644 index 0000000..911bcf2 --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@bluezbox.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _BCM2835_GPIO_H_ +#define _BCM2835_GPIO_H_ + +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, +}; + +void bcm_gpio_set_alternate(device_t, uint32_t, uint32_t); + +#endif /* _BCM2835_GPIO_H_ */ |