summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2011-12-15 01:03:49 +0000
committeradrian <adrian@FreeBSD.org>2011-12-15 01:03:49 +0000
commit1af383c5f6fceadf05a48b89f197d7031db17f5f (patch)
tree86022f3889ca5adb09c22c09555019a17c415244 /sys/mips
parent7c11417460b479740a44ec589a200214c10af10b (diff)
downloadFreeBSD-src-1af383c5f6fceadf05a48b89f197d7031db17f5f.zip
FreeBSD-src-1af383c5f6fceadf05a48b89f197d7031db17f5f.tar.gz
Re-jiggle the GPIO code a little to remove the hard-coded AR71xx GPIO
config and function mask setup. * "gpiomask" now specifies which GPIO pins to enable, for devices to bind to. * "function_set" allows bits in the function register to be set at GPIO setup. * "function_clear" allows bits in the function register to be cleared at GPIO setup. The function_set/function_clear bits allow for individual GPIO pins to either drive a GPIO line or an alternate function - eg USB, JTAG, etc. This allows for things like CS1/CS2 be enabled for those boards w/ >1 SPI device connected, or disabling JTAG for the AR7240 (which is apparently needed ..) I've verified this on the AR71xx.
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/atheros/ar71xx_gpio.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c
index 09b4d50..11906ff 100644
--- a/sys/mips/atheros/ar71xx_gpio.c
+++ b/sys/mips/atheros/ar71xx_gpio.c
@@ -54,18 +54,6 @@ __FBSDID("$FreeBSD$");
#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
-struct ar71xx_gpio_pin {
- const char *name;
- int pin;
- int flags;
-};
-
-static struct ar71xx_gpio_pin ar71xx_gpio_pins[] = {
- { "RFled", 2, GPIO_PIN_OUTPUT},
- { "SW4", 8, GPIO_PIN_INPUT},
- { NULL, 0, 0},
-};
-
/*
* Helpers
*/
@@ -353,8 +341,9 @@ ar71xx_gpio_attach(device_t dev)
{
struct ar71xx_gpio_softc *sc = device_get_softc(dev);
int error = 0;
- struct ar71xx_gpio_pin *pinp;
- int i;
+ int i, j, maxpin;
+ int mask;
+ int old = 0;
KASSERT((device_get_unit(dev) == 0),
("ar71xx_gpio: Only one gpio module supported"));
@@ -388,25 +377,49 @@ ar71xx_gpio_attach(device_t dev)
}
sc->dev = dev;
- ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS1_EN);
- ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS2_EN);
+
+ /* Enable function bits that are required */
+ if (resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "function_set", &mask) == 0) {
+ device_printf(dev, "function_set: 0x%x\n", mask);
+ ar71xx_gpio_function_enable(sc, mask);
+ old = 1;
+ }
+ /* Disable function bits that are required */
+ if (resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "function_clear", &mask) == 0) {
+ device_printf(dev, "function_clear: 0x%x\n", mask);
+ ar71xx_gpio_function_disable(sc, mask);
+ old = 1;
+ }
+ /* Handle previous behaviour */
+ if (old == 0) {
+ ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS1_EN);
+ ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS2_EN);
+ }
+
/* Configure all pins as input */
/* disable interrupts for all pins */
GPIO_WRITE(sc, AR71XX_GPIO_INT_MASK, 0);
- pinp = ar71xx_gpio_pins;
- i = 0;
- while (pinp->name) {
- strncpy(sc->gpio_pins[i].gp_name, pinp->name, GPIOMAXNAME);
- sc->gpio_pins[i].gp_pin = pinp->pin;
+
+ /* Initialise all pins specified in the mask, up to the pin count */
+ (void) ar71xx_gpio_pin_max(dev, &maxpin);
+ if (resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "pinmask", &mask) != 0)
+ mask = 0;
+ device_printf(dev, "gpio pinmask=0x%x\n", mask);
+ for (i = 0, j = 0; j < maxpin; j++) {
+ if ((mask & (1 << j)) == 0)
+ continue;
+ snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+ "pin %d", j);
+ sc->gpio_pins[i].gp_pin = j;
sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
sc->gpio_pins[i].gp_flags = 0;
- ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], pinp->flags);
- pinp++;
+ ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], DEFAULT_CAPS);
i++;
}
-
sc->gpio_npins = i;
-
device_add_child(dev, "gpioc", device_get_unit(dev));
device_add_child(dev, "gpiobus", device_get_unit(dev));
return (bus_generic_attach(dev));
OpenPOWER on IntegriCloud