Skip to content

Add support for multi-color LEDs #92473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

simonguinot
Copy link
Contributor

@simonguinot simonguinot commented Jul 1, 2025

This PR adds support for multi-color LEDs built with several monochromatic LED.

It imports the leds-group-multicolor DT binding from Linux and introduces the leds-group-multicolor driver.

Here is an example of DT fragment that defines an RGB LED with a group of monochromatic PWM LEDs:

/ { 
        monochromatic-leds { 
                compatible = "pwm-leds";

                red_pwm_led: led-0 { 
                        pwms = <&pwm1 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
                };

                green_pwm_led: led-1 { 
                        pwms = <&pwm2 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
                };

                blue_pwm_led: led-2 { 
                        pwms = <&pwm3 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
                };
        };

        multi-led { 
                compatible = "leds-group-multicolor";

                leds = <&red_pwm_led>, <&green_pwm_led>, <&blue_pwm_led>;
                label = "RGB LED";
                color-mapping = <LED_COLOR_ID_RED>,
                                <LED_COLOR_ID_GREEN>,
                                <LED_COLOR_ID_BLUE>;
        };
};

The leds-group-multicolor driver implements the ->set_color() API method. Instead of calling led_set_brightness() for each monochromatic LED, led_set_color() can be called on the leds-group-multicolor compatible device to configure all the LEDs at once.

Note that the color-mapping DT property, shown in the above example, is not mandatory.

@simonguinot
Copy link
Contributor Author

Implements #51858

@simonguinot simonguinot requested review from soburi, thedjnK, gmarull, fabiobaltieri and kartben and removed request for kartben July 1, 2025 16:40
@henrikbrixandersen henrikbrixandersen self-requested a review July 1, 2025 17:41
@simonguinot simonguinot force-pushed the leds-group-multicolor branch from 8afa941 to f4c85e3 Compare July 1, 2025 19:01
Copy link
Contributor

@bjarki-andreasen bjarki-andreasen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like the addition, some comments but overall really nice

@simonguinot
Copy link
Contributor Author

Really like the addition, some comments but overall really nice

Thank you very much for your fast feedback. I really appreciate it. Hopefully this will initiate more reviews.

But to be honest, I don't think this composite driver is nice. IMO it is not the right approach to bring support for multi-color LEDs in Zephyr. It would be more optimized to support them directly in GPIO and PWM drivers (#69227). But unfortunately this kind of hits the sacred rule of Linux compatibility. And we really need to move forward on this multi-color LED topic...

@gmarull
Copy link
Member

gmarull commented Jul 2, 2025

Really like the addition, some comments but overall really nice

Thank you very much for your fast feedback. I really appreciate it. Hopefully this will initiate more reviews.

But to be honest, I don't think this composite driver is nice. IMO it is not the right approach to bring support for multi-color LEDs in Zephyr. It would be more optimized to support them directly in GPIO and PWM drivers (#69227). But unfortunately this kind of hits the sacred rule of Linux compatibility. And we really need to move forward on this multi-color LED topic...

I think this is often a confusion about DT/Zephyr. DT describes hardware, and while it suggests a certain implementation pattern, you can technically do whatever you want as you have the full connections in DT (e.g. get PWM instances instead of LED instance). It may lead to some macro crimes, but I guess it should be doable if memory usage is a concern.

@simonguinot
Copy link
Contributor Author

Really like the addition, some comments but overall really nice

Thank you very much for your fast feedback. I really appreciate it. Hopefully this will initiate more reviews.
But to be honest, I don't think this composite driver is nice. IMO it is not the right approach to bring support for multi-color LEDs in Zephyr. It would be more optimized to support them directly in GPIO and PWM drivers (#69227). But unfortunately this kind of hits the sacred rule of Linux compatibility. And we really need to move forward on this multi-color LED topic...

I think this is often a confusion about DT/Zephyr. DT describes hardware, and while it suggests a certain implementation pattern, you can technically do whatever you want as you have the full connections in DT (e.g. get PWM instances instead of LED instance). It may lead to some macro crimes, but I guess it should be doable if memory usage is a concern.

For Linux, a LED is a channel. The LED DT descriptions and drivers in Linux are following this statement. When the need came to support multi-channel LEDs (because these devices actually exist), then composite devices and drivers were introduced. It was the only option without breaking everything. That's why in Linux multi-color LEDs are described in DT with composite devices. But a LED device can have several channels, and a correct hardware description should reflect that without using composite devices. So the Linux LED bindings are not good. And by rule we sacredly copy them.

About the leds-group-multicolor DT binding, the implementation is more constrained than suggested. It intends to support any kind of underlying LED devices (PWM, GPIO; dedicated controller, strip, mixed), and not just PWM. So having a driver duplicating code, using insane macros or other contortions, all to match an unneeded pseudo device representation is not a good idea.

That being said I think that this leds-group-multicolor driver does actually make sense for some specific use cases, such as RGB LED built with mixed LEDs of different controllers for example. So it is nice to have it anyway.

But when it comes to RGB LEDs built from GPIO or PWM lines, then it should use a different DT description, and it should be supported directly by the led-pwm and led-gpio drivers, because the code is already there. And for the GPIO part, it is implemented by #69227.

For all LED drivers, the underlying subsystem is automatically selected
in Kconfig if their compatible node is found in DT.

The only exception is the PWM LED driver which depends on PWM instead
of selecting it. The PWM Kconfig option must be explicitely selected in
order to have LED_PWM enabled.

