Brightness Sysfs Nodes in Linux Kernel
|FIgure 1 - Sysfs Nodes for Brightness|
- actual_brightness - implements _BQC
- brightness - implements _BCM, and also record current brightness level
- max_brightness - implements _BCL and converts it to number of levels
For example, the _BCL in this Thinkpad reports 16 brightness levels with Ubuntu 12.04, and therefore "cat max_brightness" returns 15. Current brightness can be read by executing "cat actual_brightness" or "cat brightness". In most cases, both max_brightness and brightness return the same value (this should not be surprising) - they are only different if something breaks in kernel or BIOS - such as _BQC does not change with _BCM.
To change brightness level, one writes a value to brightness, ranged from 0 to max_brightness. In this system, it is from 0 to 15. ACPI VGA driver will convert it to the actual value in _BCL and write to _BCM.
Hotkey Implementation in Ubuntu Linux
|Figure 2 - Overall Process for Brightness Hotkeys|
Figure 2 is an expansion of ACPI Brightness Control (2) - Hotkeys. It shows that many tasks are done even with a single hotkey press, and it also shows separation between OS and BIOS is clear - the clean interface makes hotkey development easy and that's exactly what ACPI is for. Let's add more details to OS level as it is in Figure 3.
|Figure 3 - Brightness and Desktop Daemon|
Ubuntu ships with gnome-setting-daemon (GSD) that listens to keycode events. ACPI VGA driver converts ACPI notification events to keycodes, and GSD changes brightness via sysfs nodes according. GSD is also responsible for reading brightness levels from sysfs nodes to show OSD for users and to create slider for changing brightness. It is also worthy noting that ACPI VGA driver can also calls _BCM to change brightness without interacting with GSD, but no OSD may be shown.
As GSD is designed to listen to keycode, System vendor may design BIOS to generate other none-standard ACPI events, such as WMI events, as long as there is a kernel driver to do the conversion; however, this is not a suggested.
PS. Please note keycodes are not the same as KBC's scancode.
Debugging Brightness (Hotkey) Failures
From Figure 3, it becomes obvious brightness hotkeys can fail for two primary reasons:
- BIOS does not generate events
- _BCM fails to change brightness
In Linux, it is easy to verify whether ACPI VGA events and keycodes are generated:
- Run "acpi_listen" to show ACPI standard events
- Run "sudo showkey" to show keycodes
One can trigger writes to _BCM as in "Brightness Sysfs Nodes in Linux Kernel", if brightness is changed but LCD panel is not, BIOS did not implement _BCM correctly (or graphics drivers do not respond requests from BIOS in some cases).