From owner-svn-src-all@FreeBSD.ORG Thu Dec 15 01:03:49 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 99AF8106566C; Thu, 15 Dec 2011 01:03:49 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7EE328FC12; Thu, 15 Dec 2011 01:03:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBF13nex022579; Thu, 15 Dec 2011 01:03:49 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBF13n6o022577; Thu, 15 Dec 2011 01:03:49 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201112150103.pBF13n6o022577@svn.freebsd.org> From: Adrian Chadd Date: Thu, 15 Dec 2011 01:03:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228518 - head/sys/mips/atheros X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Dec 2011 01:03:49 -0000 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));