Skip to content

Commit

Permalink
drivers: led_strip: Add support for white channels in API
Browse files Browse the repository at this point in the history
This commit implements support for RGBW LED strips. struct led_rgb
currently supports a scratch uint8 for alignment/size reasons. This same
space can also fit a white channel as used by some LEDs like the SK6812.
To accomplish this a new config, CONFIG_LED_STRIP_WHITE_CHANNEL is added
which replaces the .scratch parameter with a .w parameter that API users
can set. The existing CONFIG_LED_STRIP_RGB_SCRATCH option is kept and
mutually exclusive with this new parameter to distinguish LED strips like
the APA102 that need the alignment, but don't support a white channel in
hardware.

Signed-off-by: J M <[email protected]>
  • Loading branch information
J-Montgomery committed Jun 11, 2023
1 parent d14519c commit 49dde20
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 5 deletions.
6 changes: 6 additions & 0 deletions drivers/led_strip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ config LED_STRIP_INIT_PRIORITY
config LED_STRIP_RGB_SCRATCH
bool

config LED_STRIP_WHITE_CHANNEL
bool "LED strip white channel"
depends on !LED_STRIP_RGB_SCRATCH
help
Enables support for a white channel in addition to RGB

source "drivers/led_strip/Kconfig.lpd880x"

source "drivers/led_strip/Kconfig.ws2812"
Expand Down
8 changes: 7 additions & 1 deletion drivers/led_strip/Kconfig.ws2812
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

menuconfig WS2812_STRIP
bool "WS2812 (and compatible) LED strip driver"
select LED_STRIP_RGB_SCRATCH
select WS2812_STRIP_WHITE_CHANNEL
help
Enable LED strip driver for daisy chains of WS2812-ish (or WS2812B,
WS2813, SK6812, Everlight B1414, or compatible) devices.
Expand Down Expand Up @@ -47,3 +47,9 @@ config WS2812_STRIP_GPIO
controller.

endchoice

config WS2812_STRIP_WHITE_CHANNEL
bool "White channel"
select LED_STRIP_WHITE_CHANNEL
help
Enables support for white channels in the led_strip API.
5 changes: 4 additions & 1 deletion drivers/led_strip/ws2812_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,12 @@ static int ws2812_gpio_update_rgb(const struct device *dev,

for (j = 0; j < config->num_colors; j++) {
switch (config->color_mapping[j]) {
/* White channel is not supported by LED strip API. */
case LED_COLOR_ID_WHITE:
#ifdef CONFIG_LED_STRIP_WHITE_CHANNEL
*ptr++ = pixels[i].w;
#else
*ptr++ = 0;
#endif
break;
case LED_COLOR_ID_RED:
*ptr++ = pixels[i].r;
Expand Down
5 changes: 4 additions & 1 deletion drivers/led_strip/ws2812_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ static int ws2812_strip_update_rgb(const struct device *dev, struct led_rgb *pix
uint8_t pixel;

switch (cfg->color_mapping[j]) {
/* White channel is not supported by LED strip API. */
case LED_COLOR_ID_WHITE:
#ifdef CONFIG_LED_STRIP_WHITE_CHANNEL
pixel = pixels[i].w;
#else
pixel = 0;
#endif
break;
case LED_COLOR_ID_RED:
pixel = pixels[i].r;
Expand Down
5 changes: 4 additions & 1 deletion drivers/led_strip/ws2812_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,12 @@ static int ws2812_strip_update_rgb(const struct device *dev,
uint8_t pixel;

switch (cfg->color_mapping[j]) {
/* White channel is not supported by LED strip API. */
case LED_COLOR_ID_WHITE:
#ifdef CONFIG_LED_STRIP_WHITE_CHANNEL
pixel = pixels[i].w;
#else
pixel = 0;
#endif
break;
case LED_COLOR_ID_RED:
pixel = pixels[i].r;
Expand Down
6 changes: 5 additions & 1 deletion include/zephyr/drivers/led_strip.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@

#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/sys/__assert.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Color value for a single RGB LED.
* @brief Color value for a single RGB(W) LED.
*
* Individual strip drivers may ignore lower-order bits if their
* resolution in any channel is less than a full byte.
Expand All @@ -42,6 +43,9 @@ struct led_rgb {
* ignore.
*/
uint8_t scratch;
#else defined(CONFIG_LED_STRIP_WHITE_CHANNEL)
/** White channel */
uint8_t w;
#endif
/** Red channel */
uint8_t r;
Expand Down

0 comments on commit 49dde20

Please sign in to comment.