From nobody Mon Feb 9 06:25:42 2026 Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 767202DA76A for ; Tue, 30 Dec 2025 00:33:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767054807; cv=none; b=kNwoR4RW8RdLyFemnuy2TAlPJn+uycettR0NntJq5WLj7uK/iTqZ91KawdwD3RfxiTa7395beAGQMQU0+ODtkFJoXP2vViEe2Jk4BW4Z5Rs/eYSQ7ne8nTLwiOOnDfN85nif5CIRznD/x4w7Oi++6232VoaxgKCuuGghpxHvnkc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767054807; c=relaxed/simple; bh=vb/BqLUoijBBLDl/+VX63lRV9liHQyfBjjjfUcHVVj4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eKrEVzPctFr+wv6946XKD7s7BtJD3Ay7k0mpE7me6o1TTY1OtwBZdseTN2ix/51svGNT7stYRhpFbfIrW8/ntOGsO0IIRQIMRTPCi0DVSc94iyArsRQxjJyHH0lIaxrPOdkL2PFJ20d+orCX1nvWUD/fFff/cibXqi0zsuAFv8U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nIwrHut4; arc=none smtp.client-ip=209.85.210.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nIwrHut4" Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-7b8e49d8b35so11681540b3a.3 for ; Mon, 29 Dec 2025 16:33:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767054805; x=1767659605; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1p20MzKIYWjbK41XCAaEYmJOhhEoaluLx+FMxYZpXG4=; b=nIwrHut4lzF28ux5/pyuYp8leBicqOoAPV8fLDGQEMF6eimJYLv0PhMmSCZpHVYX0/ Yzq+Kgwb8x930jp2hJuYq1GWzbNrFFfwCOxnVvfhG2sCHJ5mG7dBvHlhyfgElHYMt0UV DUvCZxmHXrqbASjCbDI+cM5lvGmJ3Vk5YmLj3H2PR2Mhy6JbcSu0BjQkr0UwvmNmSlmB JI6rx1bFylpu8g0d1g5bXJq7uWrv/eDAnGm6J1uLT8j9+FKIcPvR8+mj4SLtnDpP3xW7 tXNHFWmZdklfH2npaUbn+L7H7JpXeaY0tBwGL2PaEQnA3ZvdGrQRXRMVb9gfFnBOo+xL aZVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767054805; x=1767659605; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=1p20MzKIYWjbK41XCAaEYmJOhhEoaluLx+FMxYZpXG4=; b=EPoZZp08+31jfLyname6tT0X+g3dOL0QW0FRuTVEe84H3mt8UPb4ExhQs/6trX1Uz0 c0H1tgbS9dGggxkeYoNByeW3qTutykLr0yWyWD/YBqQRyIbsnDG2R4h78+FxDpTCvRjA r7IllMoNHgVszbvv+O3xEJ95gNV9n/RZobVovioGoC9s7hj5MaB1ViuaJAJI0SFFsxEx SJBWzABB0xfP4jdcWeWnYEG5suKxo6a6z02H/q4mjW72PwhxNChpNSWQEgnBgXX0GtsW 13WamQ+ORLVA17HANE7Pbp2cT/zL7GBLsl93woIsy28y30TqGBW49BOaoxlj3WB1e9mY AdvA== X-Forwarded-Encrypted: i=1; AJvYcCXogIRl8n/yJuEJd9vtHU6dptDH4Nqo6/uc2N/fncycikhKGpLwC1nWxW05t7WEtk7v+PPS5PvzcpRWsfQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwBZQdmBdO+wIxQMOJwehSWqx715VmWSJSzDL9WZXn+u2mr5gs2 HPoFxYYm2MQKSmvoRh2tNqlOVcdxhVm7xLL8PTpuKsSpjExKJNnCWHlV X-Gm-Gg: AY/fxX54XHJ2cwadAIsjroHGIoOQDMQ6+vmV0jaSfRdXFrH99e+SeFRNiZ03lx8UJl/ 3qt8M/rORsiFQGVwTQdGs9thFBxaEGrT23yh2/4C+Gp95ZP5Y4hwir9Kv+cyB+IK+0szG20CfkE OyK2nMLx/m/6ku8NkfwZcV3hN8TiNdSKQReR2ETJWGM8vkKMDRZDENQQQppds6/5K9ISUJtjy4b i11Qs119QViCp7FfJNMzlXB9iAoSF3bUNnLzGw/Ayy2I+wRXOsOyQeigOunmirs8dsEWIW8yqUb 1n/18hjQVACALVDPa9+hPQ7o1Hb0Vb658E2N7am0YHT8ES/A6aU4rhhOZrNJVSy6YvpZXTNggWh Jt44O7pH1Q0WeK1iXBteePDIYTXhNv5N8PggSD+o0MFw+sisyZb0PYUn3ckS1yb5U0f5SIBj94D lC+29VREIiE9RtLx62JwwfFkYemgeUz4kx X-Google-Smtp-Source: AGHT+IGRgSrXXats3j15UWzgm8MkcNt+CUJWGAcVoa5xo4AR4v9EqVI4JWtRVE11S+bu1IVfOzO2CQ== X-Received: by 2002:a05:6a00:4298:b0:7a2:8529:259 with SMTP id d2e1a72fcca58-7ff650c7d8dmr27213399b3a.9.1767054804733; Mon, 29 Dec 2025 16:33:24 -0800 (PST) Received: from MRSPARKLE.localdomain ([150.228.155.85]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7ff7e8947a1sm30241562b3a.67.2025.12.29.16.33.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Dec 2025 16:33:24 -0800 (PST) From: Jonathan Brophy To: lee Jones , Pavel Machek , Andriy Shevencho , Jonathan Brophy , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Radoslav Tsvetkov Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-leds@vger.kernel.org Subject: [PATCH v4 3/7] dt-bindings: leds: Add virtual LED group controller bindings Date: Tue, 30 Dec 2025 13:32:40 +1300 Message-ID: <20251230003250.1197744-4-professorjonny98@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251230003250.1197744-1-professorjonny98@gmail.com> References: <20251230003250.1197744-1-professorjonny98@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jonathan Brophy Add device tree bindings for the virtual LED group controller that provides priority-based arbitration for shared physical LEDs across multiple virtual LED instances. 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 or a single trigger. It also becomes useful with multiple LEDs operating the same indicator such= as ring of light indicators, led rope where the LEDs are driven From different= GPIO outputs unifying the control that can give basic indication during system s= tartup, shutdown upgrade etc... The controller implements winner-takes-all arbitration where only the highest-priority active virtual LED controls the hardware at any given time. This enables multiple subsystems (boot, error, status indicators) to request LED control without explicit coordination. Binding supports: - Multiple virtual LED children with independent priorities - GPIO, PWM, I2C, and SPI physical LED devices - Multicolor and standard (fixed-color) operating modes - Global ownership tracking to prevent conflicts Example configurations include: - High-priority emergency/error RGB indicator - Medium-priority system state RGBW indicator - Low-priority warm white fixed-color indicator Co-developed-by: Radoslav Tsvetkov Signed-off-by: Radoslav Tsvetkov Signed-off-by: Jonathan Brophy --- .../leds/leds-group-virtualcolor.yaml | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-group-virtu= alcolor.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..88c044f42879 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-group-virtualcolor.yaml @@ -0,0 +1,170 @@ +# 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: Virtual LED Group Controller with Multicolor Support + +maintainers: + - Jonathan Brophy + +description: | + The virtual LED group controller provides priority-based arbitration for + shared physical LEDs across multiple virtual LED instances. Each virtual= LED + combines physical monochromatic LEDs into logical units with: + + - Priority-based arbitration: Higher priority virtual LEDs take preceden= ce + when multiple virtual LEDs compete for the same physical LEDs + - Sequence-based tie-breaking: Among equal priorities, most recent updat= e wins + - Winner-takes-all: Only ONE virtual LED controls ALL physical LEDs at a= ny time + - Color channel grouping: Organize LEDs by color for multicolor control + - Full multicolor ABI support: multi_intensity, multi_index, multi_multi= pliers + - Two operating modes: + * Multicolor mode: Dynamic per-channel intensity control (default) + * Standard mode: Fixed color ratios via multipliers (brightness only) + - Brightness scaling: Master brightness control with per-channel intensi= ty + - Global ownership: Physical LEDs claimed exclusively per controller ins= tance + - Update batching: Optional coalescing of rapid brightness changes + + Key features: + - Supports GPIO, PWM, I2C, and SPI LED devices + - Automatic physical LED discovery and claiming + - Lock-free arbitration with atomic sequence numbers + - Suspend/resume with state preservation + - Comprehensive debugfs telemetry (when CONFIG_DEBUG_FS enabled) + + Typical use cases: + - System status indicators with boot/update/error priority levels + - RGB lighting with priority-based overrides + - Multi-element LED arrays unified into single logical controls + - LED rings or strips with coordinated color control + +properties: + compatible: + const: leds-group-virtualcolor + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^virtual-led@[0-9a-f]+$": + type: object + $ref: leds-class-virtualcolor.yaml# + +required: + - compatible + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + /* Physical LED definitions */ + led-controller { + compatible =3D "gpio-leds"; + + led_red: led-red { + color =3D ; + function =3D LED_FUNCTION_STATUS; + gpios =3D <&gpio0 10 GPIO_ACTIVE_HIGH>; + default-state =3D "off"; + }; + + led_green: led-green { + color =3D ; + function =3D LED_FUNCTION_STATUS; + gpios =3D <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state =3D "off"; + }; + + led_blue: led-blue { + color =3D ; + function =3D LED_FUNCTION_STATUS; + gpios =3D <&gpio0 12 GPIO_ACTIVE_HIGH>; + default-state =3D "off"; + }; + + led_white: led-white { + color =3D ; + function =3D LED_FUNCTION_STATUS; + gpios =3D <&gpio0 13 GPIO_ACTIVE_HIGH>; + default-state =3D "off"; + }; + }; + + pwm-led-controller { + compatible =3D "pwm-leds"; + + pwm_red: led-pwm-red { + color =3D ; + function =3D LED_FUNCTION_STATUS; + pwms =3D <&pwm 0 7812500>; + max-brightness =3D <255>; + }; + + pwm_green: led-pwm-green { + color =3D ; + function =3D LED_FUNCTION_STATUS; + pwms =3D <&pwm 1 7812500>; + max-brightness =3D <255>; + }; + + pwm_blue: led-pwm-blue { + color =3D ; + function =3D LED_FUNCTION_STATUS; + pwms =3D <&pwm 2 7812500>; + max-brightness =3D <255>; + }; + }; + + /* virtual LED definitions */ + virtual-led-controller { + compatible =3D "leds-group-virtualcolor"; + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* High-priority RGB virtual LED (emergency/error indicator) */ + virtual-led@0 { + reg =3D <0>; + color =3D ; + function =3D LED_FUNCTION_STATUS; + priority =3D <1000>; + led-mode =3D "multicolor"; + leds =3D <&led_red>, <&led_green>, <&led_blue>; + /* Channels ordered by color ID: [0]=3Dred, [1]=3Dgreen, [2]= =3Dblue */ + }; + + /* Medium-priority RGBW indicator (system state) */ + virtual-led@1 { + reg =3D <1>; + color =3D ; + function =3D LED_FUNCTION_STATUS; + priority =3D <500>; + led-mode =3D "multicolor"; + leds =3D <&pwm_red>, <&pwm_green>, <&pwm_blue>, <&led_white>; + /* Channels: [0]=3Dwhite (ID=3D0), [1]=3Dred, [2]=3Dgreen, [3]= =3Dblue */ + }; + + /* Low-priority warm white (fixed color ratios, standard mode) */ + virtual-led@2 { + reg =3D <2>; + color =3D ; + function =3D LED_FUNCTION_STATUS; + priority =3D <10>; + led-mode =3D "standard"; + leds =3D <&led_red>, <&led_green>, <&led_blue>; + /* Channels: [0]=3Dred, [1]=3Dgreen, [2]=3Dblue */ + mc-channel-multipliers =3D <255 180 100>; + /* Creates warm white: full red, 70% green, 40% blue */ + }; + }; + +... -- 2.43.0