diff mbox

[U-Boot,v2,7/9] dm: led: Add support for blinking LEDs

Message ID 20170410173459.30461-8-sjg@chromium.org
State Accepted
Commit 53378dac8dc33e3fd5f07d60bd7a5f8258ac7a20
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass April 10, 2017, 5:34 p.m. UTC
Allow LEDs to be blinked if the driver supports it. Enable this for
sandbox so that the tests run.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Control this feature via a new CONFIG_LED_BLINK option

 configs/sandbox_defconfig       |  1 +
 configs/sandbox_noblk_defconfig |  1 +
 configs/sandbox_spl_defconfig   |  1 +
 drivers/led/Kconfig             |  9 +++++++++
 drivers/led/led-uclass.c        | 12 ++++++++++++
 include/led.h                   | 35 +++++++++++++++++++++++++++++++++++
 test/dm/led.c                   | 24 ++++++++++++++++++++++++
 7 files changed, 83 insertions(+)

Comments

techping.chan@gmail.com April 12, 2017, 8:52 a.m. UTC | #1
2017-04-11 1:34 GMT+08:00 Simon Glass <sjg@chromium.org>:

> Allow LEDs to be blinked if the driver supports it. Enable this for
> sandbox so that the tests run.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Control this feature via a new CONFIG_LED_BLINK option
>
>  configs/sandbox_defconfig       |  1 +
>  configs/sandbox_noblk_defconfig |  1 +
>  configs/sandbox_spl_defconfig   |  1 +
>  drivers/led/Kconfig             |  9 +++++++++
>  drivers/led/led-uclass.c        | 12 ++++++++++++
>  include/led.h                   | 35 +++++++++++++++++++++++++++++++++++
>  test/dm/led.c                   | 24 ++++++++++++++++++++++++
>  7 files changed, 83 insertions(+)
>
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index 7f3f5ac809..9814ea3b81 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -83,6 +83,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y
>  CONFIG_CROS_EC_KEYB=y
>  CONFIG_I8042_KEYB=y
>  CONFIG_LED=y
> +CONFIG_LED_BLINK=y
>  CONFIG_LED_GPIO=y
>  CONFIG_DM_MAILBOX=y
>  CONFIG_SANDBOX_MBOX=y
> diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_
> defconfig
> index 3f8e70d523..bba744332c 100644
> --- a/configs/sandbox_noblk_defconfig
> +++ b/configs/sandbox_noblk_defconfig
> @@ -92,6 +92,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y
>  CONFIG_CROS_EC_KEYB=y
>  CONFIG_I8042_KEYB=y
>  CONFIG_LED=y
> +CONFIG_LED_BLINK=y
>  CONFIG_LED_GPIO=y
>  CONFIG_CROS_EC=y
>  CONFIG_CROS_EC_I2C=y
> diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
> index ade67143b1..6fe21254fd 100644
> --- a/configs/sandbox_spl_defconfig
> +++ b/configs/sandbox_spl_defconfig
> @@ -94,6 +94,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y
>  CONFIG_CROS_EC_KEYB=y
>  CONFIG_I8042_KEYB=y
>  CONFIG_LED=y
> +CONFIG_LED_BLINK=y
>  CONFIG_LED_GPIO=y
>  CONFIG_DM_MAILBOX=y
>  CONFIG_SANDBOX_MBOX=y
> diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> index 0ef45bc06a..309372ab56 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
> diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
> index ea5fbabadf..78ab76050d 100644
> --- a/drivers/led/led-uclass.c
> +++ b/drivers/led/led-uclass.c
> @@ -52,6 +52,18 @@ enum led_state_t led_get_state(struct udevice *dev)
>         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",
> diff --git a/include/led.h b/include/led.h
> index 8c107e28e7..c67af22591 100644
> --- a/include/led.h
> +++ b/include/led.h
> @@ -17,10 +17,22 @@ struct led_uc_plat {
>         const char *label;
>  };
>
> +/**
> + * struct led_uc_priv - Private data the uclass stores about each device
> + *
> + * @period_ms: Flash period in milliseconds
> + */
> +struct led_uc_priv {
> +       int period_ms;
> +};
> +
>  enum led_state_t {
>         LEDST_OFF = 0,
>         LEDST_ON = 1,
>         LEDST_TOGGLE,
> +#ifdef CONFIG_LED_BLINK
> +       LEDST_BLINK,
> +#endif
>
>         LEDST_COUNT,
>  };
> @@ -42,6 +54,20 @@ struct led_ops {
>          * @return LED state led_state_t, or -ve on error
>          */
>         enum led_state_t (*get_state)(struct udevice *dev);
> +
> +#ifdef CONFIG_LED_BLINK
> +       /**
> +        * led_set_period() - set the blink period of an LED
> +        *
> +        * Thie records the period if supported, or returns -ENOSYS if not.
> +        * To start the LED blinking, use set_state().
> +        *
> +        * @dev:        LED device to change
> +        * @period_ms:  LED blink period in milliseconds
> +        * @return 0 if OK, -ve on error
> +        */
> +       int (*set_period)(struct udevice *dev, int period_ms);
> +#endif
>  };
>
>  #define led_get_ops(dev)       ((struct led_ops *)(dev)->driver->ops)
> @@ -72,4 +98,13 @@ int led_set_state(struct udevice *dev, enum led_state_t
> state);
>   */
>  enum led_state_t led_get_state(struct udevice *dev);
>
> +/**
> + * led_set_period() - set the blink period of an LED
> + *
> + * @dev:       LED device to change
> + * @period_ms: LED blink period in milliseconds
> + * @return 0 if OK, -ve on error
> + */
> +int led_set_period(struct udevice *dev, int period_ms);
> +
>  #endif
> diff --git a/test/dm/led.c b/test/dm/led.c
> index 2cc24127e2..fde700be38 100644
> --- a/test/dm/led.c
> +++ b/test/dm/led.c
> @@ -98,3 +98,27 @@ static int dm_test_led_label(struct unit_test_state
> *uts)
>         return 0;
>  }
>  DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
> +
> +/* Test LED blinking */
> +#ifdef CONFIG_LED_BLINK
> +static int dm_test_led_blink(struct unit_test_state *uts)
> +{
> +       const int offset = 1;
> +       struct udevice *dev, *gpio;
> +
> +       /*
> +        * Check that we get an error when trying to blink an LED, since
> it is
> +        * not supported by the GPIO LED driver.
> +        */
> +       ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
> +       ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
> +       ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
> +       ut_asserteq(-ENOSYS, led_set_state(dev, LEDST_BLINK));
> +       ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
> +       ut_asserteq(LEDST_OFF, led_get_state(dev));
> +       ut_asserteq(-ENOSYS, led_set_period(dev, 100));
> +
> +       return 0;
> +}
> +DM_TEST(dm_test_led_blink, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
> +#endif
> --
> 2.12.2.715.g7642488e1d-goog
>
>
Reviewed-by: Ziping Chen <techping.chan@gmail.com>
Simon Glass April 15, 2017, 4:08 p.m. UTC | #2
On 12 April 2017 at 02:52, Ziping Chen <techping.chan@gmail.com> wrote:
>
>
> 2017-04-11 1:34 GMT+08:00 Simon Glass <sjg@chromium.org>:
>>
>> Allow LEDs to be blinked if the driver supports it. Enable this for
>> sandbox so that the tests run.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Control this feature via a new CONFIG_LED_BLINK option
>>
>>  configs/sandbox_defconfig       |  1 +
>>  configs/sandbox_noblk_defconfig |  1 +
>>  configs/sandbox_spl_defconfig   |  1 +
>>  drivers/led/Kconfig             |  9 +++++++++
>>  drivers/led/led-uclass.c        | 12 ++++++++++++
>>  include/led.h                   | 35 +++++++++++++++++++++++++++++++++++
>>  test/dm/led.c                   | 24 ++++++++++++++++++++++++
>>  7 files changed, 83 insertions(+)
>>
>
> Reviewed-by: Ziping Chen <techping.chan@gmail.com>
>

Applied to u-boot-dm
diff mbox

Patch

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7f3f5ac809..9814ea3b81 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -83,6 +83,7 @@  CONFIG_I2C_ARB_GPIO_CHALLENGE=y
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_DM_MAILBOX=y
 CONFIG_SANDBOX_MBOX=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 3f8e70d523..bba744332c 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -92,6 +92,7 @@  CONFIG_I2C_ARB_GPIO_CHALLENGE=y
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index ade67143b1..6fe21254fd 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -94,6 +94,7 @@  CONFIG_I2C_ARB_GPIO_CHALLENGE=y
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
 CONFIG_LED=y
+CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
 CONFIG_DM_MAILBOX=y
 CONFIG_SANDBOX_MBOX=y
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 0ef45bc06a..309372ab56 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
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index ea5fbabadf..78ab76050d 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -52,6 +52,18 @@  enum led_state_t led_get_state(struct udevice *dev)
 	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",
diff --git a/include/led.h b/include/led.h
index 8c107e28e7..c67af22591 100644
--- a/include/led.h
+++ b/include/led.h
@@ -17,10 +17,22 @@  struct led_uc_plat {
 	const char *label;
 };
 
+/**
+ * struct led_uc_priv - Private data the uclass stores about each device
+ *
+ * @period_ms:	Flash period in milliseconds
+ */
+struct led_uc_priv {
+	int period_ms;
+};
+
 enum led_state_t {
 	LEDST_OFF = 0,
 	LEDST_ON = 1,
 	LEDST_TOGGLE,
+#ifdef CONFIG_LED_BLINK
+	LEDST_BLINK,
+#endif
 
 	LEDST_COUNT,
 };
@@ -42,6 +54,20 @@  struct led_ops {
 	 * @return LED state led_state_t, or -ve on error
 	 */
 	enum led_state_t (*get_state)(struct udevice *dev);
+
+#ifdef CONFIG_LED_BLINK
+	/**
+	 * led_set_period() - set the blink period of an LED
+	 *
+	 * Thie records the period if supported, or returns -ENOSYS if not.
+	 * To start the LED blinking, use set_state().
+	 *
+	 * @dev:	LED device to change
+	 * @period_ms:	LED blink period in milliseconds
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*set_period)(struct udevice *dev, int period_ms);
+#endif
 };
 
 #define led_get_ops(dev)	((struct led_ops *)(dev)->driver->ops)
@@ -72,4 +98,13 @@  int led_set_state(struct udevice *dev, enum led_state_t state);
  */
 enum led_state_t led_get_state(struct udevice *dev);
 
+/**
+ * led_set_period() - set the blink period of an LED
+ *
+ * @dev:	LED device to change
+ * @period_ms:	LED blink period in milliseconds
+ * @return 0 if OK, -ve on error
+ */
+int led_set_period(struct udevice *dev, int period_ms);
+
 #endif
diff --git a/test/dm/led.c b/test/dm/led.c
index 2cc24127e2..fde700be38 100644
--- a/test/dm/led.c
+++ b/test/dm/led.c
@@ -98,3 +98,27 @@  static int dm_test_led_label(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test LED blinking */
+#ifdef CONFIG_LED_BLINK
+static int dm_test_led_blink(struct unit_test_state *uts)
+{
+	const int offset = 1;
+	struct udevice *dev, *gpio;
+
+	/*
+	 * Check that we get an error when trying to blink an LED, since it is
+	 * not supported by the GPIO LED driver.
+	 */
+	ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+	ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(-ENOSYS, led_set_state(dev, LEDST_BLINK));
+	ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+	ut_asserteq(LEDST_OFF, led_get_state(dev));
+	ut_asserteq(-ENOSYS, led_set_period(dev, 100));
+
+	return 0;
+}
+DM_TEST(dm_test_led_blink, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+#endif