From nobody Sun Feb 8 21:33:51 2026 Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) (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 D90382FFF87 for ; Tue, 30 Dec 2025 08:24:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767083047; cv=none; b=cg5m2rSkkC+r1Hk1pZl4ALJcYtDV3S64XeVewcT5xeaqo8Mh06NoeyKikghz0MZjaVBgjUOxcrcrta/JS3LTD9/5WlF4/eSciKZXkEvoRyoEcYp45izhUIfNlEHuDrrRzpSBNm0DPyaXtEnOErydBae128TFEWwrLeoSv/gCqMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767083047; c=relaxed/simple; bh=OH5YDLvT7eFInoiNwMPu3oyYKH1FopxqgxlbMJ+9IBM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qWUeNWXyO0kEl+i46R536P7EOhtMywEk3scAxTdqpkCYalo7lwzZhcI+mOpDxedJEgMWSwv3UxEb+hjzK4zOAb9AyRWmNB/SeT9bbxOC/F4H9ydW09/EH77Wu7lT8l0tpV1FQxrG1Ftx+p4hZkXx7pq4vdZ+hE1qKz5shN23zVI= 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=gwYPXjc7; arc=none smtp.client-ip=209.85.214.196 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="gwYPXjc7" Received: by mail-pl1-f196.google.com with SMTP id d9443c01a7336-2a0833b5aeeso133465185ad.1 for ; Tue, 30 Dec 2025 00:24:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767083044; x=1767687844; 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=VkbI+3IsRhcx6hKZzGBXpGmnt+yRxhw1HJp+AgA3hxo=; b=gwYPXjc7UsYyMUGvKQt1v4LuwZKL/ahQWTRddwPPJTbgxzZAwH7oZAhdRC4/2yqT7N YSGV6Nvce/uhthvJUNKInU1Pb20e8lihJli+vlDKP0INrkLHLiXOKnxyp5kOnTRjlkjY Sko2Fgkp1qsn0PMgFk+Ul6gFvDrSyvhUjm534cw+rn2ocpz3htOO/9KYosI49K8C1d7O UbKXch7zuuPQIyEqmn4L3jisr3Mqfud01LTHL871m13FLswISJ3qtZdkFyl+IgnSZ0ru mQXOn6bodIpJZTkQdz4gV+0q5tU4UwnMsN//9RNARFpGowFF+WV7vDM6rpYD4CFXtHrd tKjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767083044; x=1767687844; 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=VkbI+3IsRhcx6hKZzGBXpGmnt+yRxhw1HJp+AgA3hxo=; b=qlUmO+wH1yhKSlEn8LbZNtCdbYv4Z45FGGq3GcUX6AORyOpYdLM7ftpKlqZbBvQDov PgsP3LK0ZZQv9g0cOCDW+v3nVFg8UYmpqsp+mBJMKAOjlKmROXzdaUKycRomj2RRc9rS ZudSSq8wBEOLqtQA80ZKuQuitlPKfOWFPZcTaYp16n7mLtkYNaJrbeC2jxUqX+nlCn3u 9wzn5bg4Au9cB+iAcHbC9qROO1BxfXMXd8DV6BjfoOeys3JPvsPVAqkxHe0qaD1cfIeO AxEkQfMrYvOAm5aBnp6vPuZlWCixJxX8+PxQbqSSwsVgEwJbtawluE9zojh8nrY8DmUD ucJg== X-Forwarded-Encrypted: i=1; AJvYcCWEzgU7VQpEAT97JuQMrNIgfA9ll/IuDPunLWOCohaX7e0Y7SbNSJC65j1Dbp24X1KwHvTUnB0tF1QULBA=@vger.kernel.org X-Gm-Message-State: AOJu0Yx1kXFsvRdQDdOBUGRQ0WbA8cPb8ruIYGbGtIq75Gov8Q9JdHIg BZtiyW2XHRNgQIiHyo3LXdV8nmnAorlxSOege+tO8P0Qe/836aENFZx+ X-Gm-Gg: AY/fxX6o2nMThZ7UtR79DjUl1wJpiI7L2scXgBVmgPUI/d1APEtG+N1iTHBJdMSOm3Y CVU1YPN/gPlGK1OeXeVsoWeATLtzeZdnP15OLEF7KSQKTCM3WINLStTlWyrqgwnBqS+iRMLk1Hp 9zTcfJsLKnlWv3VnRcH82V9CbgV2GJ5/oXyb9JJcMJSQknIsJdH3VII9GP8QeRT/7xh8HVKFGIM hETVSwZx7BGTDZkolVNyrsAV95D2fWDYXzsXkytK1D5m4RgKoXXHUP7WmR4KQESBzEHjzhgs3yD iQI5RJRvthDDY6rGlEdqgeoR8jFmpDKkyXJWjPn7SXJFZ82SmxKnzBSF9YEWohLCjAORntLln5G a1BcD62/jTZhMbb7pIhkNlfHl+MN9/LZGP9mgb9oeitXHFZMh7Kw5txpYecudFvdiStp4pCTegh GIduHAQHThxzzOTqXpFKuvc8OYMjcQcP5fX8368wOLYHE= X-Google-Smtp-Source: AGHT+IEpXx+1/9xAccF3LMXuAdIjDRce7eKrzDvVsd1Ni161trcdyhWaIN+5RBXPKj86BP3Q5hI8ew== X-Received: by 2002:a17:902:d507:b0:2a0:b06d:1585 with SMTP id d9443c01a7336-2a2f2836801mr361122605ad.34.1767083043885; Tue, 30 Dec 2025 00:24:03 -0800 (PST) Received: from MRSPARKLE.localdomain ([150.228.155.85]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2a2f3d76ceesm296667165ad.91.2025.12.30.00.23.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Dec 2025 00:24:03 -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 v5 2/7] dt-bindings: leds: Add virtual LED class bindings Date: Tue, 30 Dec 2025 21:23:15 +1300 Message-ID: <20251230082336.3308403-3-professorjonny98@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251230082336.3308403-1-professorjonny98@gmail.com> References: <20251230082336.3308403-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 class of led devices. for representation of virtual LEDs that combine multiple physical monochrom= atic LEDs into a group. Usefull for representing complex system states without complex userspace sc= ripting Key binding properties: - priority: Arbitration priority (0-2147483647, higher wins) - led-mode: Operating mode (multicolor or standard/fixed-color) - leds: Phandle array to physical LED devices - mc-channel-multipliers: Per-channel brightness multipliers Channel ordering is deterministic, sorted by ascending LED_COLOR_ID value. The multi_index sysfs attribute allows runtime verification. Co-developed-by: Radoslav Tsvetkov Signed-off-by: Radoslav Tsvetkov Signed-off-by: Jonathan Brophy --- .../leds/leds-class-virtualcolor.yaml | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-class-virtu= alcolor.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..4a3721455648 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-class-virtualcolor.yaml @@ -0,0 +1,197 @@ +# 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: Virtual LED class device with priority-based arbitration + +maintainers: + - Jonathan Brophy + +description: | + Represents a single virtual LED that combines one or more physical monoc= hromatic + LEDs. Multiple virtual LEDs can share the same physical LEDs, with prior= ity-based + arbitration determining which virtual LED's state is displayed. + + The driver implements winner-takes-all arbitration: + - Only virtual LEDs with brightness > 0 participate in arbitration + - Highest priority wins (ties broken by sequence number - most recent wi= ns) + - Winner controls ALL physical LEDs + - Physical LEDs not used by winner are turned off + + Two operating modes are supported: + + 1. Multicolor mode (default): + - Full multicolor LED ABI support + - Exposes multi_intensity, multi_index, multi_multipliers in sysfs + - Per-channel intensity control (0-255) + - Channel multipliers for color temperature adjustment + - Master brightness scales all channels proportionally + + 2. Standard mode: + - Fixed color ratios via mc-channel-multipliers + - Only brightness control available (no intensity changes) + - Useful for fixed-color LEDs (e.g., warm white, amber) + + Sysfs interface (multicolor mode): + - /sys/class/leds//brightness - Master brightness (0-max_brightness) + - /sys/class/leds//mc/multi_intensity - Per-channel intensities (sp= ace-separated) + - /sys/class/leds//mc/multi_index - Color IDs per channel (read-onl= y) + - /sys/class/leds//mc/multi_multipliers - Channel multipliers (read= -only) + +properties: + $nodename: + pattern: "^virtual-led(@[0-9a-f])?$" + + reg: + maxItems: 1 + description: | + Unique index of this virtual LED within the controller. Used for nod= e addressing. + + function: + description: | + LED function identifier. recommended to use: LED_FUNCTION_VIRTUAL_ST= ATUS, + See include/dt-bindings/leds/common.h + + priority: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + minimum: 0 + maximum: 2147483647 + description: | + Arbitration priority for this virtual LED (signed 32-bit integer). + When multiple virtual LEDs sharing physical LEDs are active (brightn= ess > 0), + only the highest-priority LED's state is displayed. + + Tie-breaking: If priorities are equal, the most recently updated vir= tual LED wins. + + Suggested priority ranges: + 0-99: Normal operation indicators + 100-499: System state indicators (boot, shutdown) + 500-999: Warning/error indicators + 1000+: Critical alerts and emergency overrides + + led-mode: + $ref: /schemas/types.yaml#/definitions/string + enum: [multicolor, standard] + default: multicolor + description: | + Operating mode for this virtual LED: + + - "multicolor": (default) Full multicolor ABI with dynamic intensity= control + * Exposes multi_intensity sysfs attribute for per-channel control + * Channels can be adjusted independently at runtime + * Suitable for RGB LEDs, color-changing indicators + + - "standard": Fixed color ratios, brightness-only control + * Channel intensities fixed by mc-channel-multipliers + * Only brightness sysfs attribute available (no multi_intensity) + * Suitable for warm white, amber, or other fixed-color LEDs + + leds: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 255 + description: | + Array of phandles to physical LED devices that compose this virtual = LED. + LEDs are automatically grouped by their 'color' property into channe= ls. + + Channel ordering: Channels are ordered by ascending LED_COLOR_ID val= ue. + Only colors present in the LED list are included (no sparse indices). + + Color ID values (from include/dt-bindings/leds/common.h): + LED_COLOR_ID_WHITE =3D 0 + LED_COLOR_ID_RED =3D 1 + LED_COLOR_ID_GREEN =3D 2 + LED_COLOR_ID_BLUE =3D 3 + LED_COLOR_ID_AMBER =3D 4 + LED_COLOR_ID_VIOLET =3D 5 + LED_COLOR_ID_YELLOW =3D 6 + LED_COLOR_ID_IR =3D 7 + ... (see header for complete list) + + The /sys/class/leds//mc/multi_index file reports the color ID f= or + each channel, allowing userspace to verify the ordering. + + Supported LED types: + - GPIO LEDs (gpio-leds compatible) + - PWM LEDs (pwm-leds compatible) + - I2C/SPI LED controllers (any with brightness_set or brightness_set= _blocking) + + Example 1 - RGB LED: + leds =3D <&led_red>, <&led_green>, <&led_blue>; + Results in 3 channels: [0]=3Dred (ID 1), [1]=3Dgreen (ID 2), [2]= =3Dblue (ID 3) + + Example 2 - RGBW LED: + leds =3D <&led_red>, <&led_green>, <&led_blue>, <&led_white>; + Results in 4 channels: [0]=3Dwhite (ID 0), [1]=3Dred (ID 1), [2]= =3Dgreen (ID 2), [3]=3Dblue (ID 3) + Note: White comes first because LED_COLOR_ID_WHITE =3D 0 + + Example 3 - Non-contiguous IDs: + leds =3D <&led_amber>, <&led_red>; + Results in 2 channels: [0]=3Dred (ID 1), [1]=3Damber (ID 4) + + Userspace verification: + $ cat /sys/class/leds/status:multi/mc/multi_index + 1 2 3 + # Confirms: [0]=3Dred, [1]=3Dgreen, [2]=3Dblue + + mc-channel-multipliers: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 255 + description: | + Per-channel brightness multipliers (0-255) for color temperature adj= ustment + and normalization. Array must have one entry per channel. + + Channel ordering: Array indices must match the channel order, which = is + determined by ascending LED_COLOR_ID value. Only colors present in t= he + 'leds' property are included. + + For predictable DT configuration, list multipliers in ascending colo= r ID order. + The /sys/class/leds//mc/multi_index file can verify the orderin= g at runtime. + + In multicolor mode: + - Scales the intensity value before applying brightness + - Formula: final =3D (intensity * multiplier / 255) * brightness /= max_brightness + - Useful for: Color temperature control, vendor normalization, pow= er limiting + - Default: 255 (no scaling) for all channels if omitted + + In standard mode: + - Defines the FIXED color ratios (intensity changes not allowed) + - Formula: final =3D multiplier * brightness / max_brightness + - Useful for: Fixed-color LEDs (warm white, amber) + - REQUIRED in standard mode + + Example 1 - RGB with equal scaling: + leds =3D <&red>, <&green>, <&blue>; + mc-channel-multipliers =3D <255 255 255>; + # Channels: [0]=3Dred, [1]=3Dgreen, [2]=3Dblue - all at full scale + + Example 2 - RGBW warm white (standard mode): + leds =3D <&red>, <&green>, <&blue>, <&white>; + mc-channel-multipliers =3D <180 255 200 100>; + # Channels: [0]=3Dwhite:180, [1]=3Dred:255, [2]=3Dgreen:200, [3]= =3Dblue:100 + # Note: White (ID=3D0) comes first, then red (ID=3D1), green (ID= =3D2), blue (ID=3D3) + + Example 3 - Color temperature adjustment: + leds =3D <&red>, <&green>, <&blue>; + mc-channel-multipliers =3D <255 180 100>; + # Creates warm white by reducing green/blue relative to red + +required: + - reg + - leds + +allOf: + - $ref: common.yaml# + - if: + properties: + led-mode: + const: standard + then: + required: + - mc-channel-multipliers + +unevaluatedProperties: false -- 2.43.0