ThinkPadLEDControl icon indicating copy to clipboard operation
ThinkPadLEDControl copied to clipboard

Doesn't seem to work on x390 yoga

Open eats7 opened this issue 5 years ago • 14 comments

The app runs and everything, just selecting leds in the app don't do anything for the hardware leds. Perhaps it needs updating? It's a somewhat new laptop (bought last year)

eats7 avatar Sep 02 '20 07:09 eats7

What is exactly your laptop model? Is it Lenovo or ThinkPad line? On traditional ThinkPad laptops with ThinkPad BIOS (the regular BIOS/UEFI), the offsets for LEDs in the embedded controller are always the same, only thing that changes is the actual LEDs that the computer has. Personally, I test the application on ThinkPad W540/W541, and ThinkPad T470/25, as those are the models that I have.

You can try playing with the values in the embedded controller by using the dedicated option in the app, maybe you determine the right offsets, and then I can include them in the application. If you do this, please cold shutdown the computer and power it back on after modifying values in the EC, as you may change to wrong values, by mistake, other stuff, like fan speed. Or try looking though the kernel module responsible for toggling the LEDs on Linux, maybe there you find the correct numbers.

As far as the application is concerned, I cannot possibly test and determine this for each and every variation, but I am open to integrating fixes should someone come up with them.

valinet avatar Sep 03 '20 17:09 valinet

It is a ThinkPad X390 yoga. I did try fooling around with that in options although i couldn't get any LEDs to work. It's not a HUGE issue for me, just thought I'd let you know. Perhaps others have this issue can chime in with more knowledge. Seems to be quite a cool app though!

On Thu., Sep. 3, 2020, 1:37 p.m. Valentin-Gabriel Radu, < [email protected]> wrote:

What is exactly your laptop model? Is it Lenovo or ThinkPad line? On traditional ThinkPad laptops with ThinkPad BIOS (the regular BIOS/UEFI), the offsets for LEDs in the embedded controller are always the same, only thing that changes is the actual LEDs that the computer has. Personally, I test the application on ThinkPad W540/W541, and ThinkPad T470/25, as those are the models that I have.

You can try playing with the values in the embedded controller by using the dedicated option in the app, maybe you determine the right offsets, and then I can include them in the application. If you do this, please cold shutdown the computer and power it back on after modifying values in the EC, as you may change to wrong values, by mistake, other stuff, like fan speed. Or try looking though the kernel module responsible for toggling the LEDs on Linux, maybe there you find the correct numbers.

As far as the application is concerned, I cannot possibly test and determine this for each and every variation, but I am open to integrating fixes should someone come up with them.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/valinet/ThinkPadLEDControl/issues/1#issuecomment-686644684, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVCVDVOHURVYYLD3LZIYYLSD7H5ZANCNFSM4QSWFGWA .

eats7 avatar Sep 03 '20 19:09 eats7

ThinkPad X390 yoga

Oh, okay, yeah, excuse me, I thought it was a Lenovo Yoga, it is a bit confusing that Lenovo uses this additional brand (Yoga) on both ThinkPad and Lenovo laptops, and furthermore, there are some Lenovo laptops that are simply Yoga.

Anyway, can you test whether it works on Linux by writing to the same EC locations (maybe it is a driver - WinRing0 - issue in Windows, who knows...)? A while ago I wrote a guide on how to toggle the LEDs on ThinkPads from command line in a standard Linux distribution: https://www.reddit.com/r/thinkpad/comments/7n8eyu/thinkpad_led_control_under_gnulinux/. If it works there at the same locations, then I can look into why it might not work in Windows. Otherwise, maybe they changed how the LEDs are operated on these newer machines...

valinet avatar Sep 03 '20 19:09 valinet

If you need me to try anything I dual boot Linux and windows on my machine, so I'm open to it

On Thu., Sep. 3, 2020, 3:54 p.m. Valentin-Gabriel Radu, < [email protected]> wrote:

ThinkPad X390 yoga

Oh, okay, yeah, excuse me, I thought it was a Lenovo Yoga, it is a bit confusing that Lenovo uses this additional brand (Yoga) on both ThinkPad and Lenovo laptops, and furthermore, there are some Lenovo laptops that are simply Yoga.

Anyway, can you test whether it works on Linux by writing to the same EC locations (maybe it is a driver - WinRing0 - issue in Windows, who knows...)? A while ago I wrote a guide on how to toggle the LEDs on ThinkPads from command line in a standard Linux distribution: https://www.reddit.com/r/thinkpad/comments/7n8eyu/thinkpad_led_control_under_gnulinux/. If it works there at the same locations, then I can look into why it might not work in Windows. Otherwise, maybe they changed how the LEDs are operated on these newer machines...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/valinet/ThinkPadLEDControl/issues/1#issuecomment-686722026, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVCVDUCQZPCK2WUVOTEAZDSD7YA5ANCNFSM4QSWFGWA .

