aymanbagabas/Huawei-WMI

BAT1 instead of BAT0 on Matebook D 14" AMD (KPL-W0X)

n3vu0r opened this issue · 19 comments

Hi, I'm on a Matebook D 14" AMD KPL-W0X and tried the latest master branch of this driver with kernel 5.2.14 and the driver fails to register the battery extension:

$ dmesg -t
...
input: Huawei WMI hotkeys as /devices/platform/huawei-wmi/input/input14
battery: extension failed to load: Huawei Battery Extension
battery: extension unregistered: Huawei Battery Extension
...

The driver checks against BAT0, but I'm having a BAT1 instead.

$ ls /sys/class/power_supply/
ACAD BAT1

I've changed BAT0 to BAT1 in line 438 of huawei-wmi.c and it seems to work then.

That's strange, you should have a BAT0 in your system this might indicate an ACPI detection error. Do you get any error messages in your dmesg? dmesg|grep -i acpi. Huawei laptops come with one battery only, that's why the battery extension fails. Do you use any acpi module parameters? i.e. acpi_osi in your cmdline? Sometimes this causes ACPI weirdness. Check out this

I might change it to have both battery hooks and sysfs charge_control_thresholds under /sys/devices/platform/huawei-wmi. Although the issue you’re having is not driver related, first detected battery should be named BAT0 so it’s a kernel or other module problem that should be investigated more.

My command line parameters are:

vga=current ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 iommu=pt idle=nomwait acpi_backlight=vendor acpi_enforce_resources=lax scsi_mod.use_blk_mq=1 quiet splash

Mainly to fix some IOMMU errors. I'm not sure if ACPI is working correctly:

