LEDs
Triggers
Triggers are typically locked to "pattern" by feedbackd's udev rule |
There are two types of triggers: simple and complex.[1] Simple triggers are provided by other subsystems. Complex triggers need to be enabled in kernel configs. For a list of complex triggers, see LEDs#List of kernel LED triggers.
Both trigger types are merged together in the trigger file. To see the available triggers, cat the trigger file, e.g. cat /sys/class/leds/tm2-touchkey/trigger
. The active trigger is shown in brackets.
[none] usb-gadget usb-host rfkill-any rfkill-none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer heartbeat cpu cpu0 cpu1 cpu2 cpu3 default-on panic mmc1 mmc0 rfkill0 rt5033-battery-charging-or-full rt5033-battery-charging rt5033-battery-full rt5033-battery-charging-blink-full-solid bluetooth-power hci0-power rfkill1 phy0rx phy0tx phy0assoc phy0radio rfkill2
To assign a trigger, echo the trigger name to the trigger file, e.g. echo heartbeat | sudo tee /sys/class/leds/tm2-touchkey/trigger
When rebooting, the trigger is lost again. To make it permanent, it needs to be set by an udev rule. If you're not sure about the udev matching and assignment keys, you can look them up by e.g. udevadm info --attribute-walk /sys/class/leds/tm2-touchkey
. To set up the udev rule, do something like:
sudo vi /etc/udev/rules.d/30-tm2-touchkey-leds.rules
(new file)
ACTION=="add", SUBSYSTEM=="leds", KERNEL=="tm2-touchkey", ATTR{trigger}="heartbeat"
Most of the complex triggers are tristate in the kernel configs, they can be compiled as a module. The configs can be checked by e.g. cat /boot/config | grep LEDS*_TRIGGER
. (The asterisk after the S includes LED trigger that are missing the S like LED_TRIGGER_PHY.)
If a trigger is set as a module, let's say for example CONFIG_LEDS_TRIGGER_HEARTBEAT=m
, the module needs to be loaded by:
# modprobe ledtrig-heartbeat
before it becomes available in the trigger list. To use it permanently by an udev rule like described above, the module needs to be added to /etc/modules
.
List of kernel LED triggers
For more information on a specific trigger, see the referenced links.
- drivers/leds/trigger/Kconfig [2]
- CONFIG_LEDS_TRIGGER_TIMER [3]
- CONFIG_LEDS_TRIGGER_ONESHOT [4]
- CONFIG_LEDS_TRIGGER_DISK [5]
- CONFIG_LEDS_TRIGGER_MTD [6]
- CONFIG_LEDS_TRIGGER_HEARTBEAT [7]
- CONFIG_LEDS_TRIGGER_BACKLIGHT [8]
- CONFIG_LEDS_TRIGGER_CPU [9]
- CONFIG_LEDS_TRIGGER_ACTIVITY [10]
- CONFIG_LEDS_TRIGGER_GPIO [11]
- CONFIG_LEDS_TRIGGER_DEFAULT_ON [12]
- CONFIG_LEDS_TRIGGER_TRANSIENT [13]
- CONFIG_LEDS_TRIGGER_CAMERA [14]
- CONFIG_LEDS_TRIGGER_PANIC [15]
- CONFIG_LEDS_TRIGGER_NETDEV [16]
- CONFIG_LEDS_TRIGGER_PATTERN [17]
- CONFIG_LEDS_TRIGGER_AUDIO [18]
- CONFIG_LEDS_TRIGGER_TTY [19]
ULED driver
The kernel documentation mentions an ULED driver.[26] Including this into a userspace program written in C creates a node in /dev/uleds
, which can be accessed by the program. There is an example at tools/leds/uledmon.c.[27]
Access via sysfs
LEDs are available in /sys/class/leds
. They can be turned on/off by echoing a value to brightness. However, root access is required. The range of brightness can be checked by e.g. cat /sys/class/leds/tm2-touchkey/max_brightness
. In the example tm2-touchkey LED, the max_brightnes is 1, so for this LED it's just on or off. Changing the brightness of a LED with sudo can be done like e.g.
echo 1 | sudo tee /sys/class/leds/tm2-touchkey/brightness
or:
sudo /bin/sh -c 'echo 1 > /sys/class/leds/tm2-touchkey/brightness'
visudo
To use the commands in shell scripts without typing the password, the command(s) can be added to the sudoers file, e.g.:
sudo visudo
add:
## Allow user to access tm2-touchkey leds withouth password user ALL=NOPASSWD: /usr/bin/tee /sys/class/leds/tm2-touchkey/brightness
The command echo 1 | sudo tee /sys/class/leds/tm2-touchkey/brightness
now works without password prompt.
Changing permissions in sysfs
Alternatively, to change the LED brightness without sudo, permissions in sysfs can be changed. This seems to be rather unconventional. A project modifying game controllers suggests the follwing approach to change permission on all LEDs[28]:
# Assign any new nodes in the 'leds' subsystem (nodes in /sys/class/leds) to the group 'leds' to write without root # Create a new group 'leds' before this will do anything! SUBSYSTEM=="leds", ACTION=="add", RUN+="/bin/chgrp -R leds /sys%p", RUN+="/bin/chmod -R g=u /sys%p" SUBSYSTEM=="leds", ACTION=="change", ENV{TRIGGER}!="none", RUN+="/bin/chgrp -R leds /sys%p", RUN+="/bin/chmod -R g=u /sys%p"
This changes the owning group from root
to leds
and transcribes the permission from user (root) to group (leds). It needs to be done on action "add" as well as on action "change" because when the kernel performes changes, the group permissions would be overwritten to root
again.
Based on this approach, for the tm2-tochkey leds udev rules were implemented to file /lib/udev/rules.d/20-tm2-touchkey-leds.rules after stable release v21.06 that look like this:
# allow users in group "input" to control the tm2-touchkey leds ACTION=="add", SUBSYSTEM=="leds", KERNEL=="tm2-touchkey", RUN+="/bin/chgrp -R input /sys%p", RUN+="/bin/chmod -R g=u /sys%p" ACTION=="change", SUBSYSTEM=="leds", KERNEL=="tm2-touchkey", ENV{TRIGGER}!="none", RUN+="/bin/chgrp -R input /sys%p", RUN+="/bin/chmod -R g=u /sys%p"
This permission change is limited to tm2-touchkey
. And the permissions are changed to group input
(postmarketOS users are usually already member of group input
). Additionally, the order of the udev rule keys were put in a different order (has no technical effect).
It's not fully clear if ENV{TRIGGER}!="none"
in the last line is required. A comment on unix.stackexchange.com says it would be needed for kernel older than 4.9.[29]
However, with these udev rules in place, an unpriviliged user that's member of the group input
can now turn on the tm2-touchkey leds by simply echo 1 > /sys/class/leds/tm2-touchkey/brightness
without sudo. That's especially helpful for usage in shell scripts.
Sync with backlight
References
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/leds/leds-class.rst
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/leds/trigger/Kconfig
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_TIMER.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_ONESHOT.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_DISK.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_MTD.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_HEARTBEAT.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_BACKLIGHT.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_CPU.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_ACTIVITY.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_GPIO.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_DEFAULT_ON.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_TRANSIENT.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_CAMERA.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_PANIC.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_NETDEV.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_PATTERN.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_AUDIO.html
- ↑ https://cateee.net/lkddb/web-lkddb/LEDS_TRIGGER_TTY.html
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/core/Kconfig
- ↑ https://cateee.net/lkddb/web-lkddb/USB_LEDS_TRIGGER_USBPORT.html
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/phy/Kconfig
- ↑ https://cateee.net/lkddb/web-lkddb/LED_TRIGGER_PHY.html
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/netfilter/Kconfig
- ↑ https://cateee.net/lkddb/web-lkddb/NETFILTER_XT_TARGET_LED.html
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/leds/uleds.rst.
- ↑ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/leds/uledmon.c
- ↑ https://approxeng.github.io/approxeng.input/sys.html#version-2-6-1-2-6-2
- ↑ https://unix.stackexchange.com/questions/20125/how-can-i-change-the-permissions-in-sys-to-alter-the-state-of-a-led-light-using/202870#202870
See also
Internal pages