Why does my Thinkpad brightness control skip steps?

The problem: there are 16 brightness levels on my laptop, but pressing hotkeys Fn+Home, Fn+End adjusts brightness 3 steps at a time (e.g. from 0 to 3, or from 15 to 12).

I find it important to notice that at the login screen hotkeys work fine. But after login that odd behavior appears.

Also, if I give focus to a menu (e.g. click on File menu in firefox), hotkeys work fine.

xdotool key XF86MonBrightnessDown works fine, adjusting brightness by 1 step (checked with cat /sys/devices/pci0000:00/0000:00:02.0/backlight/acpi_video0/brightness).

I also installed indicator-brightness - it shows 16 leves (0-15).

I tried setting acpi_backlight=vendor in grub (inspired by this topic: http://ubuntuforums.org/showthread.php?t=1909184 with similar problem). It worked in that hotkeys became working fine. But problems with OSD notification, xdotool and brightness indicator arised. So I think that it's not a right solution.

It seems that after login something interferes in the hotkeys processing scheme. Any ideas?

Edit (additional info)

  • I made an observation that hotkeys work at hardware level - I can adjust brightness immediately after turning on my laptop (e.g. at the BIOS screen).

  • After $ killall gnome-settings-daemon hotkeys adjust brightness by one step, but no notifications appear. Shortly gnome-settings-daemon recovers, and triple step issue returns.

  • acpi_listen gives the following output (both keys sequentially):

    $ acpi_listen
    ibm/hotkey HKEY 00000080 00001010
    video LCD0 00000086 00000000
    ibm/hotkey HKEY 00000080 00001011
    video LCD0 00000087 00000000
    

    At this point I thought that (1) hotkeys work at hardware level; (2) ibm/hotkey takes care of hotkeys; (3) video takes care too. Thus, triple step issue appears.

    I tried blacklisting video (I expected that this will lead to a double step behavior), but nothing changed.

As a workaround, I created my own hotkeys in CompizConfig Settings Manager - as described here, but with --clearmodifiers argument:

xdotool key --clearmodifiers XF86MonBrightnessUp
xdotool key --clearmodifiers XF86MonBrightnessDown

So now I can either use initial hotkeys or new ones for finer adjustments.

Open questions

There was already discussion for the case with double step: Lenovo ThinkPads, brightness function keys make two steps instead of one, looking for workaround:

the hardware just does it and then also sends out a signal saying the button's been pressed. Possibly you could unset the shortcut in System -> Preferences -> Keyboard Shortcuts for this action?

But I am eager to know,

  1. Why do I get triple step issue?
  2. How can I unset processing this hotkeys?

I would be very grateful if someone explains it.


Where do the 3 steps for 1 keypress come from?

You get three brightness steps for one keypress because:

  1. The standard ACPI/video driver adjusts step 1
  2. The thinkpad_acpi driver tells the BIOS to adjust step 2 but still forwards the keypress event
  3. The GNOME power daemon intercepts this keypress and tells ACPI to adjust once again step 3

1. Disable the video driver from adjusting brightness on its own

This gets rid of one of the three steps (step 1) above.

  • Open the terminal
  • Type sudo sh -c 'echo -n 0 > /sys/module/video/parameters/brightness_switch_enabled'
  • Test, now you should have brightness control in steps of two
  • To automatically disable this on startup, open /etc/rc.local in your favorite editor, and before the last line (exit 0), add:

    echo -n 0 > /sys/module/video/parameters/brightness_switch_enabled

2. Recompile the thinkpad_acpi module to solve the double-press issue

  • We have to stop thinkpad_acpi from adjusting the brightness via BIOS and have it only forward the keypress to GNOME, so that GNOME makes the only adjustment step
  • This is a known bug which was fixed in kernel 3.4+
  • To fix it for Ubuntu 12.04/Precise, we'll have patch its version of thinkpad_acpi and recompile it:

    1. Install the kernel headers: sudo apt-get install linux-headers-$(uname -r)
    2. Install build tools sudo apt-get install build-essential
    3. Make a temporary directory and change to it:
      mkdir ~/tpacpi-bright && cd ~/tpacpi-bright
    4. Download and patch the source file thinkpad_acpi.c from the Ubuntu Kernel git repository:

      wget -O- "http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-precise.git;\
      a=blob_plain;f=drivers/platform/x86/thinkpad_acpi.c;hb=HEAD"\
      | sed -e 's/tp_features.bright_acpimode && acpi_video/acpi_video/g' \
      > thinkpad_acpi.c
    5. In the same folder where thinkpad_acpi.c has been downloaded, you will need a "Makefile". You can download it directly from this Pastebin, using:

      wget -OMakefile http://pastebin.com/raw.php?i=ybpnxeUT

    OR paste the below into a file called Makefile, :

    obj-m += thinkpad_acpi.o
    all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    1. Now type make to create the module; you will see a thinkpad_acpi.ko file in the folder when done.
  • Test the patched module after loading it with:

    sudo rmmod thinkpad_acpi && sudo lsmod thinkpad_acpi.ko
  • If the brightness is now fixed and gives you full control, replace the stock module with the patched module:

    TPDIR=/lib/modules/$(uname -r)/kernel/drivers/platform/x86
    sudo mv $TPDIR/thinkpad_acpi.ko $TPDIR/thinkpad_acpi.ko.stock
    sudo mv ~/tpacpi-bright/thinkpad_acpi.ko $TPDIR/thinkpad_acpi.ko
    
  • You can clean up the build folder with make clean; keep it around for future kernel upgrades!


I was having the exact same problem as you plus that my system always started with the screen off.

I would like to thank you for pointing me in the right direction, acpi_backlight=vendor did the trick for me without any of the problems you experienced. I am using a HP G7 1116sg with hybrid graphics (Intel HD3000 (currently only using the intel because of hybrid problems in ubuntu. I say this only because the X220 is listed as having the same graphics adapter) / Radeon HD6870) and Ubuntu 12.04.

Just wanted to say that the grub changes worked for me without any apparent problems.

Good luck on finding a solution.