[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-5.2.14-vanilla root=UUID=7a46970d-bf0e-4fcc-bdd6-f21ba6da83fa ro vga=current ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 iommu=pt idle=nomwait acpi_backlight=vendor acpi_enforce_resources=lax scsi_mod.use_blk_mq=1 quiet splash
[    0.000000] BIOS-e820: [mem 0x0000000009f00000-0x0000000009f09fff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000008d7bf000-0x000000008f7befff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000008f7bf000-0x000000008f7fefff] ACPI data
[    0.000000] efi:  ACPI 2.0=0x8f7fe014  SMBIOS=0x8c4ed000  SMBIOS 3.0=0x8c4eb000  ESRT=0x8c4e9c18  MEMATTR=0x88da9018 
[    0.005435] ACPI: Early table checksum verification disabled
[    0.005438] ACPI: RSDP 0x000000008F7FE014 000024 (v02 HUAWEI)
[    0.005441] ACPI: XSDT 0x000000008F7CE188 0000E4 (v01 HUAWEI Tambouri 00000001      01000013)
[    0.005445] ACPI: FACP 0x000000008F7EF000 00010C (v05 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005449] ACPI: DSDT 0x000000008F7E1000 0072B0 (v01 HUAWEI Tambouri 00040000 ACPI 00040000)
[    0.005452] ACPI: FACS 0x000000008F39B000 000040
[    0.005453] ACPI: UEFI 0x000000008F7FD000 000236 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005455] ACPI: MSDM 0x000000008F7FC000 000055 (v03 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005457] ACPI: SSDT 0x000000008F7F6000 005367 (v02 HUAWEI Tambouri 00000002 ACPI 00040000)
[    0.005459] ACPI: SSDT 0x000000008F7F4000 00119C (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005461] ACPI: CRAT 0x000000008F7F3000 000810 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005463] ACPI: CDIT 0x000000008F7F2000 000029 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005464] ACPI: ASF! 0x000000008F7F1000 0000A5 (v32 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005466] ACPI: BOOT 0x000000008F7F0000 000028 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005468] ACPI: HPET 0x000000008F7EE000 000038 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005470] ACPI: APIC 0x000000008F7ED000 000138 (v03 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005471] ACPI: MCFG 0x000000008F7EC000 00003C (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005473] ACPI: WSMT 0x000000008F7EA000 000028 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005475] ACPI: UEFI 0x000000008F7E9000 000042 (v01 HUAWEI Tambouri 00000000 ACPI 00040000)
[    0.005477] ACPI: VFCT 0x000000008F7D3000 00D484 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005478] ACPI: SSDT 0x000000008F7D2000 00046D (v01 HUAWEI Tambouri 00001000 ACPI 00040000)
[    0.005480] ACPI: TPM2 0x000000008F7D1000 000034 (v04 HUAWEI Tambouri 00000002 ACPI 00040000)
[    0.005482] ACPI: IVRS 0x000000008F7D0000 0000D0 (v02 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005484] ACPI: SSDT 0x000000008F7CF000 0008C5 (v01 HUAWEI Tambouri 00001000 ACPI 00040000)
[    0.005485] ACPI: SSDT 0x000000008F7CD000 000E96 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005487] ACPI: SSDT 0x000000008F7CC000 000850 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005489] ACPI: SSDT 0x000000008F7CA000 001993 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005491] ACPI: FPDT 0x000000008F7C9000 000044 (v01 HUAWEI Tambouri 00000002 ACPI 00040000)
[    0.005492] ACPI: BGRT 0x000000008F7EB000 000038 (v01 HUAWEI Tambouri 00000001 ACPI 00040000)
[    0.005498] ACPI: Local APIC address 0xfee00000
[    0.026388] ACPI: PM-Timer IO Port: 0x408
[    0.026391] ACPI: Local APIC address 0xfee00000
[    0.026397] ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
[    0.026398] ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
[    0.026399] ACPI: LAPIC_NMI (acpi_id[0x02] high edge lint[0x1])
[    0.026399] ACPI: LAPIC_NMI (acpi_id[0x03] high edge lint[0x1])
[    0.026400] ACPI: LAPIC_NMI (acpi_id[0x04] high edge lint[0x1])
[    0.026400] ACPI: LAPIC_NMI (acpi_id[0x05] high edge lint[0x1])
[    0.026400] ACPI: LAPIC_NMI (acpi_id[0x06] high edge lint[0x1])
[    0.026401] ACPI: LAPIC_NMI (acpi_id[0x07] high edge lint[0x1])
[    0.026401] ACPI: LAPIC_NMI (acpi_id[0x08] high edge lint[0x1])
[    0.026402] ACPI: LAPIC_NMI (acpi_id[0x09] high edge lint[0x1])
[    0.026402] ACPI: LAPIC_NMI (acpi_id[0x0a] high edge lint[0x1])
[    0.026402] ACPI: LAPIC_NMI (acpi_id[0x0b] high edge lint[0x1])
[    0.026403] ACPI: LAPIC_NMI (acpi_id[0x0c] high edge lint[0x1])
[    0.026403] ACPI: LAPIC_NMI (acpi_id[0x0d] high edge lint[0x1])
[    0.026404] ACPI: LAPIC_NMI (acpi_id[0x0e] high edge lint[0x1])
[    0.026404] ACPI: LAPIC_NMI (acpi_id[0x0f] high edge lint[0x1])
[    0.026437] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.026438] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
[    0.026439] ACPI: IRQ0 used by override.
[    0.026439] ACPI: IRQ9 used by override.
[    0.026441] Using ACPI (MADT) for SMP configuration information
[    0.026442] ACPI: HPET id: 0x10228210 base: 0xfed00000
[    0.096066] Kernel command line: BOOT_IMAGE=/vmlinuz-5.2.14-vanilla root=UUID=7a46970d-bf0e-4fcc-bdd6-f21ba6da83fa ro vga=current ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 iommu=pt idle=nomwait acpi_backlight=vendor acpi_enforce_resources=lax scsi_mod.use_blk_mq=1 quiet splash
[    0.134948] ACPI: Core revision 20190509
[    0.616294] PM: Registering ACPI NVS region [mem 0x09f00000-0x09f09fff] (40960 bytes)
[    0.616294] PM: Registering ACPI NVS region [mem 0x8d7bf000-0x8f7befff] (33554432 bytes)
[    0.619531] ACPI: bus type PCI registered
[    0.619531] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    0.735568] ACPI: Added _OSI(Module Device)
[    0.735568] ACPI: Added _OSI(Processor Device)
[    0.735569] ACPI: Added _OSI(3.0 _SCP Extensions)
[    0.735570] ACPI: Added _OSI(Processor Aggregator Device)
[    0.735571] ACPI: Added _OSI(Linux-Dell-Video)
[    0.735572] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
[    0.735572] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
[    0.737775] ACPI: [Firmware Bug]: BIOS _OSI(Linux) query ignored
[    0.744848] ACPI: 8 ACPI AML tables successfully acquired and loaded
[    0.747205] ACPI: EC: EC started
[    0.747206] ACPI: EC: interrupt blocked
[    0.748081] ACPI: \_SB_.PCI0.LPC0.EC0_: Used as first EC
[    0.748083] ACPI: \_SB_.PCI0.LPC0.EC0_: GPE=0x3, EC_CMD/EC_SC=0x66, EC_DATA=0x62
[    0.748084] ACPI: \_SB_.PCI0.LPC0.EC0_: Boot DSDT EC used to handle transactions
[    0.748084] ACPI: Interpreter enabled
[    0.748100] ACPI: (supports S0 S3 S4 S5)
[    0.748101] ACPI: Using IOAPIC for interrupt routing
[    0.748390] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.748575] ACPI: Enabled 2 GPEs in block 00 to 1F
[    0.750477] ACPI: Power Resource [P0ST] (on)
[    0.750506] ACPI: Power Resource [P3ST] (on)
[    0.753722] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.753727] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
[    0.753836] acpi PNP0A08:00: _OSC: platform does not support [SHPCHotplug LTR]
[    0.753936] acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME AER PCIeCapability]
[    0.753946] acpi PNP0A08:00: [Firmware Info]: MMCONFIG for domain 0000 [bus 00-3f] only partially covers this bridge
[    0.761163] ACPI: PCI Interrupt Link [LNKA] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761231] ACPI: PCI Interrupt Link [LNKB] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761281] ACPI: PCI Interrupt Link [LNKC] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761347] ACPI: PCI Interrupt Link [LNKD] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761405] ACPI: PCI Interrupt Link [LNKE] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761451] ACPI: PCI Interrupt Link [LNKF] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761497] ACPI: PCI Interrupt Link [LNKG] (IRQs 3 5 6 10 11) *0, disabled.
[    0.761543] ACPI: PCI Interrupt Link [LNKH] (IRQs 3 5 6 10 11) *0, disabled.
[    0.762125] ACPI: EC: interrupt unblocked
[    0.762143] ACPI: EC: event unblocked
[    0.762171] ACPI: \_SB_.PCI0.LPC0.EC0_: GPE=0x3, EC_CMD/EC_SC=0x66, EC_DATA=0x62
[    0.762172] ACPI: \_SB_.PCI0.LPC0.EC0_: Boot DSDT EC used to handle transactions and events
[    2.655552] PCI: Using ACPI for IRQ routing
[    2.673075] pnp: PnP ACPI init
[    2.673295] system 00:00: Plug and Play ACPI device, IDs PNP0c02 (active)
[    2.673423] pnp 00:01: Plug and Play ACPI device, IDs PNP0b00 (active)
[    2.673448] pnp 00:02: Plug and Play ACPI device, IDs PNP0303 (active)
[    2.673474] pnp 00:03: Plug and Play ACPI device, IDs ETD2203 PNP0f13 (active)
[    2.673524] system 00:04: Plug and Play ACPI device, IDs PNP0c02 (active)
[    2.673576] system 00:05: Plug and Play ACPI device, IDs PNP0c01 (active)
[    2.674057] pnp: PnP ACPI: found 6 devices
[    2.683939] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    3.490003] ACPI: Power Button [PWRB]
[    3.490188] ACPI: Lid Switch [LID0]
[    3.490267] ACPI: Power Button [PWRF]
[    3.493097] ACPI: Video Device [VGA1] (multi-head: yes  rom: no  post: no)
[    3.493308] ACPI: Video Device [VGA2] (multi-head: yes  rom: no  post: no)
[   48.354094] ACPI: AC Adapter [ACAD] (on-line)
[   48.354604] acpi_cpufreq: overriding BIOS provided _PSD data
[   48.387252] battery: ACPI: Battery Slot [BAT1] (battery present)
[   48.433407] ACPI: bus type USB registered

