Backlight

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.

Debugging information to provide in your bug report

  • Please file backlight bugs by executing at the 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 the Terminal:
    sudo apt-get install -y acpidump fwts dmidecode iasl

  • Execute at a terminal each of the following in order, with default Ubuntu kernel parameters, and post the result of each command as a separate, non-compressed attachment to your report:
    • ls /sys/class/backlight > backlight

    • grep -r . /proc/acpi > acpi

    • sudo acpidump -o acpidump.txt

    • acpixtract acpidump.txt

      • Please note this must be done after the prior command, as it uses the newly created acpidump.txt, in order to produce the files to attach DSDT.dat, SSDT1.dat, SSDT2.dat, and SSDT3.dat.
    • iasl -d DSDT.dat

      • Please note this must be done after the prior command, as it uses the newly created DSDT.dat to create the file to attach DSDT.dsl.
    • sudo fwts > fwts

    • sudo fwts method > fwts_method

    • dmesg | grep 'ACPI: Video' > video

    • sudo dmidecode > dmidecode.log

    • cat /proc/version > version

Testing for a work around

  • Reboot with only the kernel parameter acpi_backlight=vendor :

    • Make a comment on if you can now alter the backlight with hotkeys or a brightness applet.
    • ls /sys/class/backlight > vendorbacklight

    • If you have the folder /sys/class/backlight/intel_backlight/ :
      • type sudo su , and then execute:

      • ls -la /sys/class/backlight/intel_backlight/ > lslabacklight

      • echo 8 > /sys/class/backlight/intel_backlight/brightness

        • Please comment on if the brightness changes.
  • Reboot with just 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.
  • If using a v3.13.x+ series kernel, reboot with just 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 to /boot/grub/menu.lst . Then, switch to any 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 0xd4

Intel HD Graphic Controllers

With an Intel HD Graphic Controller if passing kernel parameter acpi_backlight does not work, or it freezes and/or crashes, one may try adjusting which backlight interface is used by creating a new file in /usr/share/X11/xorg.conf.d/80-backlight.conf and paste into it the following code:

Section "Device"
    Identifier  "Intel Graphics"
    Driver      "intel"
    Option      "AccelMethod"     "sna"
    Option      "Backlight"       "intel_backlight" # use your backlight that works here
    BusID       "PCI:0:2:0"
EndSection

Thinkpads

  • Add just kernel parameters thinkpad-acpi.brightness_enable=1 acpi_backlight=vendor to /boot/grub/menu.lst . Execute:
    sudo update grub

    Restart, and comment on if brightness may be changed via hotkeys and/or brightness applet.

  • As well, execute the following and post results to your report:
    lsmod | grep thinkpad_acpi

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

Warning /!\ 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.

(i) Note that only those discrete percentage values are defined. Writing other values results in an error.

(i) 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.

Warning /!\ TODO: might be that actual_brightness queries the values on read, while brightness only returns the value written last. bl_power has no effect, what is it supposed to do?

#> 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.


CategoryDebugging

Kernel/Debugging/Backlight (last edited 2014-03-12 04:14:51 by penalvch)