[PATCH] ACPI: battery: Add ASUS Vivobook 18 M1807HA status quirk
From: Norman Becker
Date: Sun May 24 2026 - 06:47:00 EST
|
Hello Rafael, Len, and ACPI maintainers,
this is my first Linux kernel patch.
I observed incorrect battery status reporting on my ASUS Vivobook 18 M1807HA.
When AC power is unplugged and ADP0/online reports 0, the battery status may incorrectly oscillate between:
Full
Not charging Discharging
This behavior also caused KDE Plasma energy/power profiles to switch repeatedly.
The attached patch adds a DMI-specific quirk for the ASUS Vivobook 18 M1807HA. When AC power is offline, Full and Not charging are treated as Discharging.
I tested the patch locally on:
ASUSTeK COMPUTER INC.
ASUS Vivobook 18 M1807HA_M1807HA Board: M1807HA
After applying the patch:
I used ChatGPT as an auxiliary learning and review tool while understanding the kernel code and preparing the patch, but I reproduced, tested, and verified the issue and fix myself on real hardware.
Thank you for your time and review.
Best regards,
Norman Becker |
From: Norman Becker <ryleno@xxxxxxxxxx>
Date: Sun, 24 May 2026 11:20:00 +0200
Subject: [PATCH] ACPI: battery: Add ASUS Vivobook 18 M1807HA status quirk
On the ASUS Vivobook 18 M1807HA_M1807HA, the ACPI battery can keep
reporting Full at 100% charge, or Not charging below full charge, after
the AC adapter has been unplugged.
The AC adapter power_supply ADP0 reports the offline state correctly,
while BAT0/status oscillates between Discharging and Full/Not charging:
ADP0=0
BAT0=Full
CAP=100
and:
ADP0=0
BAT0=Not charging
CAP=98
Add a DMI-limited quirk for this system. When ADP0 is offline, report
Full and Not charging battery states as Discharging. Charging and
Unknown are left unchanged.
Tested on ASUS Vivobook 18 M1807HA_M1807HA.
Signed-off-by: Norman Becker <ryleno@xxxxxxxxxx>
---
drivers/acpi/battery.c | 58 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 000000000000..000000000000 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -51,6 +51,7 @@
static int battery_bix_broken_package;
static int battery_notification_delay_ms;
static int battery_ac_is_broken;
+static bool battery_asus_m1807ha_force_discharge;
static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
@@ -194,6 +195,37 @@
return POWER_SUPPLY_STATUS_DISCHARGING;
}
+static bool acpi_battery_asus_m1807ha_ac_offline(void)
+{
+ struct power_supply *psy;
+ union power_supply_propval val;
+ bool offline = false;
+
+ if (!battery_asus_m1807ha_force_discharge)
+ return false;
+
+ psy = power_supply_get_by_name("ADP0");
+ if (!psy)
+ return false;
+
+ if (!power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val))
+ offline = val.intval == 0;
+
+ power_supply_put(psy);
+
+ return offline;
+}
+
+static void acpi_battery_asus_m1807ha_fix_status(union power_supply_propval *val)
+{
+ if (!acpi_battery_asus_m1807ha_ac_offline())
+ return;
+
+ if (val->intval == POWER_SUPPLY_STATUS_FULL ||
+ val->intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+}
+
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -225,6 +257,8 @@
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+
+ acpi_battery_asus_m1807ha_fix_status(val);
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = acpi_battery_present(battery);
@@ -1143,6 +1177,13 @@
return 0;
}
+static int __init
+battery_asus_m1807ha_force_discharge_quirk(const struct dmi_system_id *d)
+{
+ battery_asus_m1807ha_force_discharge = true;
+ return 0;
+}
+
static const struct dmi_system_id bat_dmi_table[] __initconst = {
{
/* NEC LZ750/LS */
@@ -1179,6 +1220,19 @@
DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"),
},
},
+ {
+ /*
+ * The firmware reports BAT0 as Full or Not charging after AC
+ * has been unplugged. ADP0 correctly reports offline.
+ */
+ .callback = battery_asus_m1807ha_force_discharge_quirk,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASUS Vivobook 18 M1807HA_M1807HA"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ASUS Vivobook 18"),
+ DMI_MATCH(DMI_BOARD_NAME, "M1807HA"),
+ },
+ },
{},
};
--
2.50.0