https://bugzilla.kernel.org/show_bug.cgi?id=221503
Bug ID: 221503
Summary: ACPI: battery: BAT0/status flaps Discharging↔"Not
charging" while ADP0/online=0 on ASUS Vivobook 18
M1807HA
Product: ACPI
Version: 2.5
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P3
Component: Power-Battery
Assignee: [email protected]
Reporter: [email protected]
Regression: No
# BAT0/status flaps Discharging↔Not charging on ASUS Vivobook 18 M1807HA — and
reports "Not charging" while ADP0/online=0 (logically impossible)
## TL;DR
On an ASUS Vivobook 18 M1807HA (AMD Ryzen AI platform) running Ubuntu 26.04
with kernel 7.0.0-15-generic, `/sys/class/power_supply/BAT0/status` flaps
between `Discharging` and `Not charging` roughly every 5–20 seconds while the
laptop is running on battery (`ADP0/online=0`). The current ACPI/EC
implementation also reports the impossible state `BAT0/status="Not charging"`
while `ADP0/online=0` — `Not charging` is only meaningful when AC is connected.
UPower observes each transition and emits `PropertiesChanged` on D-Bus, which
`gnome-settings-daemon` interprets as physical AC plug/unplug events and plays
`power-plug.oga` / `power-unplug.oga` every 30–120 seconds.
The same hardware does **not** exhibit this behavior on Windows 11. The flap
reproduces on Ubuntu 22.04, 24.04, 25.x, and 26.04 (this report). It is **not**
fixed by BIOS update from M1807HA.318 (2025-09-26) to the latest M1807HA.321
(2026-01-19).
## Affected hardware
| Field | Value |
|---|---|
| sys_vendor | ASUSTeK COMPUTER INC. |
| product_name | ASUS Vivobook 18 M1807HA_M1807HA |
| product_family | ASUS Vivobook 18 |
| board_name | M1807HA |
| bios_vendor | American Megatrends International, LLC. |
| bios_version | M1807HA.321 |
| bios_date | 01/19/2026 |
| bios_release | 5.29 (SMBIOS) |
| CPU | AMD Ryzen AI |
| Purchased | January 2026 |
## Software
| Field | Value |
|---|---|
| Distro | Ubuntu 26.04 LTS "resolute" |
| Kernel | Linux 7.0.0-15-generic #15-Ubuntu SMP PREEMPT_DYNAMIC Wed Apr 22
16:06:43 UTC 2026 x86_64 |
| Desktop | GNOME (default) |
| Sound theme | Yaru (default Ubuntu) |
| Loaded ASUS modules | asus_wmi, asus_nb_wmi, asus_armoury, wmi_bmof,
sparse_keymap |
## Symptom 1 — Impossible state combination
While running on battery (AC unplugged), `BAT0/status` is observed to report
`Not charging`:
```
$ cat /sys/class/power_supply/ADP0/online
0
$ cat /sys/class/power_supply/BAT0/status
Not charging
```
Per the kernel power-supply documentation, valid `status` values are `Unknown |
Charging | Discharging | Not charging | Full`. `Not charging` is only
meaningful when AC is connected (battery present, AC online, but charger has
stopped — e.g. battery full or charge-limit reached). It is logically
inconsistent with `ADP0/online=0`. The expected value with no AC connected is
`Discharging`.
## Symptom 2 — Flap rate
A 180-second sample at 5-second intervals while on battery, on BIOS 321, kernel
7.0.0-15:
```
14:20:14 ADP=0 STATUS=Not charging current=484000
14:20:19 ADP=0 STATUS=Discharging current=809000
14:20:24 ADP=0 STATUS=Discharging current=992000
14:20:29 ADP=0 STATUS=Discharging current=860000
14:20:34 ADP=0 STATUS=Not charging current=691000
14:20:39 ADP=0 STATUS=Not charging current=546000
14:20:44 ADP=0 STATUS=Not charging current=438000
14:20:49 ADP=0 STATUS=Not charging current=428000
14:20:54 ADP=0 STATUS=Discharging current=838000
14:20:59 ADP=0 STATUS=Discharging current=1554000
14:21:04 ADP=0 STATUS=Not charging current=1688000
14:21:09 ADP=0 STATUS=Not charging current=968000
14:21:14 ADP=0 STATUS=Not charging current=703000
14:21:19 ADP=0 STATUS=Discharging current=905000
14:21:24 ADP=0 STATUS=Discharging current=811000
14:21:29 ADP=0 STATUS=Discharging current=814000
14:21:34 ADP=0 STATUS=Discharging current=1453000
14:21:39 ADP=0 STATUS=Not charging current=1453000
14:21:44 ADP=0 STATUS=Not charging current=1925000
14:21:49 ADP=0 STATUS=Not charging current=2148000
14:21:54 ADP=0 STATUS=Discharging current=2071000
... (36 samples total, 11 transitions)
```
Result: **11 status transitions in 180 seconds** (one every ~16 sec on
average). `ADP0/online` is rock-stable at 0 the whole time — the AC side is
fine; only `BAT0/status` flips.
Note: the flip is **not** a clean current threshold. Both states are seen at
low and high current_now values (`Not charging` at 2148 mA, `Discharging` at
683 mA). The EC's `_BST.ACPI_BATTERY_STATE` bitmap appears to oscillate on its
own, not as a function of `current_now`.
## Symptom 3 — Other EC oddities (corroborating evidence of a buggy EC
firmware)
```
manufacturer = "AS3FZFd3jC" # garbage string, not a real vendor name
model_name = "X160745" # OK
serial_number = "1B7E" # short, suspicious
technology = "Unknown" # should be "Li-ion"
cycle_count = 0 # impossible — laptop in daily use
since Jan 2026
voltage_now = 15103000 # 15.10 V — BELOW voltage_min_design
voltage_min_design = 15860000 # 15.86 V
```
A healthy battery cannot operate below `voltage_min_design`; the laptop would
have shut down. So either `voltage_now` or `voltage_min_design` is wrong as
exposed by the EC's ACPI methods.
Additional dmesg/kernel hints reported elsewhere on this platform:
- `asus_armoury: No matching power limits found for this system`
- `asus_wmi: Unknown key code 0xec`
## Why this matters from userspace
UPower polls `BAT0` every 30 seconds (`NoPollBatteries=false` is the default).
Each new `status` value triggers a D-Bus `PropertiesChanged` signal.
`gnome-settings-daemon`'s power plugin maps `Discharging → Not charging` to "AC
plug-in" and `Not charging → Discharging` to "AC plug-out", and plays
`power-plug.oga` / `power-unplug.oga` from the active sound theme. The user
hears a phantom plug/unplug sound every 30–120 seconds while on battery.
The kernel-side defect is the inconsistent `status` field; the GNOME audio side
is a downstream consequence.
## Reproducer
```bash
#!/bin/bash
# Sample BAT0/status while on battery
LOG=/tmp/bat_flip_test.log
> "$LOG"
while [ "$(cat /sys/class/power_supply/ADP0/online)" = "1" ]; do sleep 1; done
echo "AC unplugged at $(date '+%H:%M:%S'). Sampling for 180s every 5s."
SAMPLES=()
END=$(($(date +%s) + 180))
while [ "$(date +%s)" -lt "$END" ]; do
S=$(cat /sys/class/power_supply/BAT0/status)
A=$(cat /sys/class/power_supply/ADP0/online)
I=$(cat /sys/class/power_supply/BAT0/current_now)
echo "$(date '+%H:%M:%S') ADP=$A STATUS=$S current=$I" | tee -a "$LOG"
SAMPLES+=("$S")
sleep 5
done
FLIPS=0; PREV=""
for s in "${SAMPLES[@]}"; do
[ -n "$PREV" ] && [ "$s" != "$PREV" ] && FLIPS=$((FLIPS+1))
PREV="$s"
done
echo "Status flips: $FLIPS"
```
## What was ruled out
- **Real hardware AC plug bouncing** — `ADP0/online` stays at 0 throughout the
flap.
- **Polling timing artifacts in userspace** — sampling at 5 sec sees the same
`status` value across multiple consecutive reads of
`/sys/class/power_supply/BAT0/status`, so the kernel/EC is actually returning
different values at different moments, not a userspace race.
- **BIOS firmware bug fixable by ASUS** — BIOS 321 (latest, 2026-01-19) tested
with identical 11/180s flip rate as BIOS 318.
- **UCSI/USB-C PD interaction** — `ucsi-source-psy-USBC000:001`/`:002` exist
but are independent power-supply objects; their online state does not change
during the flap.
- **`asus_wmi` / ASUS Battery Extension hook** — `modprobe -r asus_armoury
asus_nb_wmi mfd_aaeon asus_wmi` performed. dmesg confirmed `ACPI: battery: hook
unregistered: ASUS Battery Extension` and `asus_wmi: ASUS WMI generic driver
unloaded`. 180-sec flap test with hook detached: 12 flips (vs 11 with hook
attached, i.e. unchanged within noise). The flap also occurs with the
asus-specific stack fully unloaded, so this is **not** an ASUS-platform-driver
issue.
## Critical diagnostic — flap is NOT interrupt-driven
A correlation test sampled both `BAT0/status` and the EC's GPE counter
(`/sys/firmware/acpi/interrupts/gpe0A`, the GPE used by the EC per boot dmesg
`ACPI: EC: GPE=0xa`) every 5 seconds for 90 seconds:
```
14:32:22 gpe0A=224 ADP=0 STATUS=Not charging
14:32:27 gpe0A=224 ADP=0 STATUS=Discharging ← flip 1, GPE unchanged
14:32:48 gpe0A=224 ADP=0 STATUS=Not charging ← flip 2, GPE unchanged
14:32:58 gpe0A=224 ADP=0 STATUS=Discharging ← flip 3, GPE unchanged
14:33:13 gpe0A=226 ADP=0 STATUS=Not charging ← flip 4, +2 GPE
14:33:18 gpe0A=228 ADP=0 STATUS=Not charging (no flip, +2 GPE)
14:33:23 gpe0A=232 ADP=0 STATUS=Not charging (no flip, +4 GPE)
14:33:33 gpe0A=232 ADP=0 STATUS=Discharging ← flip 5, GPE unchanged
14:33:48 gpe0A=232 ADP=0 STATUS=Not charging ← flip 6, GPE unchanged
```
Result over 90 sec: **6 status flips, 8 total GPE0A events**, with no temporal
correlation between them. The first three flips happened while gpe0A was
completely idle. The GPE bursts at 14:33:13–14:33:23 produced only one of the
six flips.
**Conclusion:** the EC is not generating `Notify(BAT0, 0x80)` events when the
status changes. The status changes only because the EC's `_BST` ACPI method
returns oscillating values on each successive read. This is purely a polling
artifact, observable any time userspace (UPower, anyone) reads
`/sys/class/power_supply/BAT0/status` while on battery.
This dramatically simplifies the kernel fix: there's no need to debounce
against an interrupt stream. A DMI quirk in `drivers/acpi/battery.c` can simply
normalize the value: **if AC is offline and the EC returns `Not charging`,
override it to `Discharging` before exposing it to userspace.** This matches
both the spec (`Not charging` is undefined without AC) and physical reality.
## Suspected root cause
The ACPI `_BST` (battery status) method in the EC firmware returns a status
bitmap whose "discharging" bit oscillates while on battery. This is independent
of `current_now` magnitude and independent of any real hardware event. The
Linux kernel's `drivers/acpi/battery.c` faithfully translates this bit to the
`status` sysfs string, propagating the EC's nonsense upward.
A kernel-side fix would be a DMI-matched quirk in `drivers/acpi/battery.c`
that:
1. Suppresses `Not charging` and substitutes `Discharging` when no AC adapter
is online (the platform-driver code is confirmed innocent — the asus stack was
unloaded with the bug still present), or
2. Debounces `BAT0/status` changes for some window (e.g., 60 sec) when they are
not corroborated by an AC-side transition.
Option (1) is more correct: `Not charging` while AC is offline is never a valid
state per the power-supply class documentation, and the kernel can safely
normalize it without losing information.
## Workaround in use
Empty `power-plug.oga` and `power-unplug.oga` override files placed in
`~/.local/share/sounds/Yaru/stereo/`. libcanberra finds the empty user-scope
file first, fails to decode, and silently plays nothing. No system-wide
changes, no UPower configuration change. This silences the symptom but does not
fix the underlying kernel/EC defect.
## Diagnostic data
Relevant boot dmesg lines (full grep `dmesg | grep -iE "asus|batter|acpi|EC[:
]"` attached):
```
ACPI: EC: GPE=0xa
ACPI: \_SB_.PCI0.SBRG.EC0_: Boot DSDT EC initialization complete
ACPI: \_SB_.PCI0.SBRG.EC0_: EC: Used to handle transactions and events
ACPI: AC: AC Adapter [ADP0] (on-line)
ACPI: battery: Slot [BAT0] (battery present)
asus_wmi: ASUS WMI generic driver loaded
asus_armoury: No matching power limits found for this system
asus_wmi: Initialization: 0x1
asus_wmi: SFUN value: 0x21
asus-nb-wmi: Detected ATK, not ASUSWMI, use DSTS
asus-nb-wmi: Using throttle_thermal_policy for platform_profile support
asus_wmi: fan_curve_get_factory_default (0x00110024) failed: -19
asus_wmi: fan_curve_get_factory_default (0x00110025) failed: -19
asus_wmi: fan_curve_get_factory_default (0x00110032) failed: -19
ACPI: battery: new hook: ASUS Battery Extension
```
Note in particular: `ACPI: battery: new hook: ASUS Battery Extension` — this is
`asus_wmi` registering a hook into `drivers/acpi/battery.c`
(`battery_hook_register`). To isolate it, the asus stack was fully unloaded
(`modprobe -r asus_armoury asus_nb_wmi mfd_aaeon asus_wmi`); dmesg confirmed
both `ACPI: battery: hook unregistered: ASUS Battery Extension` and `asus_wmi:
ASUS WMI generic driver unloaded`. The flap was unchanged (12 flips / 180 sec)
→ the hook is not responsible. The defect is in the path between userspace and
the EC's `_BST` method, i.e. core `drivers/acpi/battery.c` returning the EC's
bad value verbatim.
ACPI GPE counters since boot (non-zero only):
```
gpe0A: 232 EN enabled unmasked
gpe_all: 232
sci: 232
```
GPE 0xA is the EC's GPE. Total ACPI SCI activity since boot is exclusively from
the EC (gpe_all == sci == gpe0A). All other GPEs are idle.
Suggested additional attachments by reporter on request:
- `acpidump > acpi.bin && acpixtract -a acpi.bin && iasl -d *.dat` —
disassembled DSDT/SSDT including the `_BST` method body
- Full `/sys/class/power_supply/BAT0/*` dump
- Full 36-sample log of the 180-sec reproducer (`/tmp/bat_flip_test.log`)
## Related reports
- Ubuntu Launchpad bug #2029902 — "ASUS laptop charging connect/disconnect"
(similar symptom, different ASUS model)
- ArchWiki "Laptop/ASUS"
- Framework community "Battery flipping" thread — similar UPower symptom,
different root cause
## Where to file
1. **kernel.org Bugzilla** → Product: ACPI, Component: Power-Battery — primary
report. The `asus_wmi` ruling-out means this should go to the ACPI battery
maintainers, not the x86-platform / ASUS tree.
2. **linux-acpi mailing list** ([email protected]) — cross-post a
brief summary linking to the bugzilla entry. Maintainers prefer mail traffic to
bugzilla-only reports.
3. **Ubuntu Launchpad** → package: `linux` — for distribution-level tracking;
link to the kernel.org bug.
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
_______________________________________________
acpi-bugzilla mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/acpi-bugzilla