Reporting Backlight Bugs
If you have an issue where backlight stops working after suspend or hibernation, please see their respective debugging article. Otherwise, please continue with the below mentioned information.
There are a lot of different issues with backlight control which can be generally put into these classes:
- Hotkeys change the brightness, but no OSD feedback and the brightness applet does not work.
- There is nothing that the kernel can do to resolve this situation. Since there is no vendor specific control mechanism and the generic ACPI interface is not defined (or not defined correctly), there is no way Linux can interact. In those cases the hotkeys are directly wired to the backlight control and no events are passed on to the OS.
- Backlight control works through the brightness applet but not via hotkeys.
This is most likely a hotkey issue which might be further debugged looking at debugging hotkeys.
Backlight control does not work, but there are entries in /sys/class/backlight.
- This may require the ACPI backlight driver to not take control so that a vendor specific driver will have a chance to register (see below).
Backlight control does not work and there are no entries in /sys/class/backlight.
- Neither the ACPI backlight driver nor any vendor specific driver were able to find a valid interface. Either requires a new vendor driver (which is unlikely) or the ACPI BIOS is broken (see below). Updates to the ACPI BIOS are rare as well but in some cases it is possible to work with upstream to extend the Linux side to handle some of that brokenness.
When filing bugs about backlight control, please classify the issue into one of the classes above. Also describe whether there was a previous kernel that worked, or whether this was never the case. Also be very specific in the bug title about the laptop vendor and model. Backlight control is very specific to hardware and a bug titled "backlight control does not work" just causes other people to use that bug even if they have a completely different laptop. It is much simpler to look into issues separately than to mix things.
- Also, depending on the class of issues, provide additional information about the kernel interface. Does it exist, do any values change when writing into the control files? Is there any effect?
- If the kernel interface does not work, add the dump of the ACPI BIOS as described below.
Information to provide in your bug report
For all of the following steps, boot while holding the Shift key and remove all non-default kernel parameters.
Please file backlight bugs by executing at a terminal:
ubuntu-bug linux
If it turns out to be a non-linux package issue, it can be changed to the appropriate package.Install the prerequisites by executing at a terminal:
sudo apt-get install -y acpidump fwts dmidecode iasl
Execute at a terminal:
ls /sys/class/backlight > "ls sys-class-backlight"
- Attach uncompressed, untarred, and uncombined to your report.
Execute at a terminal:
grep -r . /proc/acpi > "grep -r . proc-acpi"
- Attach uncompressed, untarred, and uncombined to your report.
Execute each in the order shown as each command creates files that the next command relies on to work:
sudo acpidump -o acpidump.txt acpixtract acpidump.txt iasl -d DSDT.dat
- Attach all uncompressed, untarred, and uncombined to your report.
Execute at a terminal:
sudo fwts > fwts
- Attach uncompressed, untarred, and uncombined to your report.
1. Execute at a terminal:
sudo fwts method > "fwts method"
- Attach uncompressed, untarred, and uncombined to your report.
Execute at a terminal:
sudo dmidecode > dmidecode
- Attach uncompressed, untarred, and uncombined to your report.
Boot with only the kernel parameter:
acpi_backlight=vendor
Execute at a terminal:
ls /sys/class/backlight > "acpi_backlight=vendor ls sys-class-backlight"
Attach uncompressed, untarred, and uncombined to your report, and then execute at a terminal:
sudo su ls -la /sys/class/backlight/intel_backlight/ > "acpi_backlight=vendor ls -la sys-class-backlight-intel_backlight"
Attach uncompressed, untarred, and uncombined to your report, and then execute at a terminal:
echo 8 > /sys/class/backlight/intel_backlight/brightness
- Please comment on if the brightness changes.
Boot with only the kernel parameter:
video.use_bios_initial_backlight=0
and make a comment on if you can now alter the backlight with hotkeys or a brightness applet.Boot with only the kernel parameter:
acpi_osi=
and make a comment on if you can now alter the backlight with hotkeys or a brightness applet.Boot with only the kernel parameter:
video.use_native_backlight=1
and make a comment on if you can now alter the backlight with hotkeys or a brightness applet.If your backlight hotkeys are Fn+Left and Fn+Right, add kernel parameter
atkbd.softraw=0
Then, switch to a console, e.g. Ctrl+Alt+F1, login by root account and execute:
showkey -s
Then, press Fn+Left and Fn+Right key to check the code that shows up on screen. Post the results to the report. For example:
Fn+Left:
0xe0 0x4c 0xe0 0xcc
Fn+Right:
0xe0 0x54 0xe0 0xd4For Lenovo computers, boot with only the kernel parameters:
thinkpad-acpi.brightness_enable=1 acpi_backlight=vendor
and comment on if brightness may be changed via hotkeys and/or brightness applet.For Lenovo computers, execute at a terminal:
lsmod | grep thinkpad_acpi > "lsmod | grep thinkpad_acpi"
- Attach uncompressed, untarred, and uncombined to your report.
Diagnostic Techniques
Disabling the ACPI backlight driver
In some cases the ACPI BIOS provides the interfaces required to control the backlight through the generic ACPI interface, but the actual methods are not implemented. So the ACPI driver registers with the hardware and prevents any laptop specific drivers from doing so. In those cases it is possible to prevent the ACPI backlight driver from starting by adding the following line to the kernel boot parameters:
acpi_backlight=vendor
Unfortunately the thinkpad-acpi driver behaves differently, as it does not act on the ACPI driver being active or not, but on the ACPI methods being defined. Thus forcing the vendor specific driver to activate requires an additional:
thinkpad-acpi.brightness_enable=1
You can check to see if your system uses the thinkpad-acpi driver by using the following command:
lsmod | grep thinkpad_acpi
Disabling ACPI brightness adjustments
If ACPI can control the brightness but the control is somehow incorrect, you can disable ACPI brightness changes with boot parameter acpi.brightness_switch_enabled=0 (also accessible in /sys/module/video/parameters/brightness_switch_enabled). Note that this does not release ACPI control as acpi_backlight=vendor does (sometimes acpi=off is suggested but this completely turns off the ACPI subsystem). Changing this attribute merely suppresses events from the video device to be forwarded and therefore to be ignored. Writing values into the kernel interfaces should still work.
Checking the kernel interfaces
To decide whether the missing brightness control is a hotkey, a X driver or a kernel issue, testing the kernel interfaces will give additional information.
The /proc/acpi/video interface
This actually is deprecated and would also only be working if the ACPI backlight driver is active. It will be described only for completeness. The ACPI backlight driver also exposes itself through the new sysfs interface.
/proc/acpi/video/ | +- <GFX card> | | | +- <Display Device> | | | | | +- EDID | | +- brightness | | +- state | | +- info | +- ... +- ...
Each discovered graphics card will have one entry and within that each defined output device will have its set of values. The brightness variable contains either "<not supported>" or the possible brightness values and the currently set value. This could, for example, look like this:
#> grep -r . /proc/acpi/video/GFX0/DD04/ proc/acpi/video/GFX0/DD04/EDID:<not supported> /proc/acpi/video/GFX0/DD04/brightness:levels: 20 28 36 44 52 60 68 76 84 92 100 /proc/acpi/video/GFX0/DD04/brightness:current: 100 /proc/acpi/video/GFX0/DD04/state:state: 0x1d /proc/acpi/video/GFX0/DD04/state:query: 0x00 /proc/acpi/video/GFX0/DD04/info:device_id: 0x0410 /proc/acpi/video/GFX0/DD04/info:type: LCD /proc/acpi/video/GFX0/DD04/info:known by bios: yes
So in this case there are 11 possible percentage values which, when written into the brightness file, would change the brightness of the display. Currently it is set to full brightness.
Note that only those discrete percentage values are defined. Writing other values results in an error.
Also note that the effect may not be immediate. When testing this, the laptop I used would take a bit and then gradually fade to the destination brightness.
The /sys/class/backlight interface
Contrary to the ACPI interface in /proc, the sysfs interface has only entries when there is an output device that supports backlight control.
/sys/class/backlight/ | +- <output device with backlight control> | | | +- actual_brightness | +- bl_power | +- brightness | +- ... | +- max_brightness | +- ... +- ...
The file actual_brightness contains the currently set brightness level. Reading brightness results in the same number. In max_brightness is the maximum number allowed to be written into brightness. While the ACPI /proc interface uses percentage levels, the sysfs interface uses index numbers between 0 and the maximum brightness.
See the kernel documentation of sysfs class backlight interface for the definitive description of the attributes.
#> grep . /sys/class/backlight/acpi_video0/* /sys/class/backlight/acpi_video0/actual_brightness:10 /sys/class/backlight/acpi_video0/bl_power:0 /sys/class/backlight/acpi_video0/brightness:10 /sys/class/backlight/acpi_video0/max_brightness:10
Into the abyss: looking at the ACPI BIOS
Whenever the kernel interface does not work or is not present at all, it is time to put on the mining helmet and try to make sense of the information stored in the ACPI BIOS which can be obtained following this description. The next challenges will be to find the right section for the graphics device and the display devices defined there.
Finding the correct graphics device
The ACPI BIOS often contains not only the information for the graphics card used in the one laptop we are looking at, but has entries for every possible variation the vendor had in mind. So before further inspection, we need to find out which definition we have to look at.
If the video device is handled by the ACPI video driver and just the backlight interface is not working, the name of the used graphics device can be obtained by looking at the output of dmesg.
#> dmesg|grep 'ACPI: Video' [ 2.941100] ACPI: Video Device [GFX0] (multi-head: yes rom: no post: no)
So we know we need to look for GFX0 in the DSDT. But if the definition is bad enough to be not detected by the ACPI driver? In that case we might be successful through the backdoor. In other words from the info we got of the PCI bus.
#> lspci |grep VGA 00:02.0 VGA compatible controller: Intel Corporation Mobile 945GME Express Integrated Graphics Controller (rev 03)
So the graphics device is attached as PCI device 2 functional endpoint 0. Let's search for "_ADR.*00020000" in the disassembled DSDT:
Device (GFX0) { Name (_ADR, 0x00020000) ...
So this nicely matches the name we are expecting. If we don't know the name and maybe there are other devices (on another bus) with the same ID. Well there are a few methods that are required for a device to be considered as a video device. The ACPI spec (Appendix B.) requires two methods to be defined at the graphics device level. Actually only one, but there is (as so often room for interpretation). Linux used to require both but this was changed to be ok with one of them.
- _DOS
- (Display Output Switching) This method is required by the ACPI spec for supporting brightness control. This method allows control over how the BIOS handles events to switch the output display or what to do about the brightness when changing from AC to DC. Technically this is not really required for setting the brightness and some BIOS vendors "forgot" to implement this, even when supplying methods to set the brightness.
- _DOD
- (Display Output Devices) This returns a list of attributes of the output devices which are connected to a certain graphics device. This allows to enumerate the attached output devices and also gather some information. Strictly this is also not required to find the methods to control the backlight, but for completeness allows to check the type of the output as brightness control is only defined to LCD screens.
Essentially one of these two methods must be defined for the graphics device. Otherwise the ACPI driver will not detect it as a valid video device. In which case only the BIOS/laptop vendor can resolve this.
Verifying the methods to control the brightiness
Every output device has to define methods which allow interaction (defined in Appendix B.6 of the ACPI spec). The following methods are related to the brightness control:
- _BCL
- (Backlight Control Levels) This method is supposed to return a list of percentage values. The first two are supposed to be the brightness level on AC power and on battery. The remaining should be a list of supported levels (in ascending order might be sensible, but never count on it). This seems to be a field of generous interpretation by vendors. Some leave out the first two, some sort in reverse, some use index numbers instead of percentage values or a mix of all. The Linux ACPI driver tries hard to make something of what gets returned. But there are limits.
Method (_BCL, 0) { // List of supported brightness levels Return (Package(7){ 80, // level when machine has full power 50, // level when machine is on batteries // other supported levels 20, 40, 60, 80, 100 } }
- _BCM
- (Backlight Control Modify) Supposed to take a percentage value defined by _BCL and set the brightness accordingly. Again, one needs to "guess" whether the actual implementation uses a relative index number instead.
- _BCQ
- (Backlight Control Query) Gets the currently set brightness. This would need to be a value defined in the list returned by _BCL but, as one would make an educated guess, there is variation, too.
Reading the method definitions requires some knowledge about the ACPI AML language and some persistence on hunting down more or less complex implementations. Some are more obvious than others. There have been cases where percentage values got converted into index values and then (incorrectly) back on query.
Also often the values get stored into a register of the embedded controller which does not necessarily need to have any result on the brightness.