Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Dec 2011 01:03:49 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r228518 - head/sys/mips/atheros
Message-ID:  <201112150103.pBF13n6o022577@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112150103.pBF13n6o022577>