KrystianD / legionutil

User-space tool for setting Rapid Charge, Battery Conservation and System Performance mode on Legion laptops.
MIT License
7 stars 3 forks source link

acpi call does not work with Y740 #1

Closed Magicrafter13 closed 2 years ago

Magicrafter13 commented 2 years ago

Shortly before finding this repo I actually stumbled across the same Arch wiki page, and tried it to no avail (specifically, trying to enable rapid charge, which I know for a fact I have, as it shows up in the Lenovo app, and the BIOS settings).

When cating the call file, it returns Error: AE_NOT_FOUND.

I'm just guessing the string of text we output to /proc/acpi/call is some kind of device address in a sense, and it's different on the Y740 (and probably Y730/Y540/Y530 too).

If I can figure out what to do in the meantime, I'll update this issue. If, in addition to that, I find a way to determine what model of Lenovo device is being used, I might submit a PR 👍

You may want to check the output as suggested on the wiki page too, since despite not working the program simply says done on my machine.

Not a very helpful issue yet, but hopefully that changes.

Magicrafter13 commented 2 years ago

Okay. It took me a while, but I eventually figured out how to dump the acpi table(s) on my system.

I still haven't confirmed that this truly is the acpi call for rapid charging, but I'm decently sure, and I can at least test a few methods to verify.

First, I believe this is the call to activate rapid charge on the Y740:

_SB.PCI0.LPCB.EC0.VPC0.SBMC 0x07

Mainly due to its similarity. And I also see that 0x07 and 0x08 modify the same fields, with 7 setting something to One and 8 setting something to Zero, so at the very least, 7 and 8 are tied together.

Through searching, I've only ever seen LPC after PCI* in relation to other Lenovo products.

As for verifying the change, I can call:

_SB.PCI0.LPCB.EC0.VPC0.GBMD

This does not return a simple 0x0 or 0x1 unfortunately. It returns many bits, however the relevant bit is 0x4. So for example, with the relevant bit on, my output is 0x160245, and with the bit off my output is 0x160241. So getting the result should be as simple as taking that output, and ANDing it with 0x4.

KrystianD commented 2 years ago

Hi @Magicrafter13, thank you for raising the issue! I use Legion 5 15ACH6H and indeed it may not work well for other legion laptops. In such case, it may be better to rename the repo.

Actually, the string we output didn't look to me as an address \_SB.PCI0.LPC0.EC0.VPC0.SBMC - note all zeros, that's why I assumed it will just work on other Legion laptops, could be a wrong assumption, though.

Let me know if you figure out a way to solve it, PR will be also very welcome :)

You may want to check the output as suggested on the wiki page too, since despite not working the program simply says done on my machine.

This is indeed a good idea. I will fix it when I find time, PR for this would be also welcome :) Also checking if acpi_call module is loaded would be nice, to make it more robust. All I needed was just an extremely simple utility where I could setuid, hence implemented in a very straightforward way :)

KrystianD commented 2 years ago

I eventually figured out how to dump the acpi table(s) on my system.

Nice finding! So all we need is to try to detect what is supported. Or actually try few different calls. Not a good solution but, should not break anything as chances that same setting would do something bad on other model are very low I think.

Magicrafter13 commented 2 years ago

The wiki page states this on the Battery Conservation setting:

To verify your setting:

# echo '\_SB.PCI0.LPC0.EC0.BTSM' > /proc/acpi/call
# cat /proc/acpi/call; printf '\n'

I find this interesting because in my reading of the acpi table thing, I noticed that the two values they said to use to turn conservation mode on/off (0x3/0x5 set a bit named... BTSM!). So it seems like the intention of _SB.PCI0.LPC0.EC0.BTSM is to just... get the value of BTSM, but that makes the Rapid Charging a little confusing since that one was _SB.PCI0.LPC0.EC0.QCHO, and QCHO is unlike anything I've seen in the data I'm currently looking at. For the record, I've discovered Rapid Charging as being labeled FCGM...

Also I'm 90+% sure that I'm correct about Rapid Charging, as I enabled it in Lenovo Vantage and the bit I've talked about was changed. Another bit was change too though and I started looking for that, but it seemed to change itself back without me doing anything so it's probably unimportant. the GBMD thing outputs 24 bits, but at least half of those aren't controllable through the same handle (_SB.PCI0.LPCB.EC0.VPC0.SBMC).

Still, all I need to do to be helpful is find out how to set the same values you were trying to set :)

All I needed was just an extremely simple utility

Sorry to have suddenly jumped in here only 7 days after you created the repository lol. Honestly I found it by complete accident while trying to figure out how to do this on my machine! And when I saw that you linked to that wiki page I was curious to see if you had done anything additional, especially since yeah you just called it "Legion" util.

So all we need is to try to detect what is supported.

As far as the end user is concerned this is the best method, but if you don't want to go down that rabbit hole you could just have the user select their machine via a config file, or a command line argument or something like that. Or just not support other machines at all. Regardless of if you implement my PR (which I will make 😉 ), I'm just glad I managed to figure out how to do this on my machine. A little annoying I had to compile a program to dump a crap ton of data files and then comb through a 60k line file in ViM, but when the OEM doesn't support us we gotta do it ourselves :p.

Magicrafter13 commented 2 years ago

@KrystianD I've seen some programs that could be used to get the model of the laptop (dmidecode -t1, dmidecode -s system-version, tlp-stat --system, inxi -M, hostnamectl), but I'm not sure if they'd be installed for every system or not. Came across the idea of DMI tables, and a library called smbios. But that's a whole can of worms I'm not ready to dive into. However, I did find some "files" you could easily read to get info from.

These are the files: /sys/devices/virtual/dmi/id/product_*

For me; product_family: Legion Y740-17IRHg product_name: 81UJ product_serial: (Permission denied, and this wouldn't be important anyway) product_sku: LENOVO_MT_81UJ_BU_idea_FM_Legion Y740-17IRHg product_uuid: (Permission denied, also not important) product_version: Lenovo Legion Y740-17IRHg

There's also chassis_version in the same directory, which has the same contents as product_version for me.

What are the contents of these files for you, so I can determine the best one to use.

KrystianD commented 2 years ago

Hey, sorry for late reply, I am crazy busy recently..

Here are the values for me:

/sys/devices/virtual/dmi/id/product_family:Legion 5 15ACH6H
/sys/devices/virtual/dmi/id/product_name:82JU
/sys/devices/virtual/dmi/id/product_sku:LENOVO_MT_82JU_BU_idea_FM_Legion 5 15ACH6H
/sys/devices/virtual/dmi/id/product_version:Legion 5 15ACH6H

And I agree this should be the correct way of determining the model to choose the right ACPI names. I would opt for product_family, but not as an exact match, instead, I would start with checking for Legion 5 and Legion Y740 substrings.

KrystianD commented 2 years ago

Hey, closing this issue for now. Feel free to open it again if/when you are working on this.