Message ID | 20170410173459.30461-8-sjg@chromium.org |
---|---|
State | Accepted |
Commit | 53378dac8dc33e3fd5f07d60bd7a5f8258ac7a20 |
Delegated to: | Simon Glass |
Headers | show |
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>
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 --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
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(+)