eats7 avatar Sep 03 '20 20:09 eats7

Great, if you have the time, try some commandd from my Reddit article:

  • echo -n -e "\x0a" | sudo dd of="/sys/kernel/debug/ec/ec0/io" bs=1 seek=12 count=1 conv=notrunc 2> /dev/null should disable the red dot on the back of the laptop; before that, make sure to type sudo modprobe -r ec_sys; sudo modprobe ec_sys write_support=1 in order to load the kernel module
  • if the ec_sys module is not available, you may have to build it from the source of your current kernel, as a module, and load it using something like sudo insmod -f drivers/acpi/ec_sys.ko
  • if above does not produce anything, try to see whether some lights are exposed via the ThinkPad/IBM ACPI kernel modules: echo 0 | sudo tee /sys/class/leds/tpacpi\:\:power/brightness should turn off the power button LED, or echo 2 | sudo tee /sys/class/leds/tpacpi\:\:kbd_backlight/brightness should turn keyboard brightness to maximum Check more in the Reddit post, where I explain it more thoughtfully: https://www.reddit.com/r/thinkpad/comments/7n8eyu/thinkpad_led_control_under_gnulinux/.

If you could test these, that'd be a good starting point. Thanks.

valinet avatar Sep 03 '20 20:09 valinet

Alright, so I followed the instructions, and the red dot command didn't do anything unfortunately, and the light stayed on. The power light command sent back an error of no such file or directory, and the keyboard one seemed to work okay!

On Thu, Sep 3, 2020 at 4:18 PM Valentin-Gabriel Radu < [email protected]> wrote:

Great, if you have the time, try some command from my Reddit article:

  • echo -n -e "\x0a" | sudo dd of="/sys/kernel/debug/ec/ec0/io" bs=1 seek=12 count=1 conv=notrunc 2> /dev/null should disable the red dot on the back of the laptop; before that, make sure to type sudo modprobe -r ec_sys; sudo modprobe ec_sys write_support=1 in order to load the kernel module
  • if the ec_sys module is not available, you may have to build it from the source of your current kernel, as a module, and load it using something like sudo insmod -f drivers/acpi/ec_sys.ko
  • if above does not produce anything, try to see whether some lights are exposed via the ThinkPad/IBM ACPI kernel modules: echo 0 | sudo tee /sys/class/leds/tpacpi::power/brightness should turn off the power button LED, or echo 2 | sudo tee /sys/class/leds/tpacpi::kbd_backlight/brightness should turn keyboard brightness to maximum Check more in the Reddit post, where I explain it more thoughtfully: https://www.reddit.com/r/thinkpad/comments/7n8eyu/thinkpad_led_control_under_gnulinux/ .

If you could test these, that's be a good starting point. Thanks.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/valinet/ThinkPadLEDControl/issues/1#issuecomment-686732285, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVCVDSZ5BQZRC2EVW5DFNTSD72YBANCNFSM4QSWFGWA .

eats7 avatar Sep 05 '20 20:09 eats7

Uf, okay, that doesn't sound too good. Unfortunately, there's not much I can do without having that laptop. Maybe I can source one and figure something out, but I can't promise anything. Even with one, who knows, I'd have to investigate how it all works now... If someone has any insight on this and would like to share, that'd be awesome; you could ask a question on https://reddit.com/r/ThinkPad, see if someone has any more knowledge about this than I do.

valinet avatar Sep 06 '20 22:09 valinet

Okay no worries, it's not a huge deal for me. Maybe they just updated how they handle LEDs or something like that. I'd be curious if anyone else has an issue on new thinkpads and non yoga models.

On Sun., Sep. 6, 2020, 6:29 p.m. Valentin-Gabriel Radu, < [email protected]> wrote:

Uf, okay, that doesn't sound too good. Unfortunately, there's not much I can do without having that laptop. Maybe I can source one and figure something out, but I can't promise anything. Even with one, who knows, I'd have to investigate how it all works now... If someone has any insight on this and would like to share, that'd be awesome; you could ask a question on https://reddit.com/r/ThinkPad, see if someone has any more knowledge about this than I do.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/valinet/ThinkPadLEDControl/issues/1#issuecomment-687919599, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVCVDQN6LGM2VZI573M4VLSEQENRANCNFSM4QSWFGWA .

eats7 avatar Sep 06 '20 22:09 eats7

Actually, there is another thing to try, now that I think about it. So I was thinking how I got the values, trying to remember what I did 4 years ago. There is a place that contains logic about a lot of stuff related to ACPI, including turning on/off the LEDs: the DSDT (Differentiated System Description Table). That's how I originally verified the values for my W540 (you can find various things on the Internet, but putting them together is ultimately better done by inspecting youself), and those happened to work on the ThinkPad 25 I am currently using. Okay, so, could you boot into some Linux distro, grab the DSDT tables for the x390, and upload a copy here? Post everything from /sys/firmware/acpi/tables. I think you need to be root to see and grab what's in there.

