Charge thresholds under Linux
In regard to the question about controlling the charge threshold from Linux: apparently this isn't controlled by some standard means such as an ACPI method, but rather by direct I/O port tweaking done by the Battery MaxiMiser driver for Windows. It would be very hard to figure this out without specs.
--Thinker 17:56, 2 Oct 2005 (CEST)
maybe it would be possible to use a windows tool like SoftICE to capture the communication required to set the treshholds? as soon as we have some sort of specification adding support for it to the kernel should be rather trivial. --gst
I see that when the charge threshold is set to a high value in Windows, charging is stopped even past reboots (including into Linux), battery changes and AC power loss. The only thing that resumes charging (other than changing the setting under Windows) is disconnection of the AC power while the laptop is turned off.
Another data point: it seems that charging enable/disable is done automatically in hardware based on the configured thresholds. Some forum posts suggested it's done by software monitoring, but I checked and it does work under Linux after rebooting from Windows.
Offset 0x24 in the embedded controller (i.e., /proc/acpi/ibm/ecdump) contains the "start charging" threshold, in percentage minus 1. You can see this by changing the threshold in Windows, rebooting to Linux and looking at /proc/acpi/ibm/ecdump. No idea how to change it, though:
# echo 0x24 0x50 > /proc/acpi/ibm/ecdump has no effect. And I don't see anything obviously corresponding to the "stop charging" threshold.
When the charge thresholds are changed in Battery Maximizer, they take effect immediately but are not written to the embedded controller (or at least not through its standard interface). Looking at the writes to the EC's IO ports (and specifically for patterns of "out 0x66,0x81; out 0x62,EC_OFFSET; out 0x62,DATA"), I see that the following happens when changing the thresholds in Windows:
- There is always a write of 0x00 to EC offset 0x81.
- If the new thresholds cause charging to start or stop, there are also writes to EC offsets 0x81,0x14,0x2C,0x2D that look like the "_BTP" ACPI DSDT method (this causes the OS to be alerted when the battery passes a threshold).
- Sometimes there's also a bunch of writes to EC offsetx 0x50,0x52,0x53,0x54, but their arguments don't depend on the charge thresholds.
The SMBus isn't accessed either (i.e., no writes to the i801 SMBus chip at IO ports 0x18e8-0x18ff).
Calling the _BTP ACPI EC method under Linux does not affect the charge thresholds (after setting them in Windows) or the aforementioned read-only start-charge threshold in EC offset 0x24. In fact the Linux driver (battery.c) calls _BTP on startup anyway.
After setting the thresholds there's also a bunch of port accesses done by TPPWRIF.SYS (on behalf of PWRMGRIF.DLL). It does the following:
- Read the HDAPS sensor data (i.e., accesses to I/O ports 0x1610-0x1620 in essentially the same pattern described for reading the HDAPS sensor]).
- A write of 0x80 to port 0xB2. This is the "APMC" port used by the ACPI DSDT "SMI" method, which is called by the DSDT "UCMS" method to set the LEDs and brightness and such - looks promising. But the DSDT's SMI method always writes 0xF5 to port 0xB2 and transfers its arguments via some memory-mapped ports at physical address 0x5FEF6FC0, while a charge threshold change (even if it triggers charging) writes 0x80 to port 0xB2 and doesn't cause any access to to physical address 0x5FEF6FC0.
- A write of 0x80 to port 0x4F (huh?).
So when charging doesn't start/stop immediately, there's no use of any of those interfaces to tell the EC what the new values are!
Possible explanations (any other ideas?):
- The EC uses additional, non-standard ports. Which?
- There's some autonomous charging circuitry independent of the EC which monitors the thresholds. How is it accessed?
- Charge control is actually done by the Windows software (this contradicts my experience under Linux when rebooting from Windows). How the charger is switched on/off.
When pursuing the first option (other ports). The following narrows things down. On an otherwise idle T43 running Windows XP, the following are the only IO ports being accessed through WRITE_PORT_UCHAR even when while changing the charge threshold, and even if the change causes charging to start or stop. So if threshold setting uses IO ports through WRITE_PORT_UCHAR, it must be using one of the following ports (in hex):
- 0062,0066 (embedded controller, see above)
- 0170-0177 (IDE channel 1)
- 01F0-01FF (IDE channel 0)
- 02F8-02FF (IrDA serial port)
- 102B-102F (ACPI General-Purpose Event 0 Register Block, see below)
- 1610-161F (HDAPS sensor)
- 18C0-18CF (IDE DMA)
Concerning port 0x102B: it is accessed through some very interesting code paths, such as "ACPI"<-"ACPIEC"<-"ACPI"<-"IBMPMDRV"<-NtWriteFile<-NtDeviceIoControlFile<-"TPHKMGR" and "ACPI"<-"ACPIEC"<-"ACPI"<-"CmBatt"<-"BATTC"). There are also a lot of writes to it (alway of 0x10) when the threhold is changed. However, it's just part of the ACPI GPE0, meaning it's supposed to be involved just in event notification, and those write are just clearing event status bits, not communicating parameters.
So if there is other IO involved, either it's memory-mapped or it writes to IO ports directly without going through WRITE_PORT_UCHAR (as we know indeed happens with ports 0xB2 and 0x4F, see above).
Well, you don't really need a stop charging threshold, and I think there might not be one on all ThinkPads. In fact, the X40 does not have any advanced battery control at all, for example.
I observed that once my T43 starts charging, it will charge to full if not under supervision by the battery charger software. My best guess is that you can tell the embedded controller the start charging threshold for each battery, and you can also command it to stop charging a battery and to switch to another battery. After you stop a battery from charging, it will only start charging again if it crosses the start charging threshold.
I have not done many experiments, though. e.g. I have no idea if the EC (embedded controller) will honour a stop-charging command below the start charging threshold.
Li-Ion batteries wear our quicker when at high charge, so a stop-charge threshold is very useful for increased battery life (as long as it doesn't make you discharge the battery too deply later). For example, my laptop is never without AC power for long, so I keep it between 40% and 70% charge. Sure, older models don't have it, but if it weren't useful they wouldn't add it to later models...
My experience is that when I set the thresholds in Windows and reboot into Linux (without powering off with AC unplugged - that resets things), then both thresholds are respected. It does stop charging when it reaches the high threshold, and it does start charging again when charge falls below the low threshold.
Do you know how to issue a stop-charging command (or any other charging-related command)? Are you sure these commands even go through the EC rather than some other autonomous circuitry? I can't figure this one out.
--Thinker 18:04, 1 Dec 2005 (CET)
How did you find the "start charging" offset? Shouldn't it be possible to find the "stop charging" offset by setting/checking the value to i.e. 70% then to 80% and finally back to 70% (and checking which of the values changed between 1 and 2 and which are the same on 1 and 3)?
Another thing which I noticed on a X41 running Windows: Sometimes (even when the notebook is started) the battery is charged to 100% although it is setup to only load up to 95%. I use suspend-to-disk and a dockingstation quite often so this may be a possible cause of the problem.
I found the start-charge EC offset by (essentially) the method you suggested, but it didn't work for stop-charge.
About forgetting the threshold, one of the recent Battery Maximizer updates contained a fix for forgetting (or rather, not re-setting) the threshold on resume from hibernate.
--Thinker 17:26, 2 Dec 2005 (CET)
Ah. Neither memory-mapped nor IO-mapped, neither SMBUS nor SMBIOS, neither APM nor ACPI, but - how could anyone miss it - SMAPI - IBM's proprietary interface, in yet another incompatible incarnation. SMAPI calls are made by putting the arguments in registers and then writing constants to ports 0x2F ad 0xB2. Those ports somehow trigger a BIOS which looks at the registers, does its thing and write, results back to the registers and let the driver resume. Exceedingly strange!
--Thinker 14:21, 4 Dec 2005 (CET)
What you describe looks like a SMI interrupt. Yes, they are very nasty, let's hope IBM got the SMBIOS right, because any bugs there, or any sort of behaviour that clashes with something the Linux kernel doesn't expect will... make things go boom.
-- Hmh 2 Jan 2006, 21:28 UTC
We have it figured out and working: SMAPI support for Linux. So far, no booms.
--Thinker 23:38, 2 Jan 2006 (CET)
Cleaning the Interior
The description in the article doesn't match the keyboard removal instructions for the T43. It's best to just link to IBM's on-line instructions (which, for the T43 at least, include a nifty video of the disassembly) and to the maintenance manuals.
--Thinker 23:47, 28 Nov 2005 (CET)
Keep notebook off while charging
Why does it advise to "keep notebook off while charging"?
--Thinker 09:59, 6 Dec 2005 (CET)
Good question. Two things come to mind:
- Higher charge current is available to the battery depending on charger and notebook model, if the notebook is not draining power. And a faster charge cycle (but still well within design limits) is probably better for the battery.
- A mix of a defective battery and charge can blow up, and the probability of that happening is increased from close-to-absolute-zero to unlikely-as-all-heck if the notebook is on. This is dubious information, but it is widely "known" and pops up in the most unexpected places.
I will try to find out if IBM/Lenovo themselves recommend this, and also check out the Battery University for hints.
-- Hmh 2006-01-02 21:36 UTC
No suck luck. But the two things that came to mind are probably incorrect, there is one much simpler reason to not want the laptop turned on while charging: temperature. The battery degrades a bit faster with high temperatures (even while in storage). If temperature gets extremely high, the cells vent, and permanent capacity loss happens.
One should note that it is possible for the battery and charging circuit to be cooler with the laptop operating at full cooling fan speed than when the machine is turned off...
Now, excuse me while I go away to store my spare pack on the refrigerator :)
-- Hmh 2006-01-02 21:58 UTC
At least on the T43, the effect of internal system temperature on the laptop is very small: 1-2 degrees difference in battery temperature for idle vs. fully loaded system.
I regularly charge while working and keep my spare pack in the fridge. So far, so good.
I also do evil stuff like using a 35W power supply (left over from my ThinkPad 560) in lieu of the prescribed 72W power supply, keeping power draw low using tp_smapi's inhibit_charge_minutes and undervolting. Basically, my experience is that these units can take whatever you throw at them; at worst they just shut down.
--Thinker 23:38, 2 Jan 2006 (CET)
Approximate charge times
With your best power saving, what kind of battery power times are you guys experiencing? The best that I can do with my t43p with the standard (6cell) battery is 2h, and with the ultrabay battery is 1 hour. All of the power saving 'tricks' - hard drive spindown, even adjusting the brightness of my display, has relatively modest effect (~20% max), although CPU throttling definitely reduces power consumption.
In terms of discharge rate, I really can't get below 19,520 mW/h with the hard disk off, wifi on, cpu down to ~700 MHz, and display on minimal brightness with ATI driver power save enabled. In my "normal usage" environment (WiFi on, word processing / non cpu-intensive programming, etc.) I average 21,000 mW/h.
Of note, I have the UXGA display, which might be a huge power guzzler. I have friends with an X40 that claim 5 hours from the 9 cell...
--gsmenden 16:56, 10 Feb 2006 (EST)