]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-pxa/lubbock.c
Merge branch 'for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney...
[karo-tx-linux.git] / arch / arm / mach-pxa / lubbock.c
index 0ca0db787903ab104ef9c0f216148cc3c32acee6..3c48035afd6bcf89c5acd64b5a96c3060fa763c3 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
 #include <linux/major.h>
@@ -23,6 +24,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/smc91x.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -549,6 +552,98 @@ static void __init lubbock_map_io(void)
        PCFR |= PCFR_OPDE;
 }
 
+/*
+ * Driver for the 8 discrete LEDs available for general use:
+ * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
+ * so be sure to not monkey with them here.
+ */
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct lubbock_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} lubbock_leds[] = {
+       { "lubbock:D28", "default-on", },
+       { "lubbock:D27", "cpu0", },
+       { "lubbock:D26", "heartbeat" },
+       { "lubbock:D25", },
+       { "lubbock:D24", },
+       { "lubbock:D23", },
+       { "lubbock:D22", },
+       { "lubbock:D21", },
+};
+
+static void lubbock_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       struct lubbock_led *led = container_of(cdev,
+                                        struct lubbock_led, cdev);
+       u32 reg = LUB_DISC_BLNK_LED;
+
+       if (b != LED_OFF)
+               reg |= led->mask;
+       else
+               reg &= ~led->mask;
+
+       LUB_DISC_BLNK_LED = reg;
+}
+
+static enum led_brightness lubbock_led_get(struct led_classdev *cdev)
+{
+       struct lubbock_led *led = container_of(cdev,
+                                        struct lubbock_led, cdev);
+       u32 reg = LUB_DISC_BLNK_LED;
+
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init lubbock_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_lubbock())
+               return -ENODEV;
+
+       /* All ON */
+       LUB_DISC_BLNK_LED |= 0xff;
+       for (i = 0; i < ARRAY_SIZE(lubbock_leds); i++) {
+               struct lubbock_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = lubbock_leds[i].name;
+               led->cdev.brightness_set = lubbock_led_set;
+               led->cdev.brightness_get = lubbock_led_get;
+               led->cdev.default_trigger = lubbock_leds[i].trigger;
+               led->mask = BIT(i);
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(lubbock_leds_init);
+#endif
+
 MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
        /* Maintainer: MontaVista Software Inc. */
        .map_io         = lubbock_map_io,