This patch updates the Kconfig of the PWM LED driver to have the same
behavior as other LED drivers: PWM is now automatically selected if a
"pwm-leds" compatible node is found in DT.

Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
This patch moves the label and color-mapping LED property definitions
from led-controller.yaml into led-node.yaml.

This allows to use these properties from a LED node which is not a
child node of a LED controller. This is preparatory work for adding
the leds-group-multicolor binding.

In addition this patch also removes the redundant "label" property
definitions in gpio-leds.yaml and pwm-leds.yaml. It is now included
from led-node.yaml.

Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
@simonguinot simonguinot force-pushed the leds-group-multicolor branch from f4c85e3 to 80b1bea Compare July 9, 2025 14:19
@jeppenodgaard jeppenodgaard linked an issue Jul 10, 2025 that may be closed by this pull request
# Common fields for LED nodes

properties:
label:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks redundant :-o

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean redundant with the node name ?

There is a discussion here: LED.#92473 (comment). Feel free to join.

The leds-group-multicolor binding allows to combines several
monochromatic LEDs into one multi-color LED.

Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
@simonguinot simonguinot force-pushed the leds-group-multicolor branch from 80b1bea to 7e45db7 Compare July 10, 2025 13:52
fabiobaltieri
fabiobaltieri previously approved these changes Jul 10, 2025
@simonguinot simonguinot force-pushed the leds-group-multicolor branch from 7e45db7 to 34bf3cf Compare July 10, 2025 18:51
This driver supports multi-color LEDs built with several monochromatic
LEDs. ->set_color is the only LED driver API method implemented.

Instead of calling led_set_brightness() for each monochromatic LED,
led_set_color() can be called on the leds-group-multicolor device to
set all colors at once.

See the leds-group-multicolor DT binding for details.

Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
Add test for leds-group-multicolor driver.

Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
@kartben kartben requested a review from Copilot July 10, 2025 18:59
fabiobaltieri
fabiobaltieri previously approved these changes Jul 10, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for multi-color LEDs by importing a new DT binding and introducing a corresponding driver that wraps multiple monochromatic LEDs into one multi-color interface.

  • Import and refactor existing LED bindings to share common led-node.yaml fields.
  • Add leds-group-multicolor DT binding, Kconfig, CMake integration, and driver implementation.
  • Update test and sample configurations to include multi-color and PWM setups.

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/drivers/build_all/led/prj.conf Remove CONFIG_PWM from build-all tests
tests/drivers/build_all/led/app.overlay Add multi-led overlay node for multi-color
samples/drivers/led/pwm/prj.conf Remove CONFIG_PWM from PWM sample
dts/bindings/led/pwm-leds.yaml Include led-node.yaml for child label
dts/bindings/led/leds-group-multicolor.yaml New DT binding for multi-color LED grouping
dts/bindings/led/led-node.yaml New common LED node binding (label/color-mapping)
dts/bindings/led/led-controller.yaml Include led-node.yaml, remove duplicate props
dts/bindings/led/gpio-leds.yaml Include led-node.yaml for GPIO LEDs
drivers/led/leds_group_multicolor.c Multi-color LED driver implementation
drivers/led/Kconfig.pwm Adjust PWM LED driver dependencies
drivers/led/Kconfig.leds-group-multicolor New Kconfig for multi-color LED driver
drivers/led/Kconfig Register multi-color Kconfig file
drivers/led/CMakeLists.txt Add multi-color driver to build
Comments suppressed due to low confidence (3)

samples/drivers/led/pwm/prj.conf:3

  • Removing CONFIG_PWM from the PWM sample prj.conf disables the PWM LED driver and will break the sample build. Please restore CONFIG_PWM or update the sample dependencies accordingly.
CONFIG_LED=y

drivers/led/leds_group_multicolor.c:23

  • [nitpick] The field name led suggests a single LED but holds an array of LED specs; consider renaming it to leds for clarity.
	const struct led_dt_spec *led;

@@ -4,6 +4,7 @@
config LED_PWM
bool "PWM LED driver"
default y
depends on PWM && DT_HAS_PWM_LEDS_ENABLED
depends on DT_HAS_PWM_LEDS_ENABLED
select PWM
Copy link
Preview

Copilot AI Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using select PWM is discouraged because it implicitly enables PWM and can lead to conflicting configurations. Prefer depends on PWM to correctly express the dependency.

Suggested change
select PWM
depends on PWM

Copilot uses AI. Check for mistakes.

config LEDS_GROUP_MULTICOLOR
bool "LEDs group multi-color driver"
default y
depends on DT_HAS_LEDS_GROUP_MULTICOLOR_ENABLED
Copy link
Preview

Copilot AI Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multi-color LED driver relies on the underlying PWM LED driver (LED_PWM). Add depends on LED_PWM to the Kconfig so that the necessary driver is enabled when multi-color support is selected.

Suggested change
depends on DT_HAS_LEDS_GROUP_MULTICOLOR_ENABLED
depends on DT_HAS_LEDS_GROUP_MULTICOLOR_ENABLED && LED_PWM

Copilot uses AI. Check for mistakes.

@@ -22,10 +28,3 @@ child-binding:
brigtness granularity) and lesser than 50 milliseconds (average visual
Copy link
Preview

Copilot AI Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in brigtness; it should be spelled brightness.

Suggested change
brigtness granularity) and lesser than 50 milliseconds (average visual
brightness granularity) and lesser than 50 milliseconds (average visual

Copilot uses AI. Check for mistakes.

Copy link

@danieldegrasse danieldegrasse added this to the v4.3.0 milestone Jul 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Devicetree area: LED Label to identify LED subsystem area: Samples Samples
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LED driver for RGB leds + device tree support
8 participants