TL-WR1043: LEDs

Stefan Bethke stb at lassitu.de
Mon Nov 28 22:12:57 UTC 2011


Here's a quick and dirty hack to use the ar71xx GPIO module to get the pin configuration from a hint.

Add
  device  gpio
  device  gpioled
to your kernel config to enable these.  See gpioctl(1) and led(4) for how to control them.  The buttons can be polled with gpioctl.

-- 
Stefan Bethke <stb at lassitu.de>   Fon +49 151 14070811


-------------- next part --------------
Index: mips/atheros/ar71xx_gpio.c
===================================================================
--- mips/atheros/ar71xx_gpio.c	(revision 228073)
+++ mips/atheros/ar71xx_gpio.c	(working copy)
@@ -349,6 +349,50 @@
 }
 
 static int
+ar71xx_gpio_configure_from_hint(device_t dev)
+{
+	struct ar71xx_gpio_softc *sc = device_get_softc(dev);
+	const char *c, *d;
+	int i;
+	
+	if (resource_string_value(device_get_name(dev), 
+	    device_get_unit(dev), "pins", &c))
+		return (ENXIO);
+	device_printf(dev, "pins=%s\n", c);
+	i = 0;
+	/* "1=o:usb,2=o:sys,3=i:reset,5=o:qss,7=i:qss,9=o:wlan" */
+	while (c) {
+		d = strchr(c, '=');
+		if (d == NULL)
+			return (ENXIO);
+        sc->gpio_pins[i].gp_pin = strtol(c, NULL, 10);
+        sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
+        sc->gpio_pins[i].gp_flags = 0;
+		d++;
+		if (d[0] != 'i' && d[0] != 'o' && d[1] != ':')
+			return (ENXIO);
+        ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i],
+			d[0] == 'o' ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT);
+		d += 2;
+		c = d;
+		d = strchr(d, ',');
+		if (d != NULL) {
+	        strncpy(sc->gpio_pins[i].gp_name, c,
+				d - c < GPIOMAXNAME ? d - c : GPIOMAXNAME);
+			c = d;
+			c++;
+		} else {
+	        strncpy(sc->gpio_pins[i].gp_name, c, GPIOMAXNAME);
+			c = NULL;
+		}
+		device_printf(dev, "pin %0x=%s\n", sc->gpio_pins[i].gp_pin, sc->gpio_pins[i].gp_name);
+		i++;
+	}
+	sc->gpio_npins = i;
+	return (0);
+}
+
+static int
 ar71xx_gpio_attach(device_t dev)
 {
 	struct ar71xx_gpio_softc *sc = device_get_softc(dev);
@@ -393,20 +437,21 @@
 	/* 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;
-		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++;
-		i++;
+	if (ar71xx_gpio_configure_from_hint(dev)) {
+        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;
+            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++;
+            i++;
+        }
+        sc->gpio_npins = 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));
Index: mips/conf/TP-WN1043ND.hints
===================================================================
--- mips/conf/TP-WN1043ND.hints	(revision 228073)
+++ mips/conf/TP-WN1043ND.hints	(working copy)
@@ -75,3 +75,27 @@
 hint.map.4.end=0x00800000
 hint.map.4.name="art"
 hint.map.4.readonly=1
+
+# GPIO
+hint.gpio.0.at="apb0"
+hint.gpio.0.maddr=0x18040000
+hint.gpio.0.msize=0x10000
+hint.gpio.0.irq=2
+hint.gpio.0.pins="1=o:usb,2=o:sys,3=i:reset,5=o:qss,7=i:qss,9=o:wlan"
+
+# LEDs
+hint.gpioled.0.at="gpiobus0"
+hint.gpioled.0.name="usb"
+hint.gpioled.0.pins=0x0002
+
+hint.gpioled.1.at="gpiobus0"
+hint.gpioled.1.name="sys"
+hint.gpioled.1.pins=0x0004
+
+hint.gpioled.2.at="gpiobus0"
+hint.gpioled.2.name="qss"
+hint.gpioled.2.pins=0x0020
+
+hint.gpioled.3.at="gpiobus0"
+hint.gpioled.3.name="wlan"
+hint.gpioled.3.pins=0x0200


More information about the freebsd-embedded mailing list