summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-04-17 02:07:52 (GMT)
committerTom Rini <trini@konsulko.com>2017-04-17 02:07:52 (GMT)
commit51f866e8da758a27af596af73466bd5f0a450c4d (patch)
treeb4d47e5782265bec5ad8adcc43c43a118062ba6d /drivers
parent3fea95369850987de15a2a0ac009d05e13b90246 (diff)
parentad46af0e76384b22058d9ac979f34fad2483aff3 (diff)
downloadu-boot-fsl-qoriq-51f866e8da758a27af596af73466bd5f0a450c4d.tar.xz
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/led/Kconfig10
-rw-r--r--drivers/led/led-uclass.c32
-rw-r--r--drivers/led/led_gpio.c39
3 files changed, 71 insertions, 10 deletions
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 609b1fa..309372a 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -9,6 +9,15 @@ config LED
can provide access to board-specific LEDs. Use of the device tree
for configuration is encouraged.
+config LED_BLINK
+ bool "Support LED blinking"
+ depends on LED
+ help
+ Some drivers can support automatic blinking of LEDs with a given
+ period, without needing timers or extra code to handle the timing.
+ This option enables support for this which adds slightly to the
+ code size.
+
config SPL_LED
bool "Enable LED support in SPL"
depends on SPL && SPL_DM
@@ -17,6 +26,7 @@ config SPL_LED
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.
+
config LED_GPIO
bool "LED support for GPIO-connected LEDs"
depends on LED && DM_GPIO
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index 784ac87..78ab760 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -22,7 +22,7 @@ int led_get_by_label(const char *label, struct udevice **devp)
if (ret)
return ret;
uclass_foreach_dev(dev, uc) {
- struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+ struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
/* Ignore the top-level LED node */
if (uc_plat->label && !strcmp(label, uc_plat->label))
@@ -32,18 +32,40 @@ int led_get_by_label(const char *label, struct udevice **devp)
return -ENODEV;
}
-int led_set_on(struct udevice *dev, int on)
+int led_set_state(struct udevice *dev, enum led_state_t state)
{
struct led_ops *ops = led_get_ops(dev);
- if (!ops->set_on)
+ if (!ops->set_state)
return -ENOSYS;
- return ops->set_on(dev, on);
+ return ops->set_state(dev, state);
}
+enum led_state_t led_get_state(struct udevice *dev)
+{
+ struct led_ops *ops = led_get_ops(dev);
+
+ if (!ops->get_state)
+ return -ENOSYS;
+
+ return ops->get_state(dev);
+}
+
+#ifdef CONFIG_LED_BLINK
+int led_set_period(struct udevice *dev, int period_ms)
+{
+ struct led_ops *ops = led_get_ops(dev);
+
+ if (!ops->set_period)
+ return -ENOSYS;
+
+ return ops->set_period(dev, period_ms);
+}
+#endif
+
UCLASS_DRIVER(led) = {
.id = UCLASS_LED,
.name = "led",
- .per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+ .per_device_platdata_auto_alloc_size = sizeof(struct led_uc_plat),
};
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 5b11990..4106ecb 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -18,19 +18,47 @@ struct led_gpio_priv {
struct gpio_desc gpio;
};
-static int gpio_led_set_on(struct udevice *dev, int on)
+static int gpio_led_set_state(struct udevice *dev, enum led_state_t state)
{
struct led_gpio_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ if (!dm_gpio_is_valid(&priv->gpio))
+ return -EREMOTEIO;
+ switch (state) {
+ case LEDST_OFF:
+ case LEDST_ON:
+ break;
+ case LEDST_TOGGLE:
+ ret = dm_gpio_get_value(&priv->gpio);
+ if (ret < 0)
+ return ret;
+ state = !ret;
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ return dm_gpio_set_value(&priv->gpio, state);
+}
+
+static enum led_state_t gpio_led_get_state(struct udevice *dev)
+{
+ struct led_gpio_priv *priv = dev_get_priv(dev);
+ int ret;
if (!dm_gpio_is_valid(&priv->gpio))
return -EREMOTEIO;
+ ret = dm_gpio_get_value(&priv->gpio);
+ if (ret < 0)
+ return ret;
- return dm_gpio_set_value(&priv->gpio, on);
+ return ret ? LEDST_ON : LEDST_OFF;
}
static int led_gpio_probe(struct udevice *dev)
{
- struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+ struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
struct led_gpio_priv *priv = dev_get_priv(dev);
/* Ignore the top-level LED node */
@@ -65,7 +93,7 @@ static int led_gpio_bind(struct udevice *parent)
for (node = fdt_first_subnode(blob, dev_of_offset(parent));
node > 0;
node = fdt_next_subnode(blob, node)) {
- struct led_uclass_plat *uc_plat;
+ struct led_uc_plat *uc_plat;
const char *label;
label = fdt_getprop(blob, node, "label", NULL);
@@ -87,7 +115,8 @@ static int led_gpio_bind(struct udevice *parent)
}
static const struct led_ops gpio_led_ops = {
- .set_on = gpio_led_set_on,
+ .set_state = gpio_led_set_state,
+ .get_state = gpio_led_get_state,
};
static const struct udevice_id led_gpio_ids[] = {