linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Work around negative s16 battery current on Acer
@ 2009-07-01 18:20 Hector Martin
  2009-07-01 18:27 ` Alexey Starikovskiy
  2009-07-01 18:29 ` Andrew Morton
  0 siblings, 2 replies; 8+ messages in thread
From: Hector Martin @ 2009-07-01 18:20 UTC (permalink / raw)
  To: Alexey Starikovskiy, Len Brown; +Cc: linux-acpi, Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 836 bytes --]

My Acer Aspire 8930G laptop reports the battery current as a 16-bit
signed negative when it is charging. It also reports it as 0x10000 when
the current is 0. This patch adds a quirk for this which takes the
absolute value of the reported current cast to an s16. This is a DSDT
bug present in the latest BIOS revision (the EC register is 16 bits
signed and the DSDT attempts to take the 16-bit two's complement of
this, which works for discharge but not charge. It also breaks zero
values because a 32-bit register is used and the high bits aren't thrown
away).

I've enabled this for all Acer systems which report in mA units. This
should be safe since it won't break compliant systems unless they report
a current above 32A, which is insane.

-- 
Hector Martin (hector@marcansoft.com)
Public Key: http://www.marcansoft.com/marcan.asc


[-- Attachment #2: acpi-battery-acer-rate-quirk.patch --]
[-- Type: text/plain, Size: 1482 bytes --]

Signed-off-by: Hector Martin <hector@marcansoft.com>
--- linux/drivers/acpi/battery.c.old	2009-07-01 19:17:33.000000000 +0200
+++ linux/drivers/acpi/battery.c	2009-07-01 19:52:43.000000000 +0200
@@ -84,6 +84,10 @@
 
 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
+/* For buggy DSDTs that report negative 16-bit values for either charging
+ * or discharging and/or report 0 as 65536 due to bad math.
+ */
+#define QUIRK_SIGNED16_CURRENT 0x0001
 
 struct acpi_battery {
 	struct mutex lock;
@@ -111,6 +115,7 @@
 	int state;
 	int power_unit;
 	u8 alarm_present;
+	long quirks;
 };
 
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -387,6 +392,10 @@
 				 state_offsets, ARRAY_SIZE(state_offsets));
 	battery->update_time = jiffies;
 	kfree(buffer.pointer);
+
+	if (battery->quirks & QUIRK_SIGNED16_CURRENT)
+		battery->current_now = abs((s16)battery->current_now);
+
 	return result;
 }
 
@@ -492,6 +501,14 @@
 }
 #endif
 
+static void acpi_battery_quirks(struct acpi_battery *battery)
+{
+	battery->quirks = 0;
+	if (dmi_name_in_vendors("Acer") && battery->power_unit) {
+		battery->quirks |= QUIRK_SIGNED16_CURRENT;
+	}
+}
+
 static int acpi_battery_update(struct acpi_battery *battery)
 {
 	int result, old_present = acpi_battery_present(battery);
@@ -510,6 +527,7 @@
 		result = acpi_battery_get_info(battery);
 		if (result)
 			return result;
+		acpi_battery_quirks(battery);
 		acpi_battery_init_alarm(battery);
 	}
 #ifdef CONFIG_ACPI_SYSFS_POWER

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-07-02 23:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-01 18:20 [PATCH] Work around negative s16 battery current on Acer Hector Martin
2009-07-01 18:27 ` Alexey Starikovskiy
2009-07-01 18:29 ` Andrew Morton
2009-07-01 18:38   ` Alexey Starikovskiy
2009-07-01 20:19     ` Hector Martin
2009-07-02  3:51   ` Hector Martin
2009-07-02 22:56     ` Andrew Morton
2009-07-02 23:46       ` [PATCH] Work around negative s16 battery current on Acer (take 3) Hector Martin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).