Log in

No account? Create an account
The Lenovo laptop panel saga continues... - Technical Blog of Richard Hughes

Richard Hughes
Date: 2006-11-24 12:20
Subject: The Lenovo laptop panel saga continues...
Security: Public
Reading back byte EC0:0x31 on a IBM Thinkpad embedded controller returns the laptop panel brightness. Setting this byte changes the panel brightness. This is how the ibm_acpi module has worked for years. Hacky, but it worked.
On a Lenovo N100, doing this didn't work due a slightly different embedded controller. I've managed to work out that you can read the brightness back (0-7) from reading the byte EC0:0xB9 (\_SB.PCI0.LPCB.EC0.BRTS) but changing it does nothing to the panel brightness. I can set the EC0:0xB9 value manually, and read back the 'new' value but I can't get EC0 to change the brightness at all.
I'm guessing Lenovo have upgraded the EC0, and now we either:
  • Can't software control the brightness due to physical h/w limitation
  • Have to poke some other register to make the brightness value "set"
I've had a look at the Renesas H8S datasheets (used for the EC0 chip) but it just seems like a bog standard micro-controller.

I've also read the 2161BV ec.s disassembly of the ThinkPad EC0 firmware (which looks like it should do the right thing) but I can't seem to get hold of the decompiled sources for the latest Renesas chip used in the N100. I've a sneaky suspicion there is either a software bug in the EC0 firmware, or that there is just no physical electrical connections to be able to change the brightness in software.
There's a pint offered at the next GUADEC for any help getting this to work.

EDIT: Update: setting the brightness to 7 using the Fn keys and then setting C0:0xB9 value to zero, and then pressing Fn brightness up, the display is set to brightness 1. This means we just have to convince the EC0 to update the brightness, which maybe we could do with a fake keypress or something. Still confused.
Post A Comment | 6 Comments | | Link

Matthew Garrett
User: mjg59
Date: 2006-11-24 13:51 (UTC)
Subject: (no subject)
I'd guess that the ec code catches the brightness key event, reads back from that register, increments, changes the brightness and then writes the value back to the register. Unfortunately this tells us absolutely nothing about how it changes the brightness, and disassembling the code for the microcontroller is probably the only way you're going to find that out.
Reply | Thread | Link

Richard Hughes
User: hughsient
Date: 2006-11-24 17:48 (UTC)
Subject: (no subject)
Yes, the brightness key event isn't forwarded to ACPI, so that would make sense. The brightness controller logic has been moved into the EC rather than being done at ACPI layer, probably so that the brightness just works on windows without writing a silly little brightness applet like other vendors do.
Reply | Parent | Thread | Link

User: (Anonymous)
Date: 2006-11-24 15:02 (UTC)
Subject: workaround
As a workaround, you could set the value to either one up or one down from the desired value, send the appropriate fn+key up/down keystroke into the keyboard buffer, then read back to value to confirm that the result is what was desired.

I agree that it is an ugly kludge.

Reply | Thread | Link

Richard Hughes
User: hughsient
Date: 2006-11-24 15:22 (UTC)
Subject: Re: workaround
>send the appropriate fn+key up/down keystroke into the keyboard buffer

How do I do that from kernel space? Thanks.

Reply | Parent | Thread | Link

User: jeremiah999
Date: 2007-04-29 03:30 (UTC)
Subject: Fixing buttons
I just read about this in Planet Gnome, maybe it'll help? His site is down though so I pasted it: http://blog.eikke.com/index.php/ikke/2007/04/28/how_to_fix_your_acpi_buttons_the_hackish

How to fix your ACPI buttons, the hackish way
from Planet GNOME by Ikke

Some time ago my ACPI-driven laptop keyboard buttons (volume control, music player controls,...) stopped working. I'm using the acpi-support package (although not running a Debian derivate) driven by acpid.
Today I decided I wanted my buttons back, so I started to find out what was going wrong.

The issue: acpi_fakekey checks all /dev/input/eventX devices whether or not it's a keyboard device, and if it finds one, it writes the necessary scancode to this device. Since some recent kernel, /dev/input/event0 is no longer my AT keyboard, but one of these ACPI buttons, so writing scancodes to the device won't work: my X server keyboard driver won't see them.

/proc/bus/input/devices told me I need event4 (or use this command: hal-get-property --udi `hal-find-by-capability --capability input | grep KBD` --key input.device | sed "s:/dev/input/event::g"
). Patching acpi_fakekey.c is pretty trivial:

--- acpi-support-0.94/acpi_fakekey.c.orig 2007-04-28 18:09:37.078953488 +0200
+++ acpi-support-0.94/acpi_fakekey.c 2007-04-28 18:09:49.578470914 +0200
@@ -13,7 +13,7 @@
char filename[32];
char key_bitmask[(KEY_MAX + 7) / 8];

- for (i=0; i<32; i++) {
+ for (i=4; i<32; i++) {
snprintf(filename,sizeof(filename), "/dev/input/event%d", i);

fd = open(filename, O_RDWR);

Replace the 4 with the correct number on your system.

Now my buttons "work" again. Patching acpi_fakekey so it uses HAL to figure out the correct device to write to might be somewhat more reasonable though :-)
Reply | Thread | Link

Richard Hughes
User: hughsient
Date: 2007-04-29 08:06 (UTC)
Subject: Re: Fixing buttons
Yes, I've seen this thanks. I want to do it the non-hackish way using HAL - see http://lists.freedesktop.org/archives/hal/2007-April/008111.html and http://lists.freedesktop.org/archives/hal/2007-April/008198.html
Reply | Parent | Thread | Link

my journal
April 2008