Closed aymanbagabas closed 5 years ago
Thank you for your awesome work, I'll test.
Right away from the start I can say that fnlk
doesn't really work for MateBook 13. I get REG[0xe6]==0x0
(off) always, whatever the Fn key status, and for REG[0xe7]
I get different values: 0x28 (off), 0x26 (off), 0x2d (on), 0x2c (off), 0x32 (off), 0x21 (on), 0x1e (off), 0x25 (on), 0x27 (on), 0x29 (on) — that's what I have seen so far, and I can't really understard what triggers change here. It being so I'm reluctant to set fnlk
, since I don't understand what these values represent.
Yep, something is definitely off here. I just got REG[0xe7]==0x7b
after reboot with power cord plugged, and it didn't change until I unplugged it; then after unplugging I got 0x4d
, replugging got me 0x32
for a little while, then 0x36
where it is currently stuck. This registry seems to monitor something, but I have no idea what.
REG[0x43]
(batpro) was initially 0x0
, not 0x80
that your script sets it to when asked to go off
.
I couldn't see any change in behaviour after setting it to 0xc0
(your value for on
), 0x80
(your value for off
) or back to 0x0
.
Both REG[0xe4]
and REG[0xe5]
were initially 0x0
.
Setting REG[0xe5]
(second value for batthre
in your script) to any number I've tested doesn't have any obvious effect. REG[0xe4]
is more interesting.
Setting REG[0xe4]
to any value I've tested other than 0x0
does not affect anything when power cord is unplugged. However, when plugged, the charging LED lights up permanently, as if the battery was fully charged, /sys/class/power_supply/BAT0/status
shows Unknown
and /sys/class/power_supply/BAT0/current_now
shows 0
. It looks like the battery isn't charging, either. Setting REG[0xe4]
back to 0x0 restores charging functionality.
I meditated in front of registry table (watch ./acer_ec.pl regs
), a little and I'm pretty sure 0xa4
is for LEDs: caps lock sets it to 1, Fn sets it to 2, both on simultaneously set it to 3. Fn also sets 0x08
to 1, so that one should be Fn Lock itself...
Interesting! Thank you for your response. So I've come to these values from using PC manager in Windows while monitoring these registers. You can try that using RW Everything. Just pay attention to what get changed when you enable battery protection, change thresholds, and fn lock. These are the three things I can customize in my Matebook X Pro (2018) you might have more stuff idk. Right now, this way is very hacky and dirty but I'm trying to find a way to control these parameters using ACPI and understanding DSDT tables. If you could provide these tables (DSDT and SSDTs) for your model I'd really appreciate it. That way we could mainline it into a x86 driver.
I have no Windows running on this machine, so my best chance would be finding someone who still does.
As for DSDT/SSDTs, here is the result of acpidump
, if it is of any use:
acpi.log
Also, I received these ACPI dumps from a person running Windows. There are three, for three conditions: battery protection off and two modes for on. AcpiTbls.zip
...and they kindly supplied EC states as well. EC6662.zip
After looking at the EC states, definitely, REG[0xe4] and REG[0xe5] are responsible for battery thresholds as you can see they correspond with the thresholds values. For example, in EC6662_40_70.rw, REG[0xe4]=0x28 which is 40 in decimal and REG[0xe5]=0x46 which is 70. However, turning the battery protection might be REG[0x9c] responsibility because they match the values I have for my MBXP. 0x80 when off and 0xc0 when on.
Please try the following while charging and test if battery protection works
$ acer_ec.pl := 0x9c 0xc0
$ acer_ec.pl := 0xe4 0x28
$ acer_ec.pl := 0xe5 0x46
$ cat /sys/class/power_supply/BAT0/status
Thanks!
It being so I'm reluctant to set
fnlk
, since I don't understand what these values represent.
In PC Manager, there is a setting that makes the default behavior of the first row either function keys or multimedia. So if this is turned off, F1 key would decrease brightness and Fn+F1 would trigger F1. Now if on, it would be the opposite, F1 key would be just F1 and Fn+F1 would be brightness. While we're at it, would you be able to help by providing EC states for this? It would also be helpful to include mic led since in my machine EC states, they share the same byte. EC states:
Please try the following while charging and test if battery protection works
No such luck.
First of all, I totally agree that REG[0xe4] and REG[0xe5] are most likely thresholds, that's rather obvious. However, REG[0x9c] looks like a poor candidate for battery protection, since it has the same contents in "disables" and "70-90" dumps. Wouldn't it be natural for battery protection register to be the same in "70-90" and "40-70", but a different value in "disabled"?
Anyway, I gave it a try, and I don't have any idea what is happening.
I tried to find a register that would be the same in "40-70" and "70-90" dumps but different in "disabled" dump. I found three of those: REG[0x22], REG[0x9e] and REG[0xb2]. However, neither of them looks a good enough candidate to me:
Maybe I'm missing something?
So if this is turned off, F1 key would decrease brightness and Fn+F1 would trigger F1. Now if on, it would be the opposite, F1 key would be just F1 and Fn+F1 would be brightness.
This. Is. Awesome.
Really, thank you for that, that alone deserves your name to be remembered among the living and your image cast in stone somewhere on Mt. Everest.
I had no idea this function lock even existed (since I barely looked at PC Manager before wiping Windows off my machine). I had my comrade on 4pda.ru forum send me EC register dumps and now I've got it.
On MB13 it's [REG0x08]. It's 0x00 by default, 0x01 with Fn key on (and Fn led lit up), that much I knew already. Now I know that setting it to 0x02 enables this Fn-Lock feature, and further pressing Fn key sets it to 0x03 and inverts behaviour. This finally allows for things like Ctrl+Ins or Alt+Shift+PrtSc to happen!
Thing is, with Fn-Lock off MB13 still translates any Ctrl+Fx, Alt+Fx and Shift+Fx as Mod+Fx, so without going Fn-Lock you can never get Shift+Ins, you'll always get Shift+F12.
Another thing to mention: Fn and CapsLock leds on MB13 seem to be mirrored by [0xa4]: in is [0x00] initially, [0x01] with Fn led on, [0x02] with Caps led on, and naturally [0x03] with both on. However, manually changing this register doesn't change led states.
Really, thank you for that, that alone deserves your name to be remembered among the living and your image cast in stone somewhere on Mt. Everest.
Lol, I don't know about that.
Thing is, with Fn-Lock off MB13 still translates any Ctrl+Fx, Alt+Fx and Shift+Fx as Mod+Fx, so without going Fn-Lock you can never get Shift+Ins, you'll always get Shift+F12.
You could also use Shift+Fn+Ins
I'm using diff to see the differences between the files and comparing each one with the disabled one.
- REG[0x9c] is obviously not the battery protection switch. It turns 0xc0 whenever cable is unplugged and 0x80 whenever it is plugged, and if I try to set it to a different value, it resets itself in less than a second (when unplugged) or within 2 seconds (when plugged), the only exception being that if plugged and REG[0xe4] is non-zero (i.e. battery status Unknown) it keeps whatever value I set it to, but any attempt to change REG[0xe4] or REG[0xe5] resets it again.
Does this mean that the EC data were collected while the cable is unplugged?? The status should be "Unknown" when the feature is working since Linux "still" doesn't detect such features hence the unknown value. However, you could monitor the charging rate to know if its working using something like upower --monitor-detail
.
You could also use Shift+Fn+Ins
Not without Fn-Lock, no. Now I can.
Does this mean that the EC data were collected while the cable is unplugged??
I wouldn't really know.
I am doing some more testing, might be on something here, but still too early to say. Will update as soon as I have consistent data.
OK, I did some more testing.
What I previously said about [0x9c] seems to be only partly true (maybe I didn't pay enough attention). It indeed shows 0xc0 for not charging, 0x80 for charging, and no, it can't really be flipped manually, it gets reset back almost immediately (although not immediately enough, so to acer_ec.pl
it looks like the new value has been successfully set). Under some conditions (see below) it can be 0xc0 when power cord is plugged! And when it is, linux gets all confused about battery status: /sys/class/power_supply/BAT0/status
shows Unknown
while upower --monitor-detail
says it is charging; the led beside the charging port (on the left side of the laptop) lights constantly (as in "fully charged"), and the battery is indeed not charging.
If the battery charge is low enough, I can set reasonable thresholds with power cord unplugged, and then have charging stop at the desired point.
- Battery at 50%, unplugged. [0x9c] = 0xc0
- Set [0xe4] to 70 and [0xe5] to 90.
- Plug the cord. [0x9c] turns 0x80, charging starts.
- At 89% charge (i.e. 1% below [0xe5]) charging stops, [0x9c] turns 0xc0.
However, the lower threshold doesn't get respected...
- Battery happily discharges to 49%. [0x9c] is still 0xc0, and it looks like it is ready to go down all the way to zero.
- I lose my temper and unlpug the machine for several seconds, then replug.
...and here is where consistent behaviour ends. More often than not [0x9c] flips to 0x80 at replug, and laptop starts charging up until the threshold set by [0xe5]; but sometimes [0x9c] keeps beeing 0xc0 even after replugging, in which case battery is not charging.
I've noticed a few more things while testing:
Fiddling with [0xe4] (but not [0xe5]) almost always flips [0x9c] to 0xc0. Naturally, it has no effect when unplugged, because [0x9c] is 0xc0 anyway, but when plugged it makes the battery stop charging (the behaviour I've been seeing since I first started testing all this). However, I think I've seen at least one case where [0x9c] remained 0x80 after changing [0xe4], and I can't yet understand how to reproduce that (or maybe I didn't pay close attention again).
If laptop is charging and in sleep mode, after wakeup [0x9c] is 0xc0 for a second or two (and the battery keeps charging, mind you, the led keeps blinking!), then flips to 0x80.
If [0xe4] is 0, the laptop doesn't seem to care what [0xe5] is (again, I've seen this behaviour consistenly since day one):
- Battery at 35%, unplugged. Set [0xe4] to 40, [0xe5] to 60.
- Plug. Charging.
- At 59% [0x9c] turns 0xc0, charging stops (as expected by now).
- Set [0xe4] to 70, [0xe5] to 90.
- Nothing, still 0xc0 in [0x9c], still discharging. Wait for 10 minutes to be sure - no, nothing.
- Set [0xe4] to 0, [0xe5] to 70. Immediately charging starts, [0xc9] is 0x80.
- At 81% (yes, despite [0xe5] being 70) set [0xe4] to 70, [0xe5] to 90. Charging stops, [0x9c] is 0xc0 (not really surprising by now, but why, Discordia, why?!)
I'll test more, especially at points of inconsistence (unplug-replug and setting thresholds while plugging), but you've got the picture. Can't say I really understand what's going on and what to do next.
All right, I got it. At least I think I got it.
The way battery protection works on this machine is really different from ThinkPads, and it got me going in a totally wrong direction (well, not totally wrong, but somewhat orthogonal). What I've described in previous comment is actually things working as they are supposed to, with one exception.
Thing is, all the tests described in previous comment were done using a weak phone charger I happened to have in my office (as I left the original Huawei charger at home). Actually, 0xc0 in [0x9c] doesn't stand for "discharge", it stands for "don't charge", and this subtle difference explains it all. The original charger is powerful enough that under no circumstances (including massive wireless data transfer, max screen brightness and multithreaded CPU stress test all at the same time) battery charge can go down with charger plugged.
As soon as I guessed how this all works, I asked the windows-running guys to confirm some of the behaviour, and indeed everything fits. Here's the logic:
I think I'll modify your script for MateBook 13 to remove all but thresholds (I have made a separate script for fn-lock anyway) and introduce two-step changing.
Thank you A LOT (I really can't express how much) for all your input and work!
That's great! I was gonna tell you to install Windows to a USB using WinToUsb but you got it all figured out.
Changing [0xe4] while on AC power looks like a corner case not really accounted for. Perhaps PC Manager actually changes it in a two-step way, i.e. old->zero->new, but that's only a hypothesis, and there's hardly a way to test it.
Are you on the newest BIOS update? Some people reported broken battery protection on my model while being on an outdated BIOS update.
Could you please provide me the output of sudo dmidecode
. I wanna modify the script even further to detect what machine is running on and based on that it applies the compatible settings.
I'm on BIOS 1.05, which is the newest available on Huawei website (I did fugure out how to update BIOS without Windows, it's documented in README of this repo, if you're interested).
And here you go: dmidecode.gz
Keep up the awesome work! I can hardly be of any more use (other than testing, perhaps), but if someone is ever going to write a proper natacpi driver for these batteries, I guess it would be you.
I'm on BIOS 1.05, which is the newest available on Huawei website (I did fugure out how to update BIOS without Windows, it's documented in README of this repo, if you're interested).
That actually worked! You're a genius thank you. I've been trying to find a way for a while. I got to extracting the capsule using InsydeImageExtractor but that was it. You nailed it down.
Keep up the awesome work! I can hardly be of any more use (other than testing, perhaps), but if someone is ever going to write a proper natacpi driver for these batteries, I guess it would be you.
I will try my best whenever I get free time.
I will close this issue and the other one since we figured out how it works. I will message you whenever if I need more information. Thank you again!
- Changing [0xe4] while on AC power looks like a corner case not really accounted for. Perhaps PC Manager actually changes it in a two-step way, i.e. old->zero->new, but that's only a hypothesis, and there's hardly a way to test it.
One more thing about this: I have explicitly asked windows-running guys to test this thing, and they report [0x9c] flipping to 0x80 and charging starting "immediately" when switching PC Manager preset from "40-70" to "95-100". There's a possibility I still am missing something about this. Anyway, with what info is available, two-step switching looks like a viable option.
One more thing about this: I have explicitly asked windows-running guys to test this thing, and they report [0x9c] flipping to 0x80 and charging starting "immediately" when switching PC Manager preset from "40-70" to "95-100". There's a possibility I still am missing something about this. Anyway, with what info is available, two-step switching looks like a viable option.
Yeah, that's a possibility. I'm working on updating the script. I'll notify you whenever its ready
Mine already is. ;)
Hey! Could you please try this script for setting charging/discharging thresholds. I got it to work on my matebook x pro 2018 it would be really nice to test it on another device. Thanks!