dm: Add support for LEDs

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>
This commit is contained in:
Simon Glass 2015-06-23 15:38:45 -06:00
parent 5725128507
commit 5917112c9e
9 changed files with 152 additions and 0 deletions

View file

@ -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";
...
};

View 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"

View 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/

17
drivers/led/Kconfig Normal file
View file

@ -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.

8
drivers/led/Makefile Normal file
View file

@ -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

48
drivers/led/led-uclass.c Normal file
View file

@ -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),
};

View 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 */

51
include/led.h Normal file
View file

@ -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

View 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/