valinet avatar Sep 06 '20 23:09 valinet

Here you are! tables.tar.gz

eats7 avatar Sep 07 '20 06:09 eats7

I had a look on the tables, they indeed changed a lot. Old ThinkPad DSDT used to have a method called LED in the EC (designated "H8" on initialization) which would get two arguments: a state and an offset, like \_SB.PCI0.LPCB.EC.LED (0x00, 0x80) (that turns on the power LED). These are OR'd together and written to the EC. This exact behavior found in the ACPI files is reproduced by the software, and naturally it works. Here is the legacy LED method:

Method (LED, 2, NotSerialized) { Local0 = (Arg0 | Arg1) If (\H8DR) { HLCL = Local0 } Else { \WBEC (0x0C, Local0) } }

On your machine, none of this applies. The implementation changed entirely, there is no LED method. I searched for methods that print a LIDO and LIDC debug message in both DSDTs (LIDO and LIDC I think stand for "lid open", and "lid close", on my T470 the power LED is toggled when going though this). Here is how it looks on my T470:

        Method (_Q2A, 0, NotSerialized)  // _Qxx: EC Query, xx=0x00-0xFF
        {
            ADBG ("LIDO")
            \VCMS (0x01, \_SB.LID._LID ())
            \_SB.PCI0.LPCB.EC.LED (0x00, 0x80)
            If ((\ILNF == 0x00))
            {
                If (\IOST)
                {
                    If (!\ISOC (0x00))
                    {
                        \IOST = 0x00
                        \_SB.PCI0.LPCB.EC.HKEY.MHKQ (0x60D0)
                    }
                }
                \_SB.PCI0.LPCB.EC.HKEY.MHKQ (0x5002)
                If ((\PLUX == 0x00))
                {
                    If (VIGD)
                    {
                        \_SB.PCI0.GFX0.VLOC (0x01)
                    }
                    Notify (\_SB.LID, 0x80) // Status Change
                }
            }
        }

See the \_SB.PCI0.LPCB.EC.LED (0x00, 0x80) line? That's all that is different in the same method from your DSDT. It changed to: \_SB.PCI0.LPCB.H_EC.ITOP (). That seems to be called a lot instead of the old LED method. As you see, it takes no arguments. If we inspect the ITOP method we get this:

            Method (ITOP, 0, Serialized)
            {
                If (\_SB.PCI0.LPCB.H_EC.LIDC)
                {
                    If (\_SB.PCI0.LPCB.H_EC.PBLS)
                    {
                        \_SB.SGOV (0x0402000C, 0x01)
                    }
                    Else
                    {
                        \_SB.SGOV (0x0402000C, 0x00)
                    }
                }
                Else
                {
                    \_SB.SGOV (0x0402000C, 0x00)
                }
            }

Again, a call with a hard coded offset (0x0402000C), and some status (0x00 or 0x01). For the sake of completeness, here is SGOV method:

        Method (SGOV, 2, Serialized)
        {
            Local0 = GGRP (Arg0)
            Local1 = GNMB (Arg0)
            Local2 = (GADR (Local0, 0x02) + (Local1 * 0x10))
            OperationRegion (PDW0, SystemMemory, Local2, 0x04)
            Field (PDW0, AnyAcc, NoLock, Preserve)
            {
                TEMP,   1, 
                Offset (0x04)
            }
            TEMP = Arg1
        }

To be honest, I do not perfectly understand what this method does, but I will look into it and try to understand. As I said, the LED part of the DSDT is completely changed. One source of useful information might me the ThinkPad ACPI module in the Linux kernel. So, if you could help me with 2 more things:

  1. On Linux, could you do a ls /sys/devices/platform/thinkpad_acpi/leds and report back the output? I am curious what LEDs the driver recognizes on your machine. Also, you could try toggling them, they probably expose some files that let you do that (for example, something like echo 0 | sudo tee /sys/devices/platform/thinkpad_acpi/leds/tpacpi\:\:power/brightness should turn off the power LED. Can you test that as well?
  2. On Linux again, we can try to call the ITOP method using acpi_call. Can you try this command: echo '\_SB.PCI0.LPCB.H_EC.ITOP' | sudo tee /proc/acpi/call and report back whether anything happened to any of the LEDs? Or to anything else on the machine? I don't know if acpi-call is installed by default, you may have to install it from your distribution's repositories.

In the meantime, I will look more into those DSDT methods, and since you mentioned previously that toggling the keyboard backlight works, I will try to look in the kernel driver to see how they do that.

Thank you for your help, maybe we can sort this one out.

valinet avatar Sep 07 '20 11:09 valinet

Yeah, I looked on the ThinkPad ACPI kernel driver, it is mostly a wrapper around a few DSDT methods:

  • For toggling LEDs, it uses the LED method I described above, which is not found in the T490 DSDT
  • For getting keyboard illumination, it uses the MLCS method, which is present in the T490 DSDT
  • For setting keyboard illumination, it uses the MLCG method, which is present in the T490 DSDT

This is consistent with the reports. You said LEDs do not work (specifically, you said power LED not found), but toggling keyboard illumination does. The way LEDs are made available in /sys/devices/platform/thinkpad_acpi/leds is by checking whether the DSDT contains an LED method. As T490's does not contain one, the LED subsystem of the driver fails to initialize and reports it found no LEDs, making nothing available to user space. This part in the driver is relevant:

static enum led_access_mode __init led_init_detect_mode(void)
{
	acpi_status status;

	if (tpacpi_is_ibm()) {
		/* 570 */
		status = acpi_get_handle(ec_handle, "SLED", &led_handle);
		if (ACPI_SUCCESS(status))
			return TPACPI_LED_570;

		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
		status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
		if (ACPI_SUCCESS(status))
			return TPACPI_LED_OLD;
	}

	/* most others */
	status = acpi_get_handle(ec_handle, "LED", &led_handle);
	if (ACPI_SUCCESS(status))
		return TPACPI_LED_NEW;

	/* R30, R31, and unknown firmwares */
	led_handle = NULL;
	return TPACPI_LED_NONE;
}
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/platform/x86/thinkpad_acpi.c?h=v5.9-rc4

So, it seems to me that the Linux kernel driver is out dated for newer models, due to this change in the firmware. So yeah, I am fairly certain you won't have much success with 1 above, maybe 2 can hopefully not be a dead end.

Anyway, I opened an issue at kernel.org Bugzilla regarding the kernel module's limitation, let's see what insight we get from there: https://bugzilla.kernel.org/show_bug.cgi?id=209195

valinet avatar Sep 07 '20 12:09 valinet

Okay sorry about the late reply, been busy this week.

Here are the outputs for

1:

tyler@x390:~$ ls /sys/devices/platform/thinkpad_acpi/leds platform::micmute platform::mute tpacpi::kbd_backlight tyler@x390:~$ echo 0 | sudo tee /sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/brightness tee: '/sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/brightness': No such file or directory 0

And 2:

tyler@x390:~$ echo '_SB.PCI0.LPCB.H_EC.ITOP' | sudo tee /proc/acpi/call tee: /proc/acpi/call: No such file or directory _SB.PCI0.LPCB.H_EC.ITOP tyler@x390:~$ ls /proc/acpi/ button ibm wakeup

On Mon, Sep 7, 2020 at 8:26 AM Valentin-Gabriel Radu < [email protected]> wrote:

Yeah, I looked on the ThinkPad ACPI kernel driver, it is mostly a wrapper around a few DSDT methods:

  • For toggling LEDs, it uses the LED method I described above, which is not found in the T490 DSDT
  • For getting keyboard illumination, it uses the MLCS method, which is present in the T490 DSDT
  • For setting keyboard illumination, it uses the MLCG method, which is present in the T490 DSDT

This is consistent with the reports. You said LEDs do not work (specifically, you said power LED not found), but toggling keyboard illumination does. The way LEDs are made available in /sys/devices/platform/thinkpad_acpi/leds is by checking whether the DSDT contains an LED method. As T490's does not contain one, the LED subsystem of the driver fails to initialize and reports it found no LEDs, making nothing available to user space. This part in the driver is relevant:

static enum led_access_mode __init led_init_detect_mode(void) { acpi_status status;

if (tpacpi_is_ibm()) { /* 570 */ status = acpi_get_handle(ec_handle, "SLED", &led_handle); if (ACPI_SUCCESS(status)) return TPACPI_LED_570;

  /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
  status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
  if (ACPI_SUCCESS(status))
  	return TPACPI_LED_OLD;

}

/* most others */ status = acpi_get_handle(ec_handle, "LED", &led_handle); if (ACPI_SUCCESS(status)) return TPACPI_LED_NEW;

/* R30, R31, and unknown firmwares */ led_handle = NULL; return TPACPI_LED_NONE; }

So, it seems to me that the Linux kernel driver is out dated for newer models, due to this change in the firmware. So yeah, I am fairly certain you won't have much success with 1 above, maybe 2 can hopefully not be a dead end.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/valinet/ThinkPadLEDControl/issues/1#issuecomment-688291898, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEVCVDXLE3MGOUKIFKQP7BLSETGPBANCNFSM4QSWFGWA .

eats7 avatar Sep 12 '20 05:09 eats7