linux/drivers/acpi
Kamil Iskra 4000e62615 ACPI / battery: Correct battery capacity values on Thinkpads
Add a quirk to correctly report battery capacity on 2010 and 2011
Lenovo Thinkpad models.

The affected models that I tested (x201, t410, t410s, and x220)
exhibit a problem where, when battery capacity reporting unit is mAh,
the values being reported are wrong.  Pre-2010 and 2012 models appear
to always report in mWh and are thus unaffected.  Also, in mid-2012
Lenovo issued a BIOS update for the 2011 models that fixes the issue
(tested on x220 with a post-1.29 BIOS).  No such update is available
for the 2010 models, so those still need this patch.

Problem description: for some reason, the affected Thinkpads switch
the reporting unit between mAh and mWh; generally, mAh is used when a
laptop is plugged in and mWh when it's unplugged, although a
suspend/resume or rmmod/modprobe is needed for the switch to take
effect.  The values reported in mAh are *always* wrong.  This does
not appear to be a kernel regression; I believe that the values were
never reported correctly.  I tested back to kernel 2.6.34, with
multiple machines and BIOS versions.

Simply plugging a laptop into mains before turning it on is enough to
reproduce the problem.  Here's a sample /proc/acpi/battery/BAT0/info
from Thinkpad x220 (before a BIOS update) with a 4-cell battery:

present:                 yes
design capacity:         2886 mAh
last full capacity:      2909 mAh
battery technology:      rechargeable
design voltage:          14800 mV
design capacity warning: 145 mAh
design capacity low:     13 mAh
cycle count:              0
capacity granularity 1:  1 mAh
capacity granularity 2:  1 mAh
model number:            42T4899
serial number:           21064
battery type:            LION
OEM info:                SANYO

Once the laptop switches the unit to mWh (unplug from mains, suspend,
resume), the output changes to:

present:                 yes
design capacity:         28860 mWh
last full capacity:      29090 mWh
battery technology:      rechargeable
design voltage:          14800 mV
design capacity warning: 1454 mWh
design capacity low:     200 mWh
cycle count:              0
capacity granularity 1:  1 mWh
capacity granularity 2:  1 mWh
model number:            42T4899
serial number:           21064
battery type:            LION
OEM info:                SANYO

Can you see how the values for "design capacity", etc., differ by a
factor of 10 instead of 14.8 (the design voltage of this battery)?
On the battery itself it says: 14.8V, 1.95Ah, 29Wh, so clearly the
values reported in mWh are correct and the ones in mAh are not.

My guess is that this problem has been around ever since those
machines were released, but because the most common Thinkpad
batteries are rated at 10.8V, the error (8%) is small enough that it
simply hasn't been noticed or at least nobody could be bothered to
look into it.

My patch works around the problem by adjusting the incorrectly
reported mAh values by "10000 / design_voltage".  The patch also has
code to figure out if it should be activated or not.  It only
activates on Lenovo Thinkpads, only when the unit is mAh, and, as an
extra precaution, only when the battery capacity reported through
ACPI does not match what is reported through DMI (I've never
encountered a machine where the first two conditions would be true
but the last would not, but better safe than sorry).

I've been using this patch for close to a year on several systems
without any problems.

References: https://bugzilla.kernel.org/show_bug.cgi?id=41062
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2012-11-16 22:28:58 +01:00
..
acpica ACPICA: Table Manager: Merge duplicate code (root table) 2012-09-21 00:35:12 -04:00
apei ACPI, APEI: Fixup common access width firmware bug 2012-07-14 11:01:42 -04:00
ac.c ACPI / PM: Fix unused function warnings for CONFIG_PM_SLEEP 2012-08-10 13:35:32 +02:00
acpi_ipmi.c
acpi_memhotplug.c ACPI / memhotplug: bind the memory device when the driver is being loaded 2012-11-16 02:12:38 +01:00
acpi_pad.c ACPI: strict_strtoul() and printk() cleanup in acpi_pad 2012-11-15 00:16:00 +01:00
battery.c ACPI / battery: Correct battery capacity values on Thinkpads 2012-11-16 22:28:58 +01:00
bgrt.c efi: Fix the ACPI BGRT driver for images located in EFI boot services memory 2012-09-29 12:21:03 -07:00
blacklist.c acpi: delete module.h include from files explicitly not needing it 2011-10-31 19:30:33 -04:00
bus.c ACPI: run _OSC after ACPI_FULL_INITIALIZATION 2012-09-25 00:15:07 -04:00
button.c ACPI/button: convert to module_acpi_driver() 2012-09-21 13:38:29 -04:00
cm_sbs.c
container.c ACPI: Fix a hard coding style when determining if a device is a container, v3 2012-11-15 00:16:01 +01:00
custom_method.c ACPI: Split out custom_method functionality into an own driver 2011-05-29 01:50:40 -04:00
debugfs.c acpi: add export.h to files using THIS_MODULE/EXPORT_SYMBOL 2011-10-31 19:30:34 -04:00
dock.c ACPI: dock: Remove redundant ACPI NS walk 2012-11-15 00:16:00 +01:00
ec_sys.c simple_open: automatically convert to simple_open() 2012-04-05 15:25:50 -07:00
ec.c ACPI / EC: Don't count a SCI interrupt as a false one 2012-11-15 00:15:59 +01:00
event.c acpi: add export.h to files using THIS_MODULE/EXPORT_SYMBOL 2011-10-31 19:30:34 -04:00
fan.c ACPI/fan: convert to module_acpi_driver() 2012-09-21 13:39:03 -04:00
glue.c ACPI: Fix memory leak in acpi_bind_one() 2012-10-23 00:53:58 +02:00
hed.c ACPI/hed: convert to module_acpi_driver() 2012-09-21 13:39:25 -04:00
internal.h ACPI / EC: Cleanup the member name for spinlock/mutex in struct 2012-11-15 00:15:59 +01:00
Kconfig efi: Fix the ACPI BGRT driver for images located in EFI boot services memory 2012-09-29 12:21:03 -07:00
Makefile ACPI: Reorder IPMI driver before any other ACPI drivers 2012-10-16 18:07:12 -07:00
numa.c ACPI: Only count valid srat memory structures 2012-08-03 00:15:53 -04:00
nvs.c ACPI / PM: print physical addresses consistently with other parts of kernel 2012-03-30 02:46:57 -04:00
osl.c ACPI: Make seemingly useless check in osl.c more understandable 2012-11-15 00:18:20 +01:00
pci_bind.c
pci_irq.c PCI/PM/Runtime: make PCI traces quieter 2012-01-06 12:11:16 -08:00
pci_link.c acpi: use KERN_CONT in printk() continuation lines 2012-05-08 08:55:26 -07:00
pci_root.c Merge branch 'pci/taku-acpi-pci-host-bridge-v3' into next 2012-09-24 16:36:10 -06:00
pci_slot.c PCI/ACPI: Use acpi_pci_root info rather than looking it up again 2012-09-24 15:29:40 -06:00
power.c ACPI: add newline in power.c message 2012-11-15 00:18:21 +01:00
proc.c ACPI: Allow ACPI binding with USB-3.0 hub 2012-09-21 13:30:29 -04:00
processor_core.c cpufreq / ACPI: Fix not loading acpi-cpufreq driver regression 2012-07-12 22:39:32 +02:00
processor_driver.c ACPI: Add ACPI CPU hot-remove support 2012-11-15 00:16:04 +01:00
processor_idle.c cpuidle / ACPI: fix potential NULL pointer dereference 2012-10-08 22:51:27 -04:00
processor_perflib.c ACPI: Add fixups for AMD P-state figures 2012-09-09 22:05:02 +02:00
processor_thermal.c ACPI: Do cpufreq clamping for throttling per package v2 2012-03-22 02:16:14 -04:00
processor_throttling.c ACPI throttling: fix endian bug in acpi_read_throttling_status() 2012-03-30 16:06:12 -04:00
reboot.c Revert "ACPI: ignore FADT reset-reg-sup flag" 2012-04-20 11:19:35 -07:00
sbs.c ACPI / PM: Fix unused function warnings for CONFIG_PM_SLEEP 2012-08-10 13:35:32 +02:00
sbshc.c ACPI/sbshc: convert to module_acpi_driver() 2012-09-21 13:39:40 -04:00
sbshc.h
scan.c ACPI: create _SUN sysfs file 2012-11-16 02:56:59 +01:00
sleep.c ACPI / Sleep: add acpi_sleep=nonvs_s3 parameter 2012-11-15 00:16:02 +01:00
sleep.h
sysfs.c ACPI: replace strlen("string") with sizeof("string") -1 2012-07-26 21:35:28 -04:00
tables.c ACPI: Harden acpi_table_parse_entries() against BIOS bug 2012-10-06 15:51:49 -04:00
thermal.c Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux into thermal 2012-10-09 01:35:52 -04:00
utils.c ACPI: Use ACPICA native way to decode the PLD buffer 2012-09-21 00:31:33 -04:00
video_detect.c acpi/video_detect: blacklist samsung x360 2012-07-28 00:11:48 -04:00
video.c ACPI video: Ignore errors after _DOD evaluation. 2012-11-03 09:52:54 +08:00
wakeup.c