svn commit: r228518 - head/sys/mips/atheros
Adrian Chadd
adrian at FreeBSD.org
Thu Dec 15 01:03:49 UTC 2011
Author: adrian
Date: Thu Dec 15 01:03:49 2011
New Revision: 228518
URL: http://svn.freebsd.org/changeset/base/228518
Log:
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.
Modified:
head/sys/mips/atheros/ar71xx_gpio.c
Modified: head/sys/mips/atheros/ar71xx_gpio.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_gpio.c Thu Dec 15 00:59:11 2011 (r228517)
+++ head/sys/mips/atheros/ar71xx_gpio.c Thu Dec 15 01:03:49 2011 (r228518)
@@ -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));
More information about the svn-src-head
mailing list