Lenovo Thinkpad Charge Limit

Heya,

quick question: shouldn’t KDE offer charge limit Options? For some reason thats missing for my Laptop. But I do know that charge limits are supported, since it properly reacts to echoing the wanted values to /sys/class/power_supply/BAT0/charge_control_(start/end)_threshold (okay semi-properly; writing the values work, but cating them back out, returns broken values in the 200ish range, but the Laptop does respect the limits I set). It also shows in the KDE Battery Widget, that its charging/discharging/not charging. So yeah, KDE seems to be at least somewhat aware, but in the Power Settings there is no option to configure the limits.

For now I added TLP (which also failes to properly read the values - but it does allow me to configure the limits in a config file) for somewhat easy management, but it would be much nicer to have it in the KDE power settings.

I have tested it on a fresh installation of Arch Linux with just plasma-meta, konsole (cause thats not in plasma-meta for some reason), NetworkManger and the Arch base packages (“base”, “linux” and “linux-firmware”) installed.

So yeah, do I need some dependencies for this to work?

Isn’t it better (as in safer, os independent) to set this up in BIOS rather than the OS?

Probably. But the BIOS doesn’t expose this option. So I have to set it up from within an operating system.

This is provided by powerdevil, i.e plasma power management.

systemsettings > power management > advanced features on the top right

Charge limit, second entry.

Hmhm. Sadly this doesn’t exist on my system. In this menu I only have battery level settings (at what percentage does KDE think I have low battery and critical battery) and “other settings”, which consists of Media Playback during suspend and Related Pages. The Advanced Power settings contain nothing about thresholds.

Either your distro is old (you didn’t specify), or your hardware driver does expose the required API.

I would expect thinkpad to be supported.
My two thinkpads do support this.

The feature is pretty old now:

Is Powerdevil running ?

Or there might be a bug if you have /sys/class/power_supply/BAT0/charge_control_(start/end)_threshold present.

I specified, that I tested on a fresh Arch Linux install. It doesn’t get much more recent than that. If you want it in Version numbers:

KDE Plasma: 6.7.3
KDE Framework: 6.28.0
QT: 6.11.1
Kernel: 7.1.5

All of that running on Wayland.

As for Powerdevil, what do you mean with running? It doesn’t has a systemd Service, does it? Aside from a Service I might have missed, Powerdevil is installed and it indeed does open (I can access the advanced power settings).

And yes, I can confirm that the /sys/ files for the Battery BAT0 are present.

Maybe try updating your firmware ? I have a dell latitude which initially did not have this option in plasma, but it was shown in uefi firmware settings. after updating my uefi firmware plasma also started showing this option.

I guess powerdevil is choking on the “broken values” and therefore fails to present the charge limits.

Could you please show the output of

sudo tlp-stat -b -s

so we can have a look on the actual values. This will also show which ThinkPad exactly, so I can suggest how to reset the embedded controller (EC).

This is the result of tlpstat -b -s:

[root@LumenX380 ~]# tlp-stat -b -s
--- TLP 1.10.2 --------------------------------------------

+++ System Info
System         = LENOVO ThinkPad X380 Yoga 20LJS02W00
BIOS           = LENOVO R0SET53W (1.37 )
EC firmware    = 1.37
OS release     = Arch Linux
Kernel         = 7.1.5-arch1-2 #1 SMP PREEMPT_DYNAMIC Tue, 28 Jul 2026 13:49:51 +0000 x86_64
/proc/cmdline  = zfs=zroot/ROOT/arch0 systemd.gpt_auto=0 spl.spl_hostid=0x00bab10c
Init system    = systemd 261
Boot mode      = UEFI
Suspend mode   = s2idle [deep]

+++ TLP Status
tlp            = enabled, last run: 20:10:40, 1 sec(s) ago
tlp-rdw        = not installed
tlp-pd         = not installed
TLP profile    = balanced/BAT
Power source   = battery

+++ Battery Care
Plugin: thinkpad
Supported features: charge thresholds, chargeonce, discharge, recalibrate
Driver usage:
* natacpi (thinkpad_acpi) = active (charge thresholds, force-discharge)
Parameter value ranges:
* START_CHARGE_THRESH_BAT0/1:  0(off)..96(default)..99
* STOP_CHARGE_THRESH_BAT0/1:   1..100(default)

+++ ThinkPad Battery Status: BAT0 (Main / Internal)
/sys/class/power_supply/BAT0/manufacturer                   = LGC
/sys/class/power_supply/BAT0/model_name                     = 00HW027
/sys/class/power_supply/BAT0/cycle_count                    =      4
/sys/class/power_supply/BAT0/energy_full_design             =  39960 [mWh]
/sys/class/power_supply/BAT0/energy_full                    =  39960 [mWh]
/sys/class/power_supply/BAT0/energy_now                     =  17710 [mWh]
/sys/class/power_supply/BAT0/power_now                      =   7460 [mW]
/sys/class/power_supply/BAT0/status                         = Discharging

/sys/class/power_supply/BAT0/charge_control_start_threshold =    208 [%]
/sys/class/power_supply/BAT0/charge_control_end_threshold   =    208 [%]
/sys/class/power_supply/BAT0/charge_behaviour               = [auto] inhibit-charge force-discharge

Charge                                                      =   44.3 [%]
Capacity                                                    =  100.0 [%]

That Powerdevil can’t deal with… 208% might be an issue, yeah. As far as I can tell the value tlp-stat reads out for both thresholds is always the value I set at end threshold + 128.

Also, might be noteworthy that is a new battery in this Laptop. The original battery was dead. That being said, Windows (with Lenovo Commercial Vantage) has no issues with correctly reading the threshold values. This Laptop also excluseivly ran Windows until I got it and the first thing I did was replacing the battery, so I have no clue if the original battery also had issues with Linux and charging thresholds.

That probably is a requirement that this value is between 0 and 100 or is likely invalid like 208.

You can change the value by hand echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold for the two values and plasma ui might appear then.

Even if you write the threshold value properly, it will always be returned with an offset of +128 when read. I vaguely recall this special case with certain models. It’s due to the firmware.

An EC reset won’t help here. An EC firmware update most likely won’t help either. This needs to be addressed at the kernel level.

The fact that _start_threshold returns the value of _end_threshold is also a quirk of certain ThinkPad series and is likewise due to their firmware.

Unlucky you at the hardware roulette.

I empathize.

Share your hardware detailed info here, at least chipset/CPU thinkpad gen.
Others will be concerned and this will help identify the issue for them.

Its already in the output of tlp-stat: ThinkPad X380 Yoga 20LJS02W00. 20LJS02W00 is the 2018 Version with an Intel i7-8550U.

Firmware Version is also in the tlp-stat output, 1.37, which I just noticed is actually outdated. The current one is 1.41. Interstingly, fwupd didn’t show me this update. Oh well. I update real quick and report back.

Update: one Lenovo BIOS Update USB Stick later, and I am on 1.41. I don’t know what exactly this version changed, but it definitely didn’t changed the 208%, the system is reporting for the thresholds. Infact, the only thing which changed in the tlp-stat -b -s output are the BIOS and EC firmware Versions (to 1.41). KDE still doesn’t want to show me the Threshold options, but that doesn’t surprise me, considering the values are still broken.

If anyone here has experience submitting kernel patches and would like to do it, I think a root-cause fix is quite simple. On lines 9515 and 9522 of thinkpad_acpi.c reduce the mask to 7 bits:

/* Value is in the lower 7 bits */
*ret = *ret & 0x7F;

drivers/platform/x86/lenovo/thinkpad_acpi.c#n9507

Sorry, I’m not allowed to post real links yet :frowning:

I strongly suspect that this will work for all ThinkPads regardless of model, since threshold values are always < 127.

I did it once. It is somewhat arcane but doable, my one line change took like four months because the reply on the mailing list did not reach me. Anyway, it was also for a thinkpad and it is this mailing list: platform-driver-x86@vger.kernel.org Archives here: platform-driver-x86

You just need to setup your machine to be able to send e-mails from git, and then not let your e-mail provider screw the formatting. Like, it is way too complicated, but then you get to patch the kernel :-). And it is not complicated as in “hard”, but as in “tedious”, but there is good documentation (too much documentation, if anything). But somebody who has that computer and can test it should do it.

The lines don’t correspond to your comment, how come ?

lines
9515:

		/* The value is in the low 8 bits of the response */
		*ret = *ret & 0xFF;

9522:

		/* Value is in lower 8 bits */
		*ret = *ret & 0xFF;

Blaming the file shows those haven’t changed in years.

Sorry, I don’t get your point. My code block shows the changed code.

The author of the charge threshold feature in the kernel likely was unaware of this model’s special case. There is no documentation from Lenovo on this. However, using bits 0..6 solves the issue at hand and works for all models.

My mistake.

There is no documentation from Lenovo on this. However, using bits 0..6 solves the issue at hand and works for all models.

Indeed seems like a good patch to send, getting through the hoops…