Note: this article is from 2017. Please don’t assume it is up-to-date. Please go check if battery thresholds are already supported out of the box on coreboot for the X220. This article explains how to do it if that’s not the case.
After installing coreboot on your Thinkpad (X220) you’ll quickly realise that tp_smapi, which you were using for setting battery thresholds, doesn’t work.
Under “ThinkPad Battery Features” tlp will tell you:
tp-smapi = inactive (unsupported hardware)
And acpi_call doesn’t work either.
The proprietary BIOS of Thinkpad laptops include an interface called SMAPI which allows setting these thresholds, and other cool things. Unfortunately, coreboot doesn’t include this. If you’re an X200 user you might be in luck as the patch for supporting tpacpi-bat is currently in code review.
But what about the X220?
For us there’s a workaround too, though not as clean. We can manually control the RAM of the embedded controller, the chip that handles the battery and charging, and many other things. For that you need ectool, which is included in coreboot’s git repository, in coreboot/util/ectool. Simply use make to compile it.
The bits of the EC’s RAM we need to modify are explained in this ticket on the coreboot issue tracker. I advice you to read the full thread before applying this to your system. It also explains under what conditions this trick might work on other Thinkpad models.
For the X220 it boils down to this:
Byte 0x03 allows for configuring if we’re setting the start or stop threshold. Specifically, bit 2 (=4) of byte 0x03. If we’re setting the stop thresholds (percentage at which the battery should stop charging), we set this bit to true:
# ectool -w 0x3 -z 0x44
We can then specify the threshold. Simply note the percentage you’ll like, and set bit 7 to true, by adding 128. 80% becomes:
80+128 = 208 = 0xD0
Set this threshold by writing it to byte 0x24 of the EC’s RAM:
# ectool -w 0x24 -z 0xD0
For setting the start threshold (percentage at which the battery should start charging), do the same but set bit 2 of byte 0x03 to false:
# ectool -w 0x3 -z 0x40
# ectool -w 0x24 -z 0xB2
This sets the start threshold to 50%.
I currently run this in a script that runs at boot. It’s not required though, since the EC will remain active when the battery is plugged in and has charge, even when the laptop is “off”.
#!/bin/bash # set-battery-thresholds.sh # Stop charing at 80%. ectool -w 0x3 -z 0x44 ectool -w 0x24 -z 0xd0 # Start charging at 50%. ectool -w 0x3 -z 0x40 ectool -w 0x24 -z 0xb2
Systemd service file:
[Unit] Description=Set battery thresholds [Service] Type=simple ExecStart=/data/bin/set-battery-thresholds [Install] WantedBy=multi-user.target
While we’re at it, here’s a table containing the values to write to byte 0x24 for different percentages:
Thanks to the awesome coreboot developers and other contributors, especially those participating in the ticket I used as a base when writing this blog post.