Maybe try it without acpi_backlight=vendor acpi_enforce_resources=lax

It makes no difference, it's still at battery slot BAT1.

All the entries in /sys/class/power_supply/BAT1/ are working. The BIOS is the latest version 1.22.

Hey, I've updated master branch to reflect this issue. I've also added back the attribute under /sys/devices/platform/huawei-wmi as charge_control_thresholds.

@nekr0z you might wanna add that to your matebook-applet. Basically to detect all of /sys/class/power_supply/BATn/charge_control_{start,end}_threshold, /sys/devices/platform/huawei-wmi/charge_thresholds (for older versions maybe mark it as deprecated), and /sys/devices/platform/huawei-wmi/charge_control_thresholds.

I'm still curious about this behavior and why you're getting BAT1 instead of BAT0 even though one battery is present.

Will do. I actually did a big refactor this week for these kind of things to easily be made possible, so should be done by Tuesday, if not tomorrow. Right now, the applet scans for available endpoints in /sys/class/power_supply/BAT0/charge_control_{start,end}_threshold, /sys/devices/platform/huawei-wmi/charge_thresholds and, as a last resort, looks for a script (in that order). I'll add the scanning for different values of n in BATn and /sys/devices/platform/huawei-wmi/charge_control_thresholds as the second option, looks like this should cover all the bases.

Ok, applet v2.1.2 is out with support for all the aforementioned variants of thresholds location. :-) I must admit I only did a very limited amount of testing, so if anyone sees undesired behaviour and files a bug, that would be most welcome.
The applet is supposed to find whatever the endpoint location is and use it automatically. If the found endpoint happens to be read-only, the applet is supposed to keep looking for alternatives before falling back to read-only mode.
And yes, backwards-compatible with older versions.

Great, thank you! The updated driver works. I have now the files /sys/class/power_supply/BAT1/charge_control_{start,end}_threshold and /sys/devices/platform/huawei-wmi/charge_control_thresholds.

Since you've added back the combined file, I'm wondering which is now the preferred way to set thresholds? I assume it's the new battery API but I remember there were some quirks for some Huawei models, were only certain combinations of start and end thresholds are supported, such as 0 100, 95 100, 70 90, and 40 70? Actually, I never tried other combinations. If this is the case, does it matter then when there is a delay between setting the start and the end threshold? Because temporarily it would be an unsupported combination.

While you're at it, I've noticed a funny thing while working on the applet. My model (MB13 2019) wouldn't allow min threshold to be equal or greater than max. This makes it impossible, for example, to go from 40 70 to 70 90 if you're trying to set min before max.
I must admit I opted for a quick and dirty solution: in case the applet deals with two-file endpoint (as opposed to the old behaviour where both thresholds are set simultaneously in one file) it always sets 0 100 before setting whatever the user asked.

Well the way this works is through the WMI api that Huawei provides in the laptops's bios ASL/ACPI code. So it goes OS/Linux -> ACPI/WMI -> EC (hardware level).

The way this WMI function is implemented is to take a low and high value. So my workaround on using the charge control api was to get the currently set values then use that to fill other missing value needed by that function.

Setting min > max, max > 100, min < 0, etc leads to unexpected behavior and I've never tested these edge cases. So, the driver doesn't accept setting min > max here. As long as min <= max, it should let the values through.

if you're using /sys/class/power_supply/BAT1/charge_control_{start,end}_threshold, you have to set the end/max value first. Or use the other endpoint to set both together.

I'm wondering which is now the preferred way to set thresholds?

They're all the same. The /sys/class/power_supply is helpful if you wanna use tools like TLP to manage battery control though I haven't tested that yet. You could set any value from 0-100 for both.

You know what, now that I though about this, I think start > end is wrong.

Let's say you set 40-70 and now you want to set 10-30. If you use the the two-file endpoint you'd have to set start to 10 so it becomes 10-70 and then set end to 30 so it's 10-30. Now if you wanna go the other way, say from 10-30 to 40-70 you'd have to do end => 70 and then start => 40. Otherwise, it would be start > end and it would fail.

Done! start > end check removed.
@n3vu0r feel free to close this if you think it's solved.

Done! start > end check removed.

Hmm... Does this mean we'd better do this check ourselves? Or leave it to WMI/EC to figure this out? The laptops aren't supposed to start exploding when fed insane values, are they?

I'm only asking because I'm thinking of a way to implement setting custom thresholds in the applet. ;)

I understand. So removing this check makes things much easier. You no longer have to figure out which threshold to set first and cannot run into the pitfall of having the driver to (partially) ignore your thresholds because it considered them invalid.

This works if the ACPI/WMI passes both thresholds to EC without any checks and the EC ignores the new thresholds until a valid combination end >= start is present. If this is not the case, or if it is just unknown, the driver could maybe copy this behavior by storing the thresholds for itself and only pass them to the ACPI/WMI as soon as a valid combination is present?

Well, start < 0 and end > 100 are still there and would return invalid. I guess for the applet, you can check if start > end and give an error when that happens. If a user uses the endpoints directly, then they better know they are poking with the system/kernel because it's under /sys. Always assume the user is dumb when doing GUI stuff.

Always assume the user is dumb when doing GUI stuff.

True. Although in my book there should be no capital "G" in this phrase. ;-)

True. Although in my book there should be no capital "G" in this phrase. ;-)

I guess that's true, see my book is old and outdated xD

Ok then :D Checks are done in _UI and all seems to be addressed. I'm closing it, thank you!