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));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to