* [PATCH v3 0/4] leds: Add a virtual LED driver for groups of
@ 2025-10-19 9:23 Jonathan Brophy
2025-10-19 9:23 ` [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation Jonathan Brophy
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Jonathan Brophy @ 2025-10-19 9:23 UTC (permalink / raw)
To: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov
Cc: devicetree, linux-kernel, linux-leds
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 4262 bytes --]
From: Jonathan Brophy <professor_jonny@hotmail.com>
Introduce a new driver that implements virtual LED groups,
aggregating multiple monochromatic LEDs into virtual groups and providing
priority-based control for concurrent state management.
Existing multi-LED drivers are primarily intended to group monochrome LEDs
into multicolor LEDs, allowing per-channel intensity control of hue and
brightness. However, they are not designed to manage grouped LEDs with
independent functional roles or shared behavior.
The leds-group-virtualcolor driver allows arbitrary LEDs to be grouped
and exposed as a single logical LED representing a fixed color, status, or
function. Properties such as triggers and brightness are applied to the group
as a whole, rather than to individual LED elements.
This is particularly useful in consumer devices (e.g., routers), where a
single status LED must reflect multiple device states via color or blink
patterns. In such cases, simple device tree bindings are insufficient,
as multiple triggers may activate simultaneously, resulting in color mixing
and ambiguous status indication.
To avoid this problem, the driver implements a priority mechanism that allows
higher-priority LEDs to assume control of the group. When multiple LEDs of the
same priority are active concurrently, the most recently activated LED takes
precedence over earlier ones. If a higher-priority LED is extinguished, a lower-
priority LED will become active.
If an LED is set to blink, or is controlled with an on or off delay, any time
the LED is inactive but still triggered, it will be the only LED in control and
will be extinguished during this time for best contrast.
leds-group-virtualcolor can also enable decomposition of multi-element multicolor
LEDs into individual virtual groups that can provide individual virtual color
LEDs, supporting flexible trigger assignments and precise status representation.
leds-group-virtualcolor can join PWM LEDs into the group with their own bindings
for each primary color this enables per channel dimming and fine tuning of color
of the grouped PWM LEDs.
PWM and monochromatic LEDs can be joined into the same groups sharing the same
grouped global brightness controls.
leds-group-virtualcolor can also expose a singular LED as multiple virtual LEDs,
each having individual triggers, timings, or other properties.
Additionally, traditional bindings can only control individual LED elements,
making it impossible to represent composite colors formed by combinations
of primary RGB components but this is also made possible.
Originally intended to be used with OpenWrt for controlling RGB status LEDs
so control of power, reboot and system upgrade cam mimic the manufactures status
LED mixed colors.
Often when a device ported to OpenWrt RGB status LEDs usually became a glorified
power-led instead of a status led because user scripts or binaries would have to
be implemented as additional packages to control logic.
leds-group-virtualcolor is designed to allow LED behavior to be
fully described and logically controlled in the device tree, enabling early
status indication during system initialization—without relying on user-space
scripts or custom binaries.
Jonathan Brophy (4):
dt: bindings: Add virtualcolor class dt bindings
dt-bindings: leds: Add virtualcolor group dt bindings documentation.
ABI: Add sysfs documentation for leds-group-virtualcolor
Subject: [PATCH v3 4/4] leds: Add virtualcolor LED group driver
.../ABI/testing/sysfs-class-leds-virtualcolor | 89 +++
.../leds/leds-class-virtualcolor.yaml | 90 +++
.../leds/leds-group-virtualcolor.yaml | 110 ++++
drivers/leds/rgb/Kconfig | 17 +
drivers/leds/rgb/Makefile | 1 +
drivers/leds/rgb/leds-group-virtualcolor.c | 513 ++++++++++++++++++
include/dt-bindings/leds/common.h | 4 +
7 files changed, 824 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-class-leds-virtualcolor
create mode 100644 Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml
create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml
create mode 100644 drivers/leds/rgb/leds-group-virtualcolor.c
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation. 2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy @ 2025-10-19 9:23 ` Jonathan Brophy 2025-10-19 10:39 ` Krzysztof Kozlowski 2025-10-19 9:23 ` [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group " Jonathan Brophy ` (3 subsequent siblings) 4 siblings, 1 reply; 18+ messages in thread From: Jonathan Brophy @ 2025-10-19 9:23 UTC (permalink / raw) To: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds From: Jonathan Brophy <professor_jonny@hotmail.com> Add DT bindings for the LEDs virtualcolor class framework. Add LED-FUNCTION-VIRTUAL-STATUS ID to the FUNCTION ID list for device tree bindings. co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> --- .../leds/leds-class-virtualcolor.yaml | 90 +++++++++++++++++++ include/dt-bindings/leds/common.h | 4 + 2 files changed, 94 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml diff --git a/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml new file mode 100644 index 000000000000..8cbbbf0d746c --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/leds-class-virtualcolor.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: virtualcolor LED class + +maintainers: + - Radoslav Tsvetkov <rtsvetkov@gradotech.eu> + +description: | + Validates individual virtual LED nodes that aggregate multiple monochromatic + or PWM LEDs. + +properties: + $nodename: + pattern: "^virtual-led(@[0-9a-f])?$" + + reg: + maxItems: 1 + description: Virtual LED index/number + + function: + description: | + LED function. It is recommended to use LED_FUNCTION_VIRTUAL_STATUS + for virtual LEDs to distinguish them from physical LEDs. + See: include/dt-bindings/leds/common.h + + color: + description: | + LED color identifier from the LED_COLOR_ID_* namespace. + See: include/dt-bindings/leds/common.h + + leds: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 15 + description: | + Array of phandles to monochromatic LEDs that compose this virtual LED. + + pwm-leds-red: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 15 + description: | + Array of phandles to PWM-controlled red LEDs that compose this virtual + LED. + + pwm-leds-green: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 15 + description: | + Array of phandles to PWM-controlled green LEDs that compose this virtual + LED. + + pwm-leds-blue: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 15 + description: | + Array of phandles to PWM-controlled blue LEDs that compose this virtual + LED. + + priority: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + description: | + Priority level for this virtual LED. Higher values take precedence + when multiple virtual LEDs are active simultaneously. + +required: + - reg + +anyOf: + - required: + - leds + - required: + - pwm-leds-red + - required: + - pwm-leds-green + - required: + - pwm-leds-blue + +allOf: + - $ref: common.yaml# + +additionalProperties: true +... diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h index 4f017bea0123..39c34d585a47 100644 --- a/include/dt-bindings/leds/common.h +++ b/include/dt-bindings/leds/common.h @@ -63,6 +63,10 @@ "lp5523:{r,g,b}" (Nokia N900) */ #define LED_FUNCTION_STATUS "status" +/* Virtual system LEDs Used for virtual LED groups, multifunction RGB + indicators or status LEDs that reflect complex system states */ +#define LED_FUNCTION_VIRTUAL_STATUS "virtual-status" + #define LED_FUNCTION_MICMUTE "micmute" #define LED_FUNCTION_MUTE "mute" -- 2.43.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation. 2025-10-19 9:23 ` [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation Jonathan Brophy @ 2025-10-19 10:39 ` Krzysztof Kozlowski 0 siblings, 0 replies; 18+ messages in thread From: Krzysztof Kozlowski @ 2025-10-19 10:39 UTC (permalink / raw) To: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds On 19/10/2025 11:23, Jonathan Brophy wrote: > From: Jonathan Brophy <professor_jonny@hotmail.com> > > Add DT bindings for the LEDs virtualcolor class framework. Add Why? What part of hardware or real system use case is being solved here? > LED-FUNCTION-VIRTUAL-STATUS ID to the FUNCTION ID list for device tree > bindings. > > co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> That's not a proper tag. See submitting patches. Please use subject prefixes matching the subsystem. You can get them for example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory your patch is touching. For bindings, the preferred subjects are explained here: https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters I don't understand what is happening with your patchset. It is being changed in unexpected way, like something previously correct - like subject - now is changed for some unexplained reason. > Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> > --- > .../leds/leds-class-virtualcolor.yaml | 90 +++++++++++++++++++ > include/dt-bindings/leds/common.h | 4 + > 2 files changed, 94 insertions(+) > create mode 100644 Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml > > diff --git a/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml > new file mode 100644 > index 000000000000..8cbbbf0d746c > --- /dev/null > +++ b/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml > @@ -0,0 +1,90 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/leds/leds-class-virtualcolor.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: virtualcolor LED class I don't understand what is "virtualcolor" > + > +maintainers: > + - Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > + > +description: | Do not need '|' unless you need to preserve formatting. > + Validates individual virtual LED nodes that aggregate multiple monochromatic This sentence makes no sense. You describe here hardware in full sentence. How hardware can "validates"? Best regards, Krzysztof ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group dt bindings documentation. 2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy 2025-10-19 9:23 ` [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation Jonathan Brophy @ 2025-10-19 9:23 ` Jonathan Brophy 2025-10-19 10:43 ` Krzysztof Kozlowski 2025-10-20 11:35 ` Rob Herring (Arm) 2025-10-19 9:23 ` [PATCH v3 3/4] ABI: Add sysfs documentation for leds-group-virtualcolor Jonathan Brophy ` (2 subsequent siblings) 4 siblings, 2 replies; 18+ messages in thread From: Jonathan Brophy @ 2025-10-19 9:23 UTC (permalink / raw) To: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds From: Jonathan Brophy <professor_jonny@hotmail.com> Add device tree binding documentation for the virtual LED group driver that implements virtual LED groups by aggregating multiple monochromatic LEDs Bindings for the virtual driver are not describing hardware LEDs they describe virtual devices made from groups of hardware LEDs created from an array of LED phandles. Normally the device tree is used to describe hardware not virtual hardware but it is particularly useful in situations where you require an LED to be a specific color by mixing primary colors, such as multi element multi color LEDs to be operated from a device tree binding. It also becomes useful with multiple LEDs operating the same indicator such as ring of light indicators where the LEDs are driven From different GPIO outputs unifying the control that can give basic indication during system startup, shutdown upgrade etc... co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> --- .../leds/leds-group-virtualcolor.yaml | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml diff --git a/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml b/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml new file mode 100644 index 000000000000..f638bdd4d65e --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/leds-group-virtualcolor.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# +title: virtualcolor LED group driver +maintainers: + - Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +description: | + Implements virtual LED groups by aggregating multiple monochromatic LEDs. + Provides priority-based control for managing concurrent LED activation requests, + ensuring only the highest-priority LED state is active at any given time. +properties: + compatible: + const: leds-group-virtualcolor + '#address-cells': + const: 1 + '#size-cells': + const: 0 +patternProperties: + "^virtual": + $ref: leds-class-virtualcolor.yaml# +required: + - compatible +additionalProperties: false +examples: + - | + #include <dt-bindings/leds/common.h> + #include <dt-bindings/gpio/gpio.h> + + led-controller { + compatible = "gpio-leds"; + led_red: led_red { + gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led_green: led_green { + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led_blue: led_blue { + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + pwm-led-controller { + compatible = "pwm-leds"; + + led_1: led-1 { + color = <LED_COLOR_ID_RED>; + pwms = <&twl_pwm 0 7812500>; + }; + + led_2: led-2 { + color = <LED_COLOR_ID_GREEN>; + pwms = <&twl_pwmled 0 7812500>; + }; + + led_3: led-3 { + color = <LED_COLOR_ID_RED>; + pwms = <&twl_pwm 0 7812500>; + }; + + led_4: led-4 { + color = <LED_COLOR_ID_GREEN>; + pwms = <&twl_pwmled 0 7812500>; + }; + + }; + + virtual-led-controller { + compatible = "leds-group-virtualcolor"; + #address-cells = <1>; + #size-cells = <0>; + + virtual_red@0 { + reg = <0>; + function = LED_FUNCTION_VIRTUAL_STATUS; + color = <LED_COLOR_ID_RED>; + leds = <&led_red>; + priority = <2>; + }; + + virtual_yellow_mix@1 { + reg = <1>; + function = LED_FUNCTION_VIRTUAL_STATUS; + color = <LED_COLOR_ID_YELLOW>; + leds = <&led_green &led_red>; + pwm-leds-red = <&led_1 &led_2>; + pwm-leds-green = <&led_1 &led_3>; + priority = <1>; + }; + + virtual_white@2 { + reg = <2>; + function = LED_FUNCTION_VIRTUAL_STATUS; + color = <LED_COLOR_ID_WHITE>; + leds = <&led_red &led_green &led_blue>; + priority = <15>; + }; + + virtual_pwm_red@3 { + reg = <3>; + function = LED_FUNCTION_VIRTUAL_STATUS; + color = <LED_COLOR_ID_RED>; + pwm-leds-red = <&led_1 &led_3>; + priority = <1>; + }; + }; -- 2.43.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group dt bindings documentation. 2025-10-19 9:23 ` [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group " Jonathan Brophy @ 2025-10-19 10:43 ` Krzysztof Kozlowski 2025-10-20 11:35 ` Rob Herring (Arm) 1 sibling, 0 replies; 18+ messages in thread From: Krzysztof Kozlowski @ 2025-10-19 10:43 UTC (permalink / raw) To: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds On 19/10/2025 11:23, Jonathan Brophy wrote: > From: Jonathan Brophy <professor_jonny@hotmail.com> > > Add device tree binding documentation for the virtual LED group driver > that implements virtual LED groups by aggregating multiple monochromatic > LEDs > > Bindings for the virtual driver are not describing hardware LEDs they > describe virtual devices made from groups of hardware LEDs created from an array > of LED phandles. Don't describe DT syntax, but hardware. Phandles are not important here. How the board, system looks like? What are you achieving here? > > Normally the device tree is used to describe hardware not virtual hardware > but it is particularly useful in situations where you require an LED to be a > specific color by mixing primary colors, such as multi element multi color LEDs > to be operated from a device tree binding. Please describe the hardware and usecase, and then say how existing bindings cannot cover it so binding solves that use case. Write concise, yet informative statements. We all now how DT works, this you do not have to explain to us. But we need to know WHY we want this code. > > It also becomes useful with multiple LEDs operating the same indicator such as > ring of light indicators where the LEDs are driven From different GPIO outputs > unifying the control that can give basic indication during system startup, > shutdown upgrade etc... > > co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> > --- > .../leds/leds-group-virtualcolor.yaml | 110 ++++++++++++++++++ > 1 file changed, 110 insertions(+) > create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml > > diff --git a/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml b/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml > new file mode 100644 > index 000000000000..f638bdd4d65e > --- /dev/null > +++ b/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml > @@ -0,0 +1,110 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/leds/leds-group-virtualcolor.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > +title: virtualcolor LED group driver > +maintainers: > + - Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > +description: | > + Implements virtual LED groups by aggregating multiple monochromatic LEDs. > + Provides priority-based control for managing concurrent LED activation requests, > + ensuring only the highest-priority LED state is active at any given time. > +properties: > + compatible: > + const: leds-group-virtualcolor > + '#address-cells': > + const: 1 > + '#size-cells': > + const: 0 > +patternProperties: > + "^virtual": > + $ref: leds-class-virtualcolor.yaml# > +required: > + - compatible > +additionalProperties: false > +examples: > + - | Totally corrupted patch. I don't understand the changes. Please start from scratch from latest reviewed binding or example schema. > + #include <dt-bindings/leds/common.h> > + #include <dt-bindings/gpio/gpio.h> > + > + led-controller { > + compatible = "gpio-leds"; > + led_red: led_red { > + gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; > + default-state = "off"; > + }; > + led_green: led_green { > + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; > + default-state = "off"; > + }; > + led_blue: led_blue { > + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; > + default-state = "off"; > + }; > + }; > + > + pwm-led-controller { > + compatible = "pwm-leds"; > + > + led_1: led-1 { > + color = <LED_COLOR_ID_RED>; > + pwms = <&twl_pwm 0 7812500>; > + }; > + > + led_2: led-2 { > + color = <LED_COLOR_ID_GREEN>; > + pwms = <&twl_pwmled 0 7812500>; > + }; > + > + led_3: led-3 { > + color = <LED_COLOR_ID_RED>; > + pwms = <&twl_pwm 0 7812500>; > + }; > + > + led_4: led-4 { > + color = <LED_COLOR_ID_GREEN>; > + pwms = <&twl_pwmled 0 7812500>; > + }; > + > + }; > + > + virtual-led-controller { > + compatible = "leds-group-virtualcolor"; > + #address-cells = <1>; > + #size-cells = <0>; > + > + virtual_red@0 { Follow DTS coding style. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group dt bindings documentation. 2025-10-19 9:23 ` [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group " Jonathan Brophy 2025-10-19 10:43 ` Krzysztof Kozlowski @ 2025-10-20 11:35 ` Rob Herring (Arm) 2025-10-20 18:00 ` jonathan brophy 1 sibling, 1 reply; 18+ messages in thread From: Rob Herring (Arm) @ 2025-10-20 11:35 UTC (permalink / raw) To: Jonathan Brophy Cc: Jonathan Brophy, Pavel Machek, linux-leds, linux-kernel, Krzysztof Kozlowski, devicetree, Conor Dooley, Radoslav Tsvetkov, lee Jones On Sun, 19 Oct 2025 22:23:25 +1300, Jonathan Brophy wrote: > From: Jonathan Brophy <professor_jonny@hotmail.com> > > Add device tree binding documentation for the virtual LED group driver > that implements virtual LED groups by aggregating multiple monochromatic > LEDs > > Bindings for the virtual driver are not describing hardware LEDs they > describe virtual devices made from groups of hardware LEDs created from an array > of LED phandles. > > Normally the device tree is used to describe hardware not virtual hardware > but it is particularly useful in situations where you require an LED to be a > specific color by mixing primary colors, such as multi element multi color LEDs > to be operated from a device tree binding. > > It also becomes useful with multiple LEDs operating the same indicator such as > ring of light indicators where the LEDs are driven From different GPIO outputs > unifying the control that can give basic indication during system startup, > shutdown upgrade etc... > > co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> > --- > .../leds/leds-group-virtualcolor.yaml | 110 ++++++++++++++++++ > 1 file changed, 110 insertions(+) > create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml > My bot found errors running 'make dt_binding_check' on your patch: yamllint warnings/errors: dtschema/dtc warnings/errors: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led-controller (pwm-leds): led-1: 'max-brightness' is a required property from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led-controller (pwm-leds): led-2: 'max-brightness' is a required property from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led-controller (pwm-leds): led-3: 'max-brightness' is a required property from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led-controller (pwm-leds): led-4: 'max-brightness' is a required property from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# doc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20251019092331.49531-3-professorjonny98@gmail.com The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group dt bindings documentation. 2025-10-20 11:35 ` Rob Herring (Arm) @ 2025-10-20 18:00 ` jonathan brophy 0 siblings, 0 replies; 18+ messages in thread From: jonathan brophy @ 2025-10-20 18:00 UTC (permalink / raw) To: Rob Herring (Arm) Cc: Jonathan Brophy, Pavel Machek, linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org, Krzysztof Kozlowski, devicetree@vger.kernel.org, Conor Dooley, Radoslav Tsvetkov, lee Jones On Sun, 21 October 2025 12:35 AM, JRob Herring (Arm) wrote: > > >On Sun, 19 Oct 2025 22:23:25 +1300, Jonathan Brophy wrote:> > > From: Jonathan Brophy <professor_jonny@hotmail.com> > > > >> Add device tree binding documentation for the virtual LED group driver >> >> that implements virtual LED groups by aggregating multiple monochromatic >> >> LEDs >> >> > >> Bindings for the virtual driver are not describing hardware LEDs they > >> describe virtual devices made from groups of hardware LEDs created from an array > >> of LED phandles. > > > >> Normally the device tree is used to describe hardware not virtual hardware > >> but it is particularly useful in situations where you require an LED to be a > >> specific color by mixing primary colors, such as multi element multi color LEDs > >> to be operated from a device tree binding. > > >> It also becomes useful with multiple LEDs operating the same indicator such as > >> ring of light indicators where the LEDs are driven From different GPIO outputs > >> unifying the control that can give basic indication during system startup, > >> shutdown upgrade etc... > >> > >> co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > >> Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> > >> Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> > >> --- > >> .../leds/leds-group-virtualcolor.yaml | 110 ++++++++++++++++++ > >> 1 file changed, 110 insertions(+) > >> create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml > > >My bot found errors running 'make dt_binding_check' on your patch: > > > >yamllint warnings/errors: > > > >dtschema/dtc warnings/errors: > >/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led->controller (pwm-leds): led-1: 'max-brightness' is a required property > > from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# > >/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led->controller (pwm-leds): led-2: 'max-brightness' is a required property > > from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# > >/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led->controller (pwm-leds): led-3: 'max-brightness' is a required property > > from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# > >/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.example.dtb: pwm-led->controller (pwm-leds): led-4: 'max-brightness' is a required property > > from schema $id: http://devicetree.org/schemas/leds/leds-pwm.yaml# > sorry this was me checking my yaml's without validating the whole structure as those are covered by their own Yaml's In futurre I will validate the whole structure. ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 3/4] ABI: Add sysfs documentation for leds-group-virtualcolor 2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy 2025-10-19 9:23 ` [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation Jonathan Brophy 2025-10-19 9:23 ` [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group " Jonathan Brophy @ 2025-10-19 9:23 ` Jonathan Brophy 2025-10-19 9:23 ` [PATCH v3 4/4] leds: Add virtualcolor LED group driver Jonathan Brophy 2025-10-19 14:24 ` [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jacek Anaszewski 4 siblings, 0 replies; 18+ messages in thread From: Jonathan Brophy @ 2025-10-19 9:23 UTC (permalink / raw) To: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds From: Jonathan Brophy <professor_jonny@hotmail.com> Document the sysfs ABI for the Virtual Color LED Group Driver, including brightness control, priority levels, per-color PWM control, and monochromatic LED diagnostic attributes. Co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> --- .../ABI/testing/sysfs-class-leds-virtualcolor | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-leds-virtualcolor diff --git a/Documentation/ABI/testing/sysfs-class-leds-virtualcolor b/Documentation/ABI/testing/sysfs-class-leds-virtualcolor new file mode 100644 index 000000000000..f9b455ca34c8 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-leds-virtualcolor @@ -0,0 +1,89 @@ +What: /sys/class/leds/<led>/brightness +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Controls the overall brightness of the virtual LED. Setting to 0 + deactivates the virtual LED and restores the next highest-priority + active LED. Setting to 1-255 activates the virtual LED and applies + brightness to all grouped LEDs (monochromatic and RGB). + + Only the highest-priority active virtual LED is displayed at any + given time. + + Range: 0-255 (or configured max-brightness) + +What: /sys/class/leds/<led>/priority +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Sets the priority level for this virtual LED. Higher priority + values take precedence when multiple LEDs are active simultaneously. + + When a higher-priority LED is activated: + - The current active LED (if lower priority) is turned off + - The higher-priority LED's state is applied + - When the higher-priority LED is deactivated, the previous LED + is restored + + Default: 0 + Range: signed integer + +What: /sys/class/leds/<led>/red_brightness +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Sets brightness of all red PWM LEDs in the virtual group. Only + affects LEDs configured under "pwm-leds-red" in device tree. + + Range: 0-255 + +What: /sys/class/leds/<led>/green_brightness +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Sets brightness of all green PWM LEDs in the virtual group. Only + affects LEDs configured under "pwm-leds-green" in device tree. + + Range: 0-255 + +What: /sys/class/leds/<led>/blue_brightness +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Sets brightness of all blue PWM LEDs in the virtual group. Only + affects LEDs configured under "pwm-leds-blue" in device tree. + + Range: 0-255 + +What: /sys/class/leds/<led>/monochromatic_count +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Read-only. Shows the number of monochromatic LEDs in this virtual + LED group, as configured in device tree under the "leds" property. + +What: /sys/class/leds/<led>/monochromatic_leds +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Read-only. Shows a comma-separated list of monochromatic LED device + names that are part of this virtual group. Returns "none" if no + monochromatic LEDs are configured. + +What: /sys/class/leds/<led>/monochromatic_brightness +Date: October 2025 +KernelVersion: 6.13 +Contact: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> +Description: + Read-only. Shows the current brightness values of monochromatic LEDs + as a comma-separated list in the same order as monochromatic_leds. + Returns "none" if no monochromatic LEDs are configured. + + Example output: -- 2.43.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 4/4] leds: Add virtualcolor LED group driver 2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy ` (2 preceding siblings ...) 2025-10-19 9:23 ` [PATCH v3 3/4] ABI: Add sysfs documentation for leds-group-virtualcolor Jonathan Brophy @ 2025-10-19 9:23 ` Jonathan Brophy 2025-10-20 3:29 ` kernel test robot 2025-10-20 7:13 ` Dan Carpenter 2025-10-19 14:24 ` [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jacek Anaszewski 4 siblings, 2 replies; 18+ messages in thread From: Jonathan Brophy @ 2025-10-19 9:23 UTC (permalink / raw) To: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds From: Jonathan Brophy <professor_jonny@hotmail.com> Introduces a new driver that implements virtual LED groups, aggregating multiple monochromatic LEDs into virtual groups and providing priority-based control for concurrent state management. This driver is a work in progress, I am unable to get the read-only diagnostic sysfs attributes to show under the led framework. Author: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Co Author: Jonathan Brophy <professor_jonny@hotmail.com> Copyright (C) 2024 Jonathan Brophy <professor_jonny@hotmail.com> Co-developed-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Signed-off-by: Radoslav Tsvetkov <rtsvetkov@gradotech.eu> Tested-by: Jonathan Brophy <professor_jonny@hotmail.com> Signed-off-by: Jonathan Brophy <professor_jonny@hotmail.com> --- drivers/leds/rgb/Kconfig | 17 + drivers/leds/rgb/Makefile | 1 + drivers/leds/rgb/leds-group-virtualcolor.c | 513 +++++++++++++++++++++ 3 files changed, 531 insertions(+) create mode 100644 drivers/leds/rgb/leds-group-virtualcolor.c diff --git a/drivers/leds/rgb/Kconfig b/drivers/leds/rgb/Kconfig index 222d943d826a..70a80fd46b9c 100644 --- a/drivers/leds/rgb/Kconfig +++ b/drivers/leds/rgb/Kconfig @@ -75,4 +75,21 @@ config LEDS_MT6370_RGB This driver can also be built as a module. If so, the module will be called "leds-mt6370-rgb". +config LEDS_GROUP_VIRTUALCOLOR + tristate "Virtual LED Group Driver with Priority Control" + depends on OF || COMPILE_TEST + help + This option enables support for virtual LED groups that aggregate + multiple monochromatic LEDs with priority-based control. It allows + managing concurrent LED activation requests by ensuring only the + highest-priority LED state is active at any given time. + + Multiple LEDs can be grouped together and controlled as a single + virtual LED with priority levels and blinking support. This is + useful for systems that need to manage multiple LED indicators + with different priority levels. + + To compile this driver as a module, choose M here: the module + will be called leds-group-virtualcolor. + endif # LEDS_CLASS_MULTICOLOR diff --git a/drivers/leds/rgb/Makefile b/drivers/leds/rgb/Makefile index a501fd27f179..693fd300b849 100644 --- a/drivers/leds/rgb/Makefile +++ b/drivers/leds/rgb/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_LEDS_NCP5623) += leds-ncp5623.o obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o obj-$(CONFIG_LEDS_MT6370_RGB) += leds-mt6370-rgb.o +obj-$(CONFIG_LEDS_GROUP_VIRTUALCOLOR) += leds-group-virtualcolor.o diff --git a/drivers/leds/rgb/leds-group-virtualcolor.c b/drivers/leds/rgb/leds-group-virtualcolor.c new file mode 100644 index 000000000000..035985174743 --- /dev/null +++ b/drivers/leds/rgb/leds-group-virtualcolor.c @@ -0,0 +1,513 @@ +// PWM RGB LED driver with per-color grouped LED arrays + +#include <linux/leds.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/list.h> + +#define MAX_LEDS_PER_COLOR 5 + +enum led_color_channel { + LED_RED = 0, + LED_GREEN = 1, + LED_BLUE = 2, + LED_COLOR_MAX +}; + +struct color_channel { + struct led_classdev **leds; // Array of LEDs for this color + int num_leds; // Count of LEDs in this color + enum led_brightness brightness; // Current brightness for this color + char *color_name; +}; + +struct virtual_led { + struct led_classdev cdev; + struct led_classdev **monochromatics; // Regular monochromatic LEDs + struct color_channel colors[LED_COLOR_MAX]; // RGB color channels + int num_monochromatics; + struct leds_virtualcolor *vc_data; + int priority; + struct list_head list; +}; + +struct leds_virtualcolor { + struct virtual_led *vleds; + int num_vleds; + struct list_head active_leds; + struct mutex lock; +}; + +/** + * Apply brightness to all LEDs of a specific color + */ +static void color_set_brightness(struct color_channel *color, + enum led_brightness brightness) +{ + int i; + + for (i = 0; i < color->num_leds; i++) + led_set_brightness(color->leds[i], brightness); + + color->brightness = brightness; +} + +/** + * Apply brightness to monochromatic LEDs + */ +static void virtual_set_monochromatic_brightness(struct virtual_led *vled, + enum led_brightness brightness) +{ + int i; + + for (i = 0; i < vled->num_monochromatics; i++) + led_set_brightness(vled->monochromatics[i], brightness); +} + +/** + * Apply brightness to all RGB color channels + */ +static void virtual_set_rgb_brightness(struct virtual_led *vled, + enum led_brightness brightness) +{ + int i; + + for (i = 0; i < LED_COLOR_MAX; i++) { + if (vled->colors[i].num_leds > 0) + color_set_brightness(&vled->colors[i], brightness); + } +} + +/** + * Set independent brightness per color (R, G, B) + */ +static void virtual_set_rgb_independent(struct virtual_led *vled, + enum led_brightness r, + enum led_brightness g, + enum led_brightness b) +{ + if (vled->colors[LED_RED].num_leds > 0) + color_set_brightness(&vled->colors[LED_RED], r); + + if (vled->colors[LED_GREEN].num_leds > 0) + color_set_brightness(&vled->colors[LED_GREEN], g); + + if (vled->colors[LED_BLUE].num_leds > 0) + color_set_brightness(&vled->colors[LED_BLUE], b); +} + +static ssize_t priority_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + int priority; + + mutex_lock(&vled->vc_data->lock); + priority = vled->priority; + mutex_unlock(&vled->vc_data->lock); + + return sysfs_emit(buf, "%d\n", priority); +} + +static ssize_t priority_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + int new_priority; + int ret; + + ret = kstrtoint(buf, 10, &new_priority); + if (ret < 0) + return ret; + + mutex_lock(&vled->vc_data->lock); + vled->priority = new_priority; + mutex_unlock(&vled->vc_data->lock); + + return count; +} + +/** + * Per-color brightness sysfs attributes + */ +static ssize_t red_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + return sysfs_emit(buf, "%d\n", vled->colors[LED_RED].brightness); +} + +static ssize_t red_brightness_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + int brightness; + int ret; + + ret = kstrtoint(buf, 10, &brightness); + if (ret < 0) + return ret; + + if (brightness < 0 || brightness > LED_FULL) + return -EINVAL; + + mutex_lock(&vled->vc_data->lock); + color_set_brightness(&vled->colors[LED_RED], brightness); + mutex_unlock(&vled->vc_data->lock); + + return count; +} + +static ssize_t green_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + return sysfs_emit(buf, "%d\n", vled->colors[LED_GREEN].brightness); +} + +static ssize_t green_brightness_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + int brightness; + int ret; + + ret = kstrtoint(buf, 10, &brightness); + if (ret < 0) + return ret; + + if (brightness < 0 || brightness > LED_FULL) + return -EINVAL; + + mutex_lock(&vled->vc_data->lock); + color_set_brightness(&vled->colors[LED_GREEN], brightness); + mutex_unlock(&vled->vc_data->lock); + + return count; +} + +static ssize_t blue_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + return sysfs_emit(buf, "%d\n", vled->colors[LED_BLUE].brightness); +} + +static ssize_t blue_brightness_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct virtual_led *vled = dev_get_drvdata(dev); + int brightness; + int ret; + + ret = kstrtoint(buf, 10, &brightness); + if (ret < 0) + return ret; + + if (brightness < 0 || brightness > LED_FULL) + return -EINVAL; + + mutex_lock(&vled->vc_data->lock); + color_set_brightness(&vled->colors[LED_BLUE], brightness); + mutex_unlock(&vled->vc_data->lock); + + return count; +} + +static DEVICE_ATTR_RW(priority); +static DEVICE_ATTR_RW(red_brightness); +static DEVICE_ATTR_RW(green_brightness); +static DEVICE_ATTR_RW(blue_brightness); + +static struct attribute *virtual_led_attrs[] = { + &dev_attr_priority.attr, + &dev_attr_red_brightness.attr, + &dev_attr_green_brightness.attr, + &dev_attr_blue_brightness.attr, + NULL, +}; + +static const struct attribute_group virtual_led_attr_group = { + .attrs = virtual_led_attrs, +}; + +static bool virtual_led_is_active(struct list_head *head, struct virtual_led *vled) +{ + struct virtual_led *entry; + + list_for_each_entry(entry, head, list) { + if (entry == vled) + return true; + } + + return false; +} + +static int virtual_led_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct virtual_led *vled = container_of(cdev, struct virtual_led, cdev); + struct leds_virtualcolor *vc_data = vled->vc_data; + struct virtual_led *active; + + mutex_lock(&vc_data->lock); + + active = list_first_entry_or_null(&vc_data->active_leds, struct virtual_led, list); + if (active) { + if (active->priority > vled->priority) + goto out_unlock; + + virtual_set_monochromatic_brightness(active, LED_OFF); + virtual_set_rgb_brightness(active, LED_OFF); + } + + if (brightness == LED_OFF) { + if (virtual_led_is_active(&vc_data->active_leds, vled)) + list_del(&vled->list); + + active = list_first_entry_or_null(&vc_data->active_leds, struct virtual_led, list); + if (active) { + virtual_set_monochromatic_brightness(active, active->cdev.brightness); + /* Restore each color to its saved brightness */ + virtual_set_rgb_independent(active, + active->colors[LED_RED].brightness, + active->colors[LED_GREEN].brightness, + active->colors[LED_BLUE].brightness); + } + } else { + if (!virtual_led_is_active(&vc_data->active_leds, vled)) + list_add(&vled->list, &vc_data->active_leds); + + active = list_first_entry_or_null(&vc_data->active_leds, struct virtual_led, list); + if (active) { + virtual_set_monochromatic_brightness(active, brightness); + virtual_set_rgb_brightness(active, brightness); + } + } + +out_unlock: + mutex_unlock(&vc_data->lock); + + return 0; +} + +/** + * Parse monochromatic LEDs from device tree + */ +static int parse_monochromatic_leds(struct device *dev, struct device_node *child, + struct virtual_led *vled) +{ + u32 mono_count; + int ret, i; + + mono_count = of_property_count_elems_of_size(child, "leds", sizeof(u32)); + if (mono_count <= 0) { + vled->num_monochromatics = 0; + return 0; + } + + vled->num_monochromatics = mono_count; + vled->monochromatics = devm_kcalloc(dev, vled->num_monochromatics, + sizeof(*vled->monochromatics), GFP_KERNEL); + if (!vled->monochromatics) + return -ENOMEM; + + for (i = 0; i < vled->num_monochromatics; i++) { + struct led_classdev *led_cdev; + + led_cdev = devm_of_led_get(dev, i); + if (IS_ERR(led_cdev)) { + ret = PTR_ERR(led_cdev); + return dev_err_probe(dev, ret, + "Failed to get monochromatic LED %d\n", i); + } + + vled->monochromatics[i] = led_cdev; + } + + return 0; +} + +/** + * Parse color-grouped PWM LEDs from device tree + * Format: + * pwm-leds-red = <&pwm_r0 &pwm_r1>; + * pwm-leds-green = <&pwm_g0 &pwm_g1>; + * pwm-leds-blue = <&pwm_b0>; + */ +static int parse_pwm_color_leds(struct device *dev, struct device_node *child, + struct virtual_led *vled) +{ + const char *color_props[] = {"pwm-leds-red", "pwm-leds-green", "pwm-leds-blue"}; + const char *color_names[] = {"Red", "Green", "Blue"}; + int ret, c, i, count; + + for (c = 0; c < LED_COLOR_MAX; c++) { + count = of_property_count_elems_of_size(child, color_props[c], sizeof(u32)); + if (count < 0) { + vled->colors[c].num_leds = 0; + continue; + } + + if (count > MAX_LEDS_PER_COLOR) { + return dev_err_probe(dev, -EINVAL, + "Too many %s LEDs (%d), max %d\n", + color_names[c], count, MAX_LEDS_PER_COLOR); + } + + vled->colors[c].num_leds = count; + vled->colors[c].color_name = (char *)color_names[c]; + vled->colors[c].brightness = LED_OFF; + + vled->colors[c].leds = devm_kcalloc(dev, count, + sizeof(*vled->colors[c].leds), GFP_KERNEL); + if (!vled->colors[c].leds) + return -ENOMEM; + + for (i = 0; i < count; i++) { + struct led_classdev *led_cdev; + + led_cdev = devm_of_led_get(dev, i); + if (IS_ERR(led_cdev)) { + ret = PTR_ERR(led_cdev); + return dev_err_probe(dev, ret, + "Failed to get %s LED %d\n", + color_names[c], i); + } + + vled->colors[c].leds[i] = led_cdev; + } + + dev_dbg(dev, "Parsed %d %s LEDs\n", count, color_names[c]); + } + + return 0; +} + +static int leds_virtualcolor_init_vled(struct device *dev, struct device_node *child, + struct virtual_led *vled, + struct leds_virtualcolor *vc_data) +{ + struct led_init_data init_data = {}; + u32 max_brightness; + int ret, total_rgb_leds = 0, c; + + ret = of_property_read_u32(child, "priority", &vled->priority); + if (ret) + vled->priority = 0; + + INIT_LIST_HEAD(&vled->list); + + /* Parse monochromatic LEDs */ + ret = parse_monochromatic_leds(dev, child, vled); + if (ret) + return ret; + + /* Parse color-grouped PWM LEDs */ + ret = parse_pwm_color_leds(dev, child, vled); + if (ret) + return ret; + + /* Count total RGB LEDs */ + for (c = 0; c < LED_COLOR_MAX; c++) + total_rgb_leds += vled->colors[c].num_leds; + + /* At least one type of LED must be present */ + if (vled->num_monochromatics == 0 && total_rgb_leds == 0) { + return dev_err_probe(dev, -EINVAL, + "No LEDs specified for virtual LED\n"); + } + + ret = of_property_read_u32(child, "max-brightness", &max_brightness); + if (ret) + vled->cdev.max_brightness = LED_FULL; + else + vled->cdev.max_brightness = max_brightness; + + vled->cdev.brightness_set_blocking = virtual_led_brightness_set; + vled->cdev.flags = LED_CORE_SUSPENDRESUME; + + ret = devm_led_classdev_register_ext(dev, &vled->cdev, &init_data); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register virtual LED\n"); + + dev_set_drvdata(vled->cdev.dev, vled); + + ret = devm_device_add_group(vled->cdev.dev, &virtual_led_attr_group); + if (ret) + return dev_err_probe(dev, ret, + "Failed to create sysfs attributes\n"); + + vled->vc_data = vc_data; + + dev_info(dev, "Virtual LED: %d mono, %d red, %d green, %d blue\n", + vled->num_monochromatics, vled->colors[LED_RED].num_leds, + vled->colors[LED_GREEN].num_leds, vled->colors[LED_BLUE].num_leds); + + return 0; +} + +static int leds_virtualcolor_probe(struct platform_device *pdev) +{ + struct leds_virtualcolor *vc_data; + struct device *dev = &pdev->dev; + int count = 0; + int ret; + + vc_data = devm_kzalloc(dev, sizeof(*vc_data), GFP_KERNEL); + if (!vc_data) + return -ENOMEM; + + mutex_init(&vc_data->lock); + + ret = devm_add_action_or_reset(dev, (void (*)(void *))mutex_destroy, + &vc_data->lock); + if (ret) + return ret; + + INIT_LIST_HEAD(&vc_data->active_leds); + + vc_data->num_vleds = of_get_child_count(dev->of_node); + if (vc_data->num_vleds == 0) { + dev_err(dev, "No virtual LEDs defined\n"); + return -EINVAL; + } + + vc_data->vleds = devm_kcalloc(dev, vc_data->num_vleds, sizeof(*vc_data->vleds), GFP_KERNEL); + if (!vc_data->vleds) + return -ENOMEM; + + for_each_available_child_of_node_scoped(dev->of_node, child) { + struct virtual_led *vled = &vc_data->vleds[count]; + + ret = leds_virtualcolor_init_vled(dev, child, vled, vc_data); + if (ret) + return ret; + + count++; + } + + platform_set_drvdata(pdev, vc_data); + + return 0; +} + +static const struct of_device_id leds_virtualcolor_of_match[] = { + { .compatible = "leds-group-virtualcolor" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, leds_virtualcolor_of_match); + +static struct platform_driver leds_virtualcolor_driver = { + .probe = leds_virtualcolor_probe, + .driver = { + .name = "leds_virtualcolor", + .of_match_table = leds_virtualcolor_of_match, + }, +}; + +module_platform_driver(leds_virtualcolor_driver); + +MODULE_AUTHOR("Radoslav Tsvetkov <rtsvetkov@gradotech.eu>"); +MODULE_DESCRIPTION("Virtual Color LED Driver with RGB Color Grouping"); +MODULE_LICENSE("GPL"); -- 2.43.0 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3 4/4] leds: Add virtualcolor LED group driver 2025-10-19 9:23 ` [PATCH v3 4/4] leds: Add virtualcolor LED group driver Jonathan Brophy @ 2025-10-20 3:29 ` kernel test robot 2025-10-22 16:19 ` Nathan Chancellor 2025-10-20 7:13 ` Dan Carpenter 1 sibling, 1 reply; 18+ messages in thread From: kernel test robot @ 2025-10-20 3:29 UTC (permalink / raw) To: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: llvm, oe-kbuild-all, devicetree, linux-kernel, linux-leds Hi Jonathan, kernel test robot noticed the following build warnings: [auto build test WARNING on lee-leds/for-leds-next] [also build test WARNING on robh/for-next linus/master v6.18-rc2 next-20251017] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Brophy/dt-bindings-Add-virtualcolor-class-dt-bindings-documentation/20251019-172647 base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git for-leds-next patch link: https://lore.kernel.org/r/20251019092331.49531-5-professorjonny98%40gmail.com patch subject: [PATCH v3 4/4] leds: Add virtualcolor LED group driver config: i386-randconfig-001-20251020 (https://download.01.org/0day-ci/archive/20251020/202510201144.TwTDnjSJ-lkp@intel.com/config) compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251020/202510201144.TwTDnjSJ-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202510201144.TwTDnjSJ-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/leds/rgb/leds-group-virtualcolor.c:463:38: warning: cast from 'void (*)(struct mutex *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict] 463 | ret = devm_add_action_or_reset(dev, (void (*)(void *))mutex_destroy, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/device/devres.h:166:34: note: expanded from macro 'devm_add_action_or_reset' 166 | __devm_add_action_or_reset(dev, action, data, #action) | ^~~~~~ 1 warning generated. vim +463 drivers/leds/rgb/leds-group-virtualcolor.c 449 450 static int leds_virtualcolor_probe(struct platform_device *pdev) 451 { 452 struct leds_virtualcolor *vc_data; 453 struct device *dev = &pdev->dev; 454 int count = 0; 455 int ret; 456 457 vc_data = devm_kzalloc(dev, sizeof(*vc_data), GFP_KERNEL); 458 if (!vc_data) 459 return -ENOMEM; 460 461 mutex_init(&vc_data->lock); 462 > 463 ret = devm_add_action_or_reset(dev, (void (*)(void *))mutex_destroy, 464 &vc_data->lock); 465 if (ret) 466 return ret; 467 468 INIT_LIST_HEAD(&vc_data->active_leds); 469 470 vc_data->num_vleds = of_get_child_count(dev->of_node); 471 if (vc_data->num_vleds == 0) { 472 dev_err(dev, "No virtual LEDs defined\n"); 473 return -EINVAL; 474 } 475 476 vc_data->vleds = devm_kcalloc(dev, vc_data->num_vleds, sizeof(*vc_data->vleds), GFP_KERNEL); 477 if (!vc_data->vleds) 478 return -ENOMEM; 479 480 for_each_available_child_of_node_scoped(dev->of_node, child) { 481 struct virtual_led *vled = &vc_data->vleds[count]; 482 483 ret = leds_virtualcolor_init_vled(dev, child, vled, vc_data); 484 if (ret) 485 return ret; 486 487 count++; 488 } 489 490 platform_set_drvdata(pdev, vc_data); 491 492 return 0; 493 } 494 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 4/4] leds: Add virtualcolor LED group driver 2025-10-20 3:29 ` kernel test robot @ 2025-10-22 16:19 ` Nathan Chancellor 0 siblings, 0 replies; 18+ messages in thread From: Nathan Chancellor @ 2025-10-22 16:19 UTC (permalink / raw) To: kernel test robot Cc: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov, llvm, oe-kbuild-all, devicetree, linux-kernel, linux-leds On Mon, Oct 20, 2025 at 11:29:28AM +0800, kernel test robot wrote: ... > url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Brophy/dt-bindings-Add-virtualcolor-class-dt-bindings-documentation/20251019-172647 > base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git for-leds-next > patch link: https://lore.kernel.org/r/20251019092331.49531-5-professorjonny98%40gmail.com > patch subject: [PATCH v3 4/4] leds: Add virtualcolor LED group driver > config: i386-randconfig-001-20251020 (https://download.01.org/0day-ci/archive/20251020/202510201144.TwTDnjSJ-lkp@intel.com/config) > compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251020/202510201144.TwTDnjSJ-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202510201144.TwTDnjSJ-lkp@intel.com/ > > All warnings (new ones prefixed by >>): > > >> drivers/leds/rgb/leds-group-virtualcolor.c:463:38: warning: cast from 'void (*)(struct mutex *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict] > 463 | ret = devm_add_action_or_reset(dev, (void (*)(void *))mutex_destroy, > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > include/linux/device/devres.h:166:34: note: expanded from macro 'devm_add_action_or_reset' > 166 | __devm_add_action_or_reset(dev, action, data, #action) > | ^~~~~~ > 1 warning generated. This should use a dedicated wrapper function like a patch that I just sent for the same issue in another driver [1] to avoid a kernel control flow integrity violation at run time with CONFIG_CFI=y. [1]: https://lore.kernel.org/20251022-ishtp-fix-function-cast-warn-v1-1-bfb06464f8ca@kernel.org/ Cheers, Nathan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 4/4] leds: Add virtualcolor LED group driver 2025-10-19 9:23 ` [PATCH v3 4/4] leds: Add virtualcolor LED group driver Jonathan Brophy 2025-10-20 3:29 ` kernel test robot @ 2025-10-20 7:13 ` Dan Carpenter 2025-10-20 17:40 ` Jonathan Brophy 1 sibling, 1 reply; 18+ messages in thread From: Dan Carpenter @ 2025-10-20 7:13 UTC (permalink / raw) To: oe-kbuild, Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: lkp, oe-kbuild-all, devicetree, linux-kernel, linux-leds Hi Jonathan, kernel test robot noticed the following build warnings: https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Brophy/dt-bindings-Add-virtualcolor-class-dt-bindings-documentation/20251019-172647 base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git for-leds-next patch link: https://lore.kernel.org/r/20251019092331.49531-5-professorjonny98%40gmail.com patch subject: [PATCH v3 4/4] leds: Add virtualcolor LED group driver config: parisc-randconfig-r072-20251020 (https://download.01.org/0day-ci/archive/20251020/202510201457.uOrhkKly-lkp@intel.com/config) compiler: hppa-linux-gcc (GCC) 8.5.0 If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202510201457.uOrhkKly-lkp@intel.com/ smatch warnings: drivers/leds/rgb/leds-group-virtualcolor.c:303 parse_monochromatic_leds() warn: 'mono_count' unsigned <= 0 drivers/leds/rgb/leds-group-virtualcolor.c:303 parse_monochromatic_leds() warn: error code type promoted to positive: 'mono_count' vim +/mono_count +303 drivers/leds/rgb/leds-group-virtualcolor.c bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 296 static int parse_monochromatic_leds(struct device *dev, struct device_node *child, bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 297 struct virtual_led *vled) bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 298 { bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 299 u32 mono_count; This needs to be an int. bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 300 int ret, i; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 301 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 302 mono_count = of_property_count_elems_of_size(child, "leds", sizeof(u32)); bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 @303 if (mono_count <= 0) { ^^^^^^^^^^^^^^^ bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 304 vled->num_monochromatics = 0; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 305 return 0; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 306 } bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 307 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 308 vled->num_monochromatics = mono_count; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 309 vled->monochromatics = devm_kcalloc(dev, vled->num_monochromatics, bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 310 sizeof(*vled->monochromatics), GFP_KERNEL); bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 311 if (!vled->monochromatics) bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 312 return -ENOMEM; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 313 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 314 for (i = 0; i < vled->num_monochromatics; i++) { bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 315 struct led_classdev *led_cdev; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 316 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 317 led_cdev = devm_of_led_get(dev, i); bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 318 if (IS_ERR(led_cdev)) { bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 319 ret = PTR_ERR(led_cdev); bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 320 return dev_err_probe(dev, ret, bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 321 "Failed to get monochromatic LED %d\n", i); bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 322 } bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 323 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 324 vled->monochromatics[i] = led_cdev; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 325 } bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 326 bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 327 return 0; bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 328 } -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 4/4] leds: Add virtualcolor LED group driver 2025-10-20 7:13 ` Dan Carpenter @ 2025-10-20 17:40 ` Jonathan Brophy 0 siblings, 0 replies; 18+ messages in thread From: Jonathan Brophy @ 2025-10-20 17:40 UTC (permalink / raw) To: Dan Carpenter, oe-kbuild@lists.linux.dev, Jonathan Brophy, lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: lkp@intel.com, oe-kbuild-all@lists.linux.dev, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-leds@vger.kernel.org From: Dan Carpenter <dan.carpenter@linaro.org> Sent: Monday, October 20, 2025 8:13 PM >Hi Jonathan, > >kernel test robot noticed the following build warnings: > >patch subject: [PATCH v3 4/4] leds: Add virtualcolor LED group driver > >drivers/leds/rgb/leds-group-virtualcolor.c:303 parse_monochromatic_leds() warn: 'mono_count' unsigned <= 0 > >drivers/leds/rgb/leds-group-virtualcolor.c:303 parse_monochromatic_leds() warn: error code type promoted to positive: >'mono_count' > >bc8d39d8adf81b2 Jonathan Brophy 2025-10-19 299 u32 mono_count; > > >This needs to be an int. Thank you My compiler did not pick this up. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of 2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy ` (3 preceding siblings ...) 2025-10-19 9:23 ` [PATCH v3 4/4] leds: Add virtualcolor LED group driver Jonathan Brophy @ 2025-10-19 14:24 ` Jacek Anaszewski 2025-10-20 8:40 ` Alexander Dahl [not found] ` <DS0PR84MB37465DFAA8E8994B503A69829FF4A@DS0PR84MB3746.NAMPRD84.PROD.OUTLOOK.COM> 4 siblings, 2 replies; 18+ messages in thread From: Jacek Anaszewski @ 2025-10-19 14:24 UTC (permalink / raw) To: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree, linux-kernel, linux-leds Hi Jonathan, On 10/19/25 11:23, Jonathan Brophy wrote: > From: Jonathan Brophy <professor_jonny@hotmail.com> > > Introduce a new driver that implements virtual LED groups, > aggregating multiple monochromatic LEDs into virtual groups and providing > priority-based control for concurrent state management. Aren't you trying to reinvent LED trigger mechanism? -- Best regards, Jacek Anaszewski ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of 2025-10-19 14:24 ` [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jacek Anaszewski @ 2025-10-20 8:40 ` Alexander Dahl 2025-10-20 18:56 ` jonathan brophy [not found] ` <DS0PR84MB37465DFAA8E8994B503A69829FF4A@DS0PR84MB3746.NAMPRD84.PROD.OUTLOOK.COM> 1 sibling, 1 reply; 18+ messages in thread From: Alexander Dahl @ 2025-10-20 8:40 UTC (permalink / raw) To: Jacek Anaszewski Cc: Jonathan Brophy, lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov, devicetree, linux-kernel, linux-leds Hei Jacek, Am Sun, Oct 19, 2025 at 04:24:38PM +0200 schrieb Jacek Anaszewski: > Hi Jonathan, > > On 10/19/25 11:23, Jonathan Brophy wrote: > > From: Jonathan Brophy <professor_jonny@hotmail.com> > > > > Introduce a new driver that implements virtual LED groups, > > aggregating multiple monochromatic LEDs into virtual groups and providing > > priority-based control for concurrent state management. > > Aren't you trying to reinvent LED trigger mechanism? Instead of using virtual LEDs, could this be implemented as a "virtual" trigger which allows grouping (and prioritizing) multiple other triggers, and apply that to only one existing LED? Greets Alex ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of 2025-10-20 8:40 ` Alexander Dahl @ 2025-10-20 18:56 ` jonathan brophy 0 siblings, 0 replies; 18+ messages in thread From: jonathan brophy @ 2025-10-20 18:56 UTC (permalink / raw) To: Alexander Dahl, Jacek Anaszewski Cc: lee Jones, Pavel Machek, Jonathan Brophy, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-leds@vger.kernel.org Hi Alexander > >From: Alexander Dahl <ada@thorsis.com> >Sent: Monday, October 20, 2025 9:40 PM > >Hei Jacek, > > > >Am Sun, Oct 19, 2025 at 04:24:38PM +0200 schrieb Jacek Anaszewski: > >> Hi Jonathan, > >> > >> On 10/19/25 11:23, Jonathan Brophy wrote: > >> > From: Jonathan Brophy <professor_jonny@hotmail.com> > >> > Introduce a new driver that implements virtual LED groups, > >> > aggregating multiple monochromatic LEDs into virtual groups and providing > >> > priority-based control for concurrent state management. > > >> Aren't you trying to reinvent LED trigger mechanism? > > > >Instead of using virtual LEDs, could this be implemented as a > >"virtual" trigger which allows grouping (and prioritizing) multiple > >other triggers, and apply that to only one existing LED? > > > >Greets > >Alex I looked at this you would have to include priority for each virtual trigger and it would get very hard to understand very quickly. then things like per channel color for each trigger etc would just be impossible to implement.. it would need a way to map and display it logically under sysfs too. For example the additive RGB color wheel has 3 primary colors if you have a solid and a blink for each primary and secondary color that is 8 triggers for a single led. I'm basically following the similar structure of leds-group-multicolor where they in effect create a new structure representing individual led elements but, instead of displaying the properties of the parent items, I'm creating new virtual properties that of the group in the form of a single virtual LED or a multi LED. ^ permalink raw reply [flat|nested] 18+ messages in thread
[parent not found: <DS0PR84MB37465DFAA8E8994B503A69829FF4A@DS0PR84MB3746.NAMPRD84.PROD.OUTLOOK.COM>]
* Re: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of [not found] ` <DS0PR84MB37465DFAA8E8994B503A69829FF4A@DS0PR84MB3746.NAMPRD84.PROD.OUTLOOK.COM> @ 2025-10-20 18:57 ` Jacek Anaszewski 2025-10-20 21:45 ` professorjonny98 0 siblings, 1 reply; 18+ messages in thread From: Jacek Anaszewski @ 2025-10-20 18:57 UTC (permalink / raw) To: Jonathan Brophy, Jonathan Brophy, lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Radoslav Tsvetkov Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-leds@vger.kernel.org On 10/19/25 23:17, Jonathan Brophy wrote: > on 10/20/25 3:25am Jacek Anaszewski wrote: >> On 10/19/25 11:23, Jonathan Brophy wrote: > >>> From: Jonathan Brophy <professor_jonny@hotmail.com> >>> >>> Introduce a new driver that implements virtual LED groups, >>> aggregating multiple monochromatic LEDs into virtual groups and providing >>> priority-based control for concurrent state management. >> >>Aren't you trying to reinvent LED trigger mechanism? >> >>-- >>Best regards, >>Jacek Anaszewski > > It is much simpler than that, I'm just trying to group LEDs into a new > virtual (fake) leds with some priority rules and define all this in the > DTS. > > Consider below is a dts of my router as an example. > > The leds node is the actual status LED I have in my router three > elements red, green and blue: > > Then I have my virtualcolor_leds node defining my groups that consist of > these elements. > > I have two leds defined in each color I wish to display one that blinks > and one that does not. > > From here I can define all my led colors and logic pattern in the > device tree. > > These virtual LEDs just appear as regular LEDs in sysfs. > > After a factory reset of my device I would expect the status led to be > solid yellow when it starts up then when ready to setup blink blue ready > for setup. > > It I connected these ot standard triggers I would end up with a mess not > knowing the status if multiple triggers operated at the same time. > > Without the logic I would likely after boot have a yellow led that > flashes white as the solid yellow would mix with the flashing blue by > mixing of the power and setting up triggers. > > I can define aliases to the virtual leds for access within user space > and have all the features of a normal led with out the logic headache. > > My alternative is to create a driver defining logic in userspace with a > cronjob or as such or with a custom binary. Userspace "driver" or rather a service would be for sure an approach quicker to implement, that would not need lengthy discussion here to achieve a consensus on the design. Otherwise, I would see this solution rather as a new LED trigger, that would allow to define the LEDs to be grouped under it. The trigger interface would need also to allow defining patterns according to which the LEDs would be lit. Still, the trigger would be a task for months, and would need much analysis to come up with a reasonable user interface. -- Best regards, Jacek Anaszewski ^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of 2025-10-20 18:57 ` Jacek Anaszewski @ 2025-10-20 21:45 ` professorjonny98 0 siblings, 0 replies; 18+ messages in thread From: professorjonny98 @ 2025-10-20 21:45 UTC (permalink / raw) To: 'Jacek Anaszewski', 'Jonathan Brophy', 'lee Jones', 'Pavel Machek', 'Rob Herring', 'Krzysztof Kozlowski', 'Conor Dooley', 'Radoslav Tsvetkov' Cc: devicetree, linux-kernel, linux-leds Hi Jacek >From: Jacek Anaszewski <jacek.anaszewski@gmail.com> >Sent: Tuesday, 21 October 2025 7:57 AM >To: Jonathan Brophy <Professor_jonny@hotmail.com>; Jonathan Brophy <professorjonny98@gmail.com>; lee Jones <lee@kernel.org>; Pavel Machek <pavel@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Radoslav Tsvetkov ><rtsvetkov@gradotech.eu> >Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-leds@vger.kernel.org >Subject: Re: [PATCH v3 0/4] leds: Add a virtual LED driver for groups of > >On 10/19/25 23:17, Jonathan Brophy wrote: >> on 10/20/25 3:25am Jacek Anaszewski wrote: >>> On 10/19/25 11:23, Jonathan Brophy wrote: >> >>>> From: Jonathan Brophy <professor_jonny@hotmail.com> >>>> >>>> Introduce a new driver that implements virtual LED groups, >>>> aggregating multiple monochromatic LEDs into virtual groups and >>>> providing priority-based control for concurrent state management. >>> >>>Aren't you trying to reinvent LED trigger mechanism? >>> >>>-- >>>Best regards, >>>Jacek Anaszewski >> >> It is much simpler than that, I'm just trying to group LEDs into a new >> virtual (fake) leds with some priority rules and define all this in >> the DTS. >> >> Consider below is a dts of my router as an example. >> >> The leds node is the actual status LED I have in my router three >> elements red, green and blue: >> >> Then I have my virtualcolor_leds node defining my groups that consist >> of these elements. >> >> I have two leds defined in each color I wish to display one that >> blinks and one that does not. >> >> From here I can define all my led colors and logic pattern in the >> device tree. >> >> These virtual LEDs just appear as regular LEDs in sysfs. >> >> After a factory reset of my device I would expect the status led to be >> solid yellow when it starts up then when ready to setup blink blue >> ready for setup. >> >> It I connected these ot standard triggers I would end up with a mess >> not knowing the status if multiple triggers operated at the same time. >> >> Without the logic I would likely after boot have a yellow led that >> flashes white as the solid yellow would mix with the flashing blue by >> mixing of the power and setting up triggers. >> >> I can define aliases to the virtual leds for access within user space >> and have all the features of a normal led with out the logic headache. >> >> My alternative is to create a driver defining logic in userspace with >> a cronjob or as such or with a custom binary. > >Userspace "driver" or rather a service would be for sure an approach quicker to implement, that would not need lengthy discussion here to achieve a consensus on the design. > >Otherwise, I would see this solution rather as a new LED trigger, that would allow to define the LEDs to be grouped under it. The trigger interface would need also to allow defining patterns according to which the LEDs would be lit. > >Still, the trigger would be a task for months, and would need much analysis to come up with a reasonable user interface. > >-- >Best regards, >Jacek Anaszewski The initial reason for this driver was to define aliases to point to standard triggers in OpenWrt I'm happy that this driver will fit my purpose and will solve a long-standing issue of control of status LEDs without other complicated means. If there is a better Idea to do this awesome but I am not very skilled and I dont know if I will be able to implement this myself. Having these things bound in the DTS enable status LEDs to be able to connect directly to hardware triggers on things like Ethernet ports. I also have security concerns with being able to alter triggers for important things like warning lights from userspace for the things I wish to attach them too. What I come up with is secure and easy to work out what is going on and does not alter major parts of the framework. With drivers everyone creates their own driver to effectively manage LED in their device, and it becomes a problem where the OpenWrt community has to reverse engineer their efforts this makes it a little bit more unified if manufactures adopt a standard approach to led control of grouped LEDs to format color-based status indication. My TPlink x80-5g modem router had the basis of a similar grouping function with a similar structure in the DTS from the manufacturer but it was very basic compared to what I have created. Best regards Jonathan Brophy ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-10-22 16:20 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-19 9:23 [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jonathan Brophy
2025-10-19 9:23 ` [PATCH v3 1/4] dt: bindings: Add virtualcolor class dt bindings documentation Jonathan Brophy
2025-10-19 10:39 ` Krzysztof Kozlowski
2025-10-19 9:23 ` [PATCH v3 2/4] dt-bindings: leds: Add virtualcolor group " Jonathan Brophy
2025-10-19 10:43 ` Krzysztof Kozlowski
2025-10-20 11:35 ` Rob Herring (Arm)
2025-10-20 18:00 ` jonathan brophy
2025-10-19 9:23 ` [PATCH v3 3/4] ABI: Add sysfs documentation for leds-group-virtualcolor Jonathan Brophy
2025-10-19 9:23 ` [PATCH v3 4/4] leds: Add virtualcolor LED group driver Jonathan Brophy
2025-10-20 3:29 ` kernel test robot
2025-10-22 16:19 ` Nathan Chancellor
2025-10-20 7:13 ` Dan Carpenter
2025-10-20 17:40 ` Jonathan Brophy
2025-10-19 14:24 ` [PATCH v3 0/4] leds: Add a virtual LED driver for groups of Jacek Anaszewski
2025-10-20 8:40 ` Alexander Dahl
2025-10-20 18:56 ` jonathan brophy
[not found] ` <DS0PR84MB37465DFAA8E8994B503A69829FF4A@DS0PR84MB3746.NAMPRD84.PROD.OUTLOOK.COM>
2025-10-20 18:57 ` Jacek Anaszewski
2025-10-20 21:45 ` professorjonny98
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).