-
Notifications
You must be signed in to change notification settings - Fork 0
Home
This wiki aims to help on defining Linux kernel's multi color element LED support.
Following interfaces would need to be defined:
- Kernel-userspace interface for applications to use
- Kernel-devicetree interfaces for device manufacturers to use
- Kernel-driver interfaces for device driver writers to use
It has been agreed to proceed to first define kernel-userspace interface and once that is done then work on internals of kernel and devicetree solution.
Pavel Machek: https://www.spinics.net/lists/linux-leds/msg11024.html
Requirements for RGB LED interface:
1) Userspace should be able to set the white color
2) Userspace should be able to arbitrary color from well known list
and it should approximately match what would CRT, LCD or OLED monitor
display. Color list is for example here:
https://www.rapidtables.com/web/color/RGB_Color.html
2a) LEDs probably slightly change color as they age. That's out of
scope, unless the variation is much greater than on monitors.
3a) Manufacturing differences cause small color variation. Again,
that's out of scope, unless the variation is much greater than on
monitors.
Nice to have features:
3) Full range of available colors/intensities should be available to
userspace
4) Interface should work well with existing triggers
5) It would be nice if userland knew how many lumens are produced at
each wavelength for each setting (again, minus aging and manufacturing
variations).
6) Complexity of math in kernel should be low, and preferably it
should be integer or fixed point
Problems:
a) RGB LEDs are usually not balanced. Setting 100% PWM on
red/green/blue channels will result in nothing close to white
light. In fact, to get white light on N900, blue and green channel's
PWM needs to be set pretty low, as in 5%.
b) LED class does not define any relation between "brightness" in
sysfs and ammount of light in lumens. Some drivers use close to linear
relation, some use exponential relation. Human eyes percieve logarithm
of lumens. RGB color model uses even more complex function.
https://en.wikipedia.org/wiki/Gamma_correction
#Windows, Mac, sRGB and TV/video standard gammas
https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation
c) Except for white LEDs, LEDs are basically sources of single
wavelength of light, while CRTs and LCDs produce broader
spectrums.
d) RG, RGBW and probably other LED combinations exist.
e) Not all "red" LEDs will produce same wavelength. Similar
differences will exist for other colors.
f) We have existing RGB LEDs represented as three separate
monochromatic LEDs in sysfs.
LEDs come with multiple different models. While most commonly you might have single color led, red-green-blue leds are somewhat common with two-color leds perhaps coming as a next majority.
When looking what kind of LED color element combinaties there are here is an example list from digikey:
- red, green, blue
- red, green, blue, amber
- red, green, blue, white
- red, green, blue, white - cool
- red, green, blue, white - neutral
- red, green, blue, white - warm
- red, orange
- purple, ultraviolet
- amber, blue
- amber, blue, cyan, green, red, violet, white - cool
- amber, blue, green
- amber, green, blue
- and then lots of single special colors
LEDs come with multiple variant luminances for each color and they are non-balanced.
With GPIO hardware interface each color element within LED is on/off. Hardware engineer tunes up the LEDs with an example resistors in the hardware design to get expected colors for particular design.
In example with red-green LED one might get:
- red=0, green=0 -> "black" or rather LED is not lit (off)
- red=0, green=1 -> "green"
- red=1, green=0 -> "red"
- red=1, green=1 -> "orange"
With PWM controller controlled LEDs hardware designed has decided to use processor's integrated generic PWM controller. With PWM controller one sets duty cycle (on/off durations) for separate LED color elements. With fast enough refresh rate human eye is not able to see fast blinking instead eye notices change of color intensity changing for different color elements within a LED. Depending on LED model actual color perceived by human eye is highly different.
There are several brands and models and techniques how special purpose LED controllers work.
Examples in discussion has been:
- Texas Instruments LP503x series (LP5036/30/24/18)
- Motorola CPCAP
- Custom PMIC with LED support
- https://www.spinics.net/lists/linux-leds/msg10971.html
In embedded systems it is possible for actual CPU's to be slow, system load to be high, or other high priority activities happening so that userspace<->kernel operations to control LED color can take time.
If color change is not "atomic" transitional color artifacts can be perceived.
https://www.spinics.net/lists/linux-leds/msg10821.html
Idea of usage of ICC profiles to defining LED behavior within user space and then setting converted color to sysfs interface:
If one wants to have dimmed led one need to adjust red,green and blue values instead of changing brightness with "brightness" as trigger like heartbeat would then set it to 0 and 255 depending on state.
More logical approach would be to set color and brightness and then triggering would respect the brightness and use that for ON state. Perhaps triggering should not change visible value in sysfs at all and adjust only internal brightness value used in calculations.
Date: Sat, 19 Jan 2019 21:11:01 +0200
Current set of concepts:
- brightness-model: hardware, onoff, linear
- could be extended in future with other modes like hsv if wanted
- From user space point-of-view atomic changes for color elements and brightness.
Sysfs interfaces:
- brightness_model: Change of brightness model on the fly. Similar if as trigger selection.
- color: configuring all color element values as array of values with support for optional brightness entry as last value.
- color_names: information for user space about color element values in 'color' array.
- max_color: information for user space about maximum values for entries in 'color' array.
From https://github.com/vesajaaskelainen/linux/commit/627f38bb78cebc694b8e6d735fb088c87925435d:
From user space multi color element LEDs can be configured using sysfs entries:
- brightness_model : current brightness model.
<brightness model option> ...
with "[" and "]" around selected mode.
- color : current multi color element values with encoding:
<color element value> ... [<brightness value]
All color element values can be changed at once and optionally
to set new brigthness value.
Reading the sysfs entry provides current settings in use
without brightness value.
- color_names : names for multi color elements with encoding:
<color element name> ...
Lists all color element names.
- max_color : maximul values for multi color elements with encoding:
<color element value> ...
Lists all color element maximum values.
Multi color element LEDs support also triggers as thru control of brightness.
Example usage:
$ cd /sys/class/leds/status
$ ls
brightness brightness_model color color_names device max_brightness max_color power subsystem trigger uevent
$ cat brightness_model
hardware [onoff] linear
$ cat color_names
red green blue
$ cat max_color
255 255 255
$ cat brightness
0
# Setting up color to not so bright purple with brightness set to 255
$ echo "32 0 32 255" > color
# Setting up color to a bit brighter purple with brightness
$ echo "128 0 128 255" > color
# Activate heartbeat blinking
$ echo "heartbeat" > trigger
# Now led is blinking with purple color
# Change color to green
$ echo "0 255 0" > color
# Now led is blinking with green color
Date: Fri, 8 Feb 2019 14:30:33 +0000 (08:30 -0600)
- http://git.ti.com/gitweb/?p=ti-analog-linux-kernel/dmurphy-analog.git;a=blob;f=Documentation/ABI/testing/sysfs-class-led-multicolor;h=45629199791285200e3775fc0b4dde1dfebb130f;hb=ce08183aa24edc0d883550339eef93fd72b4ac45
- http://git.ti.com/gitweb/?p=ti-analog-linux-kernel/dmurphy-analog.git;a=blob;f=Documentation/leds/leds-class-multicolor.txt;h=357f045a826aac71d65704891c18e7fb31e5cb9b;hb=refs/heads/multicolor_class
What: /sys/class/leds/<led>/colors/sync_enable
Date: January 2019
KernelVersion: 5.0
Contact: Dan Murphy <dmurphy@ti.com>
Description: read/write
Writing a 1 to this file will enable the synchronization of all
the defined color LEDs within the LED node. Brightness values
for each LED will be stored and written when sync is set to 1.
Writing a 0 to this file will disable syncing and allow
individual control of the LEDs brightness settings.
What: /sys/class/leds/<led>/colors/sync
Date: January 2019
KernelVersion: 5.0
Contact: Dan Murphy <dmurphy@ti.com>
Description: write only
Writing a 1 to this file while sync_enable is set to 1 will
write the current brightness values to all defined LEDs within
the LED node. All LEDs defined will be configured based
on the brightness that has been requested.
If sync_enable is set to 0 then writing a 1 to sync has no
affect on the LEDs.
What: /sys/class/leds/<led>/colors/<led_color>/brightness
Date: January 2019
KernelVersion: 5.0
Contact: Dan Murphy <dmurphy@ti.com>
Description: read/write
The led_color directory is dynamically created based on the
colors defined by the registrar of the class.
The led_color can be but not limited to red, green, blue,
white, amber, yellow and violet. Drivers can also declare a
LED color for presentation. There is one directory per color
presented. The brightness file is created under each
led_color directory and controls the individual LED color
setting.
If sync is enabled then writing the brightness value of the LED
is deferred until a 1 is written to
/sys/class/leds/<led>/color/sync. If syncing is
disabled then the LED brightness value will be written
immediately to the LED driver.
The value of the color is from 0 to
/sys/class/leds/<led>/colors/<led_color>/max_brightness.
What: /sys/class/leds/<led>/colors/<led_color>/max_brightness
Date: January 2019
KernelVersion: 5.0
Contact: Dan Murphy <dmurphy@ti.com>
Description: read only
Maximum brightness level for the LED color, default is
255 (LED_FULL).
If the LED does not support different brightness levels, this
should be 1.
What: /sys/class/leds/<led>/brightness_model
Date: January 2019
KernelVersion: 5.0
Contact: Jacek Anaszewski <j.anaszewski@samsung.com>
Description: read/write
Example usage:
$ cd /sys/class/leds/<led>
# Without sychronization mode enabled changes are instant:
# Changes LED color to red:
$ echo 255 > colors/red/brightness
# Changes LED color to orangish
$ echo 255 > colors/green/brightness
# Enabling sychronization mode:
$ echo 1 > colors/sync_enable
# Change LED color "atomically" to blue:
$ echo 0 > colors/red/brightness
$ echo 0 > colors/green/brightness
$ echo 255 > colors/blue/brightness
$ echo 1 > colors/sync
# Change LED color "atomically" to green:
$ echo 255 > colors/green/brightness
$ echo 0 > colors/blue/brightness
$ echo 1 > colors/sync
# Disabling sychronization mode:
$ echo 0 > colors/sync_enable