179 lines
4.3 KiB
Plaintext
179 lines
4.3 KiB
Plaintext
diff -Nur a/arch/arm/Kconfig leds/arch/arm/Kconfig
|
|
--- a/arch/arm/Kconfig 2016-09-12 16:05:51.000000000 +0200
|
|
+++ leds/arch/arm/Kconfig 2016-09-21 19:17:56.246729135 +0200
|
|
@@ -651,6 +651,8 @@
|
|
select DM_KEYBOARD
|
|
select DM_SERIAL
|
|
select DM_USB
|
|
+ select LED
|
|
+ select LED_GPIO
|
|
select OF_BOARD_SETUP
|
|
select OF_CONTROL
|
|
select OF_SEPARATE
|
|
diff -Nur a/board/sunxi/board.c leds/board/sunxi/board.c
|
|
--- a/board/sunxi/board.c 2016-09-12 16:05:51.000000000 +0200
|
|
+++ leds/board/sunxi/board.c 2016-09-21 19:14:16.236727224 +0200
|
|
@@ -29,6 +29,7 @@
|
|
#include <asm/io.h>
|
|
#include <crc.h>
|
|
#include <environment.h>
|
|
+#include <led.h>
|
|
#include <libfdt.h>
|
|
#include <nand.h>
|
|
#include <net.h>
|
|
@@ -682,6 +683,12 @@
|
|
{
|
|
__maybe_unused int ret;
|
|
|
|
+#ifdef CONFIG_LED
|
|
+ ret = led_set_default_states();
|
|
+ if (ret)
|
|
+ return ret;
|
|
+#endif
|
|
+
|
|
setenv("fel_booted", NULL);
|
|
setenv("fel_scriptaddr", NULL);
|
|
/* determine if we are running in FEL mode */
|
|
diff -Nur a/drivers/led/led_gpio.c leds/drivers/led/led_gpio.c
|
|
--- a/drivers/led/led_gpio.c 2016-09-12 16:05:51.000000000 +0200
|
|
+++ leds/drivers/led/led_gpio.c 2016-09-21 19:14:16.236727224 +0200
|
|
@@ -67,6 +67,7 @@
|
|
node = fdt_next_subnode(blob, node)) {
|
|
struct led_uclass_plat *uc_plat;
|
|
const char *label;
|
|
+ const char *state;
|
|
|
|
label = fdt_getprop(blob, node, "label", NULL);
|
|
if (!label) {
|
|
@@ -74,6 +75,7 @@
|
|
fdt_get_name(blob, node, NULL));
|
|
return -EINVAL;
|
|
}
|
|
+ state = fdt_getprop(blob, node, "default-state", NULL);
|
|
ret = device_bind_driver_to_node(parent, "gpio_led",
|
|
fdt_get_name(blob, node, NULL),
|
|
node, &dev);
|
|
@@ -81,6 +83,15 @@
|
|
return ret;
|
|
uc_plat = dev_get_uclass_platdata(dev);
|
|
uc_plat->label = label;
|
|
+ if (state) {
|
|
+ if(!strcmp(state, "on"))
|
|
+ uc_plat->default_state = LED_STATE_ON;
|
|
+ else if(!strcmp(state, "keep"))
|
|
+ uc_plat->default_state = LED_STATE_KEEP;
|
|
+ else
|
|
+ uc_plat->default_state = LED_STATE_OFF;
|
|
+ } else
|
|
+ uc_plat->default_state = LED_STATE_OFF;
|
|
}
|
|
|
|
return 0;
|
|
diff -Nur a/drivers/led/led-uclass.c leds/drivers/led/led-uclass.c
|
|
--- a/drivers/led/led-uclass.c 2016-09-12 16:05:51.000000000 +0200
|
|
+++ leds/drivers/led/led-uclass.c 2016-09-21 19:14:16.236727224 +0200
|
|
@@ -12,6 +12,21 @@
|
|
#include <dm/root.h>
|
|
#include <dm/uclass-internal.h>
|
|
|
|
+int led_autoset(struct udevice *dev)
|
|
+{
|
|
+ struct led_uclass_plat *uc_pdata;
|
|
+ int ret = 0;
|
|
+
|
|
+ uc_pdata = dev_get_uclass_platdata(dev);
|
|
+ if (!uc_pdata->label)
|
|
+ return -EMEDIUMTYPE;
|
|
+
|
|
+ if (uc_pdata->default_state != LED_STATE_KEEP)
|
|
+ ret = led_set_on(dev, uc_pdata->default_state == LED_STATE_ON);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int led_get_by_label(const char *label, struct udevice **devp)
|
|
{
|
|
struct udevice *dev;
|
|
@@ -32,6 +47,26 @@
|
|
return -ENODEV;
|
|
}
|
|
|
|
+int led_set_default_states(void)
|
|
+{
|
|
+ struct udevice *dev;
|
|
+ struct uclass *uc;
|
|
+ int ret;
|
|
+
|
|
+ ret = uclass_get(UCLASS_LED, &uc);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ for (uclass_first_device(UCLASS_LED, &dev);
|
|
+ dev;
|
|
+ uclass_next_device(&dev)) {
|
|
+ ret = led_autoset(dev);
|
|
+ if (ret == -EMEDIUMTYPE || ret == -ENOSYS)
|
|
+ ret = 0;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int led_set_on(struct udevice *dev, int on)
|
|
{
|
|
struct led_ops *ops = led_get_ops(dev);
|
|
diff -Nur a/include/led.h leds/include/led.h
|
|
--- a/include/led.h 2016-09-12 16:05:51.000000000 +0200
|
|
+++ leds/include/led.h 2016-09-21 19:14:16.236727224 +0200
|
|
@@ -8,6 +8,14 @@
|
|
#ifndef __LED_H
|
|
#define __LED_H
|
|
|
|
+/* LED default states
|
|
+ */
|
|
+enum led_default_state {
|
|
+ LED_STATE_OFF,
|
|
+ LED_STATE_ON,
|
|
+ LED_STATE_KEEP
|
|
+};
|
|
+
|
|
/**
|
|
* struct led_uclass_plat - Platform data the uclass stores about each device
|
|
*
|
|
@@ -15,6 +23,7 @@
|
|
*/
|
|
struct led_uclass_plat {
|
|
const char *label;
|
|
+ enum led_default_state default_state;
|
|
};
|
|
|
|
struct led_ops {
|
|
@@ -31,6 +40,14 @@
|
|
#define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops)
|
|
|
|
/**
|
|
+ * led_autoset() - set the state of an LED according to fdt
|
|
+ *
|
|
+ * @dev: LED device to set
|
|
+ * @return 0 if OK, -ve on error
|
|
+ */
|
|
+int led_autoset(struct udevice *dev);
|
|
+
|
|
+/**
|
|
* led_get_by_label() - Find an LED device by label
|
|
*
|
|
* @label: LED label to look up
|
|
@@ -40,6 +57,13 @@
|
|
int led_get_by_label(const char *label, struct udevice **devp);
|
|
|
|
/**
|
|
+ * led_set_default_states() - set the state of all LEDs according to fdt
|
|
+ *
|
|
+ * @return 0 if OK, -ve on error
|
|
+ */
|
|
+int led_set_default_states(void);
|
|
+
|
|
+/**
|
|
* led_set_on() - set the state of an LED
|
|
*
|
|
* @dev: LED device to change
|