dm: Add support for LEDs
authorSimon Glass <sjg@chromium.org>
Tue, 23 Jun 2015 21:38:45 +0000 (15:38 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 21 Jul 2015 23:39:24 +0000 (17:39 -0600)
Add a simple uclass for LEDs, so that these can be controlled by the device
tree and activated when needed. LEDs are referred to by their label.

This implementation requires a driver for each type of LED (e.g GPIO, I2C).

Signed-off-by: Simon Glass <sjg@chromium.org>
doc/device-tree-bindings/leds/common.txt [new file with mode: 0644]
drivers/Kconfig
drivers/Makefile
drivers/led/Kconfig [new file with mode: 0644]
drivers/led/Makefile [new file with mode: 0644]
drivers/led/led-uclass.c [new file with mode: 0644]
include/dm/uclass-id.h
include/led.h [new file with mode: 0644]
scripts/Makefile.spl

diff --git a/doc/device-tree-bindings/leds/common.txt b/doc/device-tree-bindings/leds/common.txt
new file mode 100644 (file)
index 0000000..2d88816
--- /dev/null
@@ -0,0 +1,23 @@
+Common leds properties.
+
+Optional properties for child nodes:
+- label : The label for this LED.  If omitted, the label is
+  taken from the node name (excluding the unit address).
+
+- linux,default-trigger :  This parameter, if present, is a
+    string defining the trigger assigned to the LED.  Current triggers are:
+     "backlight" - LED will act as a back-light, controlled by the framebuffer
+                  system
+     "default-on" - LED will turn on (but for leds-gpio see "default-state"
+                   property in Documentation/devicetree/bindings/gpio/led.txt)
+     "heartbeat" - LED "double" flashes at a load average based rate
+     "ide-disk" - LED indicates disk activity
+     "timer" - LED flashes at a fixed, configurable rate
+
+Examples:
+
+system-status {
+       label = "Status";
+       linux,default-trigger = "heartbeat";
+       ...
+};
index c7e526cc8a7f5c0a62e97993f2048e4c21caa03e..5ebc89da9129c0e43b2bce4e581a7d8acd43cd1c 100644 (file)
@@ -20,6 +20,8 @@ source "drivers/net/Kconfig"
 
 source "drivers/input/Kconfig"
 
+source "drivers/led/Kconfig"
+
 source "drivers/serial/Kconfig"
 
 source "drivers/tpm/Kconfig"
index 405b64b26873ce5076b56047128a4f62de565e73..c090aba30d95d4bbab119e8202eb393df320b2d1 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
+obj-$(CONFIG_LED) += led/
 obj-y += misc/
 obj-y += pcmcia/
 obj-y += dfu/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644 (file)
index 0000000..e4d9a84
--- /dev/null
@@ -0,0 +1,17 @@
+config LED
+       bool "Enable LED support"
+       depends on DM
+       help
+         Many boards have LEDs which can be used to signal status or alerts.
+         U-Boot provides a uclass API to implement this feature. LED drivers
+         can provide access to board-specific LEDs. Use of the device tree
+         for configuration is encouraged.
+
+config SPL_LED_SUPPORT
+       bool "Enable LED support in SPL"
+       depends on LED
+       help
+         The LED subsystem adds a small amount of overhead to the image.
+         If this is acceptable and you have a need to use LEDs in SPL,
+         enable this option. You will need to enable device tree in SPL
+         for this to work.
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644 (file)
index 0000000..b39b205
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_LED) += led-uclass.o
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
new file mode 100644 (file)
index 0000000..a80ae93
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+int led_get_by_label(const char *label, struct udevice **devp)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_LED, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(dev, uc) {
+               struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+               if (!strcmp(label, uc_plat->label))
+                       return uclass_get_device_tail(dev, 0, devp);
+       }
+
+       return -ENOENT;
+}
+
+int led_set_on(struct udevice *dev, int on)
+{
+       struct led_ops *ops = led_get_ops(dev);
+
+       if (!ops->set_on)
+               return -ENOSYS;
+
+       return ops->set_on(dev, on);
+}
+
+UCLASS_DRIVER(led) = {
+       .id             = UCLASS_LED,
+       .name           = "led",
+       .per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+};
index 24baa5cd648bdf7e0fea1b0a4ba30ea1f8c2b1f4..a961648645eaa3d17ac3b071723a44525d9ea51f 100644 (file)
@@ -33,6 +33,7 @@ enum uclass_id {
        UCLASS_I2C,             /* I2C bus */
        UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
        UCLASS_I2C_GENERIC,     /* Generic I2C device */
+       UCLASS_LED,             /* Light-emitting diode (LED) */
        UCLASS_LPC,             /* x86 'low pin count' interface */
        UCLASS_MASS_STORAGE,    /* Mass storage device */
        UCLASS_MOD_EXP,         /* RSA Mod Exp device */
diff --git a/include/led.h b/include/led.h
new file mode 100644 (file)
index 0000000..8925d75
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __LED_H
+#define __LED_H
+
+/**
+ * struct led_uclass_plat - Platform data the uclass stores about each device
+ *
+ * @label:     LED label
+ */
+struct led_uclass_plat {
+       const char *label;
+};
+
+struct led_ops {
+       /**
+        * set_on() - set the state of an LED
+        *
+        * @dev:        LED device to change
+        * @on:         1 to turn the LED on, 0 to turn it off
+        * @return 0 if OK, -ve on error
+        */
+       int (*set_on)(struct udevice *dev, int on);
+};
+
+#define led_get_ops(dev)       ((struct led_ops *)(dev)->driver->ops)
+
+/**
+ * led_get_by_label() - Find an LED device by label
+ *
+ * @label:     LED label to look up
+ * @devp:      Returns the associated device, if found
+ * @return 0 if found, -ve on error
+ */
+int led_get_by_label(const char *label, struct udevice **devp);
+
+/**
+ * led_set_on() - set the state of an LED
+ *
+ * @dev:       LED device to change
+ * @on:                1 to turn the LED on, 0 to turn it off
+ * @return 0 if OK, -ve on error
+ */
+int led_set_on(struct udevice *dev, int on);
+
+#endif
index bcc7ca2f894a8d434b87fe7a42d0e44e12177a4f..6b32618a61a79e88aece0f9ed1b5de622701d87c 100644 (file)
@@ -64,6 +64,7 @@ libs-$(CONFIG_SPL_SERIAL_SUPPORT) += drivers/serial/
 libs-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/
 libs-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/
 libs-y += fs/
+libs-$(CONFIG_SPL_LED_SUPPORT) += drivers/led/
 libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
 libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/
 libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/