Created attachment 200506 [details] Use consistent driver name Support ThinkPad battery charge start/stop control using new sysctls: dev.acpi_ibm.0.bat0_charge_start dev.acpi_ibm.0.bat0_charge_stop Informed by the Linux driver: https://lore.kernel.org/patchwork/patch/858076/ And this driver: https://github.com/teleshoes/tpacpi-bat/blob/master/battery_asl Two patches are attached: - First one uses a consistent driver name in the source code and man pages "ThinkPad ACPI Extras" instead of references to IBM - Second one contains the majority of the change
Created attachment 200507 [details] Support ThinkPad battery charge start/stop control
Is anybody able to take a look?
(In reply to Kevin Zheng from comment #2) Submitting this on Christmas probably didn't help to get it noticed. Even though I have long wanted the ability to control charging, I totally missed it. A little explanation of why stopping and starting charging is desirable would probably be a desirable, as well. Not sure about the naming convention change as I believe that this module is appropriate to more Lenovo models than just the Thinkpad. Maybe it is time to just bite the bullet and go to "Lenovo". Not that many IBM units around any more. That said, any change might cause confusion for current users when acpi_ibm no longer loads.Is that worse than for newer users who no longer think of IBM and Thinkpad as related.
(In reply to rkoberman from comment #3) Perhaps "Lenovo" is better than "ThinkPad" and "IBM". Note that this patch does not change the name of the module, so it is still "acpi_ibm" and loading "acpi_ibm" will still continue to work. Controlling battery charge thresholds could be useful for prolonging battery life in machines that are used mostly on AC power. On Windows, battery charging thresholds can be controlled using the Lenovo Power Manager. This patch exposes the same functionality through the sysctl interface.
(In reply to Kevin Zheng from comment #0) I've applied the patch on a FreeBSD 12.0p10 running on a Thinkpad T450. The sysctls appear but how can i test that the patch actually works as intended?
(In reply to Manuel Stühn from comment #5) Set those sysctls to a non-zero number between 0-100. If you start with a full battery, set start_thresh to something like 80; discharge your battery to 85%, plug in, battery shouldn't charge. Discharge to 75%, battery will charge until stop_thresh.
(In reply to Kevin Zheng from comment #6) I've tried the following: # sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 2 hw.acpi.battery.state: 1 hw.acpi.battery.time: 156 hw.acpi.battery.life: 57 # sysctl dev.acpi_ibm.0 | grep charge dev.acpi_ibm.0.bat0_charge_stop: 90 dev.acpi_ibm.0.bat0_charge_start: 50 If i plug in the laptop then, it seems to charge anyway: # sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 2 hw.acpi.battery.state: 2 hw.acpi.battery.time: -1 hw.acpi.battery.life: 58
(In reply to Manuel Stühn from comment #7) Per Google (https://askubuntu.com/questions/34452/how-can-i-limit-battery-charging-to-80-capacity), this method might have stopped working in the T440s. I've tested on T430s and T410, and this patch works on both.
I'm using it on my T520 and it is working fine. I read the old IBM whitepaper on this and they recommend keeping hte btter at or below 85% when a ystm is usually plugged in. Not sure just what they implemented, but the paper proposed that the percentage of time on battery be tracked and if the battery percentage was below a threshold, the maximum charge be reduced to 85%. If the charge dropped below come low value (20%?), the maximum charge would reset to 100% for some time. Statistics were to be retained across boots. It's at least 20 years, so my memory of details is fuzzy, but I'm thinking of writing something to implement at least a bit of this scheme, but I have done little coding since kernels and drivers were written in assembly, so I'm hardly the ideal person for the job.
I just hit a minor nit. I can't set dev.acpi_ibm.0.bat0_charge_stop to 100. I get "sysctl: dev.acpi_ibm.0.bat0_charge_stop=100: Invalid argument". 99 works fine. Since the range is really 1-100, perhaps you should subtract 0ne from the input value to pass the 09-99 value to ACPI. I also have noted the values are sticky, lasting through reboots and even power cycles, so are being stored in the BIOS configuration. Still working well for me. I keep it at 85 when I'm home and bump it to 99 when traveling as I am more frequently not on AC and the extra 15% is very useful. It's really like to get this into the system, but I'd like to know more about it on newer systems. The Tx20s are over 8 years old and I expect to be upgrading mine before too much longer.
(In reply to rkoberman from comment #10) Thanks for the comments. The range is actually 0-99, where 0 means "battery controller default", and 1-99 is a custom setting. The values are sticky, but they are not stored in the BIOS configuration. I believe the values are actually persisted on the battery controller chip in the battery pack and are reset when the battery pack is detached. Notice that if you set a value, shut down the computer, remove and reattach the battery, the values get reset. I agree; it'd be great to figure out how to get this working on newer ThinkPads. Until I get one, however, I have no incentive to write a patch :)
I'll pick this up
A commit references this bug: Author: emaste Date: Wed Jan 15 19:43:46 UTC 2020 New revision: 356764 URL: https://svnweb.freebsd.org/changeset/base/356764 Log: acpi_ibm: reference ThinkPad instead of IBM These are now Lenovo ThinkPads, not IBM ThinkPads. PR: 234403 Submitted by: Kevin Zheng <kevinz5000@gmail.com> (original) Changes: head/share/man/man4/acpi_ibm.4 head/sys/dev/acpi_support/acpi_ibm.c
What is -4 Not supported
(In reply to Ed Maste from comment #14) I'm guessing that this is either the battery firmware or the ME reporting that although this ACPI method exists, the operation is not supported? I don't remember from what basis I added this -- perhaps from the Linux driver?
Patch needs to be rebased after r357292, acpi_ibm: add support for ThinkPad PrivacyGuard. I will likely do so and test the change later this week.
Created attachment 219436 [details] Patch Update patch rebased over Privacy Guard.
Works for me on ThinkPad T440p and 12-STABLE. I wonder why it's still not committed?
From Ed's comments above, it seems like he has newer hardware where the ME doesn't let you set the battery charge thresholds this way. I run a T430s where this method is still supported, and it sounds like it also works on T440p.
(In reply to Kevin Zheng from comment #19) This is anticipated feature. The patch is small and can't break anything. Better to support some hardware than not to support anything, acpi_ibm already lacks support for modern ThinkPads. There are ThinkPads based on AMD chips in the market, without ME. I saw reports that on T495 this method still works.
Created attachment 225156 [details] Patch Update patch against releng/13.0 in Git format.
Dear Kevin Zheng, I'm new to FreeBSD, and I'm trying to set battery charge start/stop control point of my laptop(think pad T430s), and I got some error. ``` root@freebsd:/boot/loader.conf.d # sysctl dev.acpi_ibm.0.bat0_charge_start=80 sysctl: unknown oid 'dev.acpi_ibm.0.bat0_charge_start' ``` ``` root@freebsd:/boot/loader.conf.d # kldstat Id Refs Address Size Name 1 51 0xffffffff80200000 1f30590 kernel 2 1 0xffffffff82131000 71af0 iwn6000fw.ko 3 1 0xffffffff821a3000 a8108 iwn6000g2afw.ko 4 1 0xffffffff8224c000 a8968 iwn6000g2bfw.ko 5 1 0xffffffff822f5000 8710 acpi_ibm.ko 6 1 0xffffffff82520000 158430 i915kms.ko 7 1 0xffffffff82679000 7e020 drm.ko 8 2 0xffffffff826f8000 cbc8 linuxkpi_gplv2.ko 9 1 0xffffffff82705000 3378 acpi_wmi.ko 10 1 0xffffffff82709000 3250 ichsmb.ko 11 1 0xffffffff8270d000 2180 smbus.ko 12 1 0xffffffff82710000 47a0 if_axe.ko 13 1 0xffffffff82715000 3178 uether.ko 14 1 0xffffffff82719000 20b8 acpi_call.ko ``` ``` root@freebsd:/boot/loader.conf.d # sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 1 hw.acpi.battery.state: 0 hw.acpi.battery.rate: 0 hw.acpi.battery.time: -1 hw.acpi.battery.life: 97 ``` Many thanks, Ben
(In reply to Kevin Zheng from comment #0) Dear Kevin Zheng, I'm new to FreeBSD, and I'm trying to set battery charge start/stop control point of my laptop(think pad T430s), and I got some error. ``` root@freebsd:/boot/loader.conf.d # sysctl dev.acpi_ibm.0.bat0_charge_start=80 sysctl: unknown oid 'dev.acpi_ibm.0.bat0_charge_start' ``` ``` root@freebsd:/boot/loader.conf.d # kldstat Id Refs Address Size Name 1 51 0xffffffff80200000 1f30590 kernel 2 1 0xffffffff82131000 71af0 iwn6000fw.ko 3 1 0xffffffff821a3000 a8108 iwn6000g2afw.ko 4 1 0xffffffff8224c000 a8968 iwn6000g2bfw.ko 5 1 0xffffffff822f5000 8710 acpi_ibm.ko 6 1 0xffffffff82520000 158430 i915kms.ko 7 1 0xffffffff82679000 7e020 drm.ko 8 2 0xffffffff826f8000 cbc8 linuxkpi_gplv2.ko 9 1 0xffffffff82705000 3378 acpi_wmi.ko 10 1 0xffffffff82709000 3250 ichsmb.ko 11 1 0xffffffff8270d000 2180 smbus.ko 12 1 0xffffffff82710000 47a0 if_axe.ko 13 1 0xffffffff82715000 3178 uether.ko 14 1 0xffffffff82719000 20b8 acpi_call.ko ``` ``` root@freebsd:/boot/loader.conf.d # sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 1 hw.acpi.battery.state: 0 hw.acpi.battery.rate: 0 hw.acpi.battery.time: -1 hw.acpi.battery.life: 97 ``` Many thanks, Ben
(In reply to Benjamin Fang from comment #23) Hi Benjamin, Since this patch hasn't been integrated into FreeBSD yet, you need to recompile the acpi_ibm kernel module yourself before you can use these sysctls. If you aren't able to compile the kernel module yourself, you may contact me privately for a binary. Regards, Kevin
(In reply to Kevin Zheng from comment #24) Hi Kevin, I agree that it would be good to get this committed. My IBM T23 only died 2 years ago, now running X200 and T430s, and some folks will be for years yet, they're so #@$&*! reliable, the older the better. I was wondering if it was worth updating man and code patches to 100 rather than 99 as the upper limit, since charging ended (to 'high' state) at 100% without the patch on all of mine. However this 2021 thread, just this week revived at https://forums.freebsd.org/threads/how-to-set-battery-charging-thresholds-on-laptop.79807/ using awkward and potentially dangerous? acpi_call invocations confirmed that 100 isn't an accepted value at that level either. Another reason to commit it! I'm running 12.4 on the T430s. Hoping git references in patch won't interfere with patching, 12 being still svn based? Now I just have to remember how to build just one module .. it's been years :) cheers, Ian
Thanks for the comments. I'd like to point out that you can still grab the old patch for 12 and try to apply that. I'm also running with this patch on a T480s and this method of battery control still works.
any news ?
try my solution
try https://github.com/dr3mro/battery_ctrl my solution
With respect, Amr, your script lacks any checking on parameters apart from there being two of them, or on success. Checks should include that: . acpi_call.ko is loaded (kldstat) . Both are integers > 0 and <= 100 . start charge value is < stop value . Both acpi_call invocations succeed.
@ian smith(In reply to Ian Smith from comment #30) Thank you for your valuable feed back I will be honored if you recheck it now Thanks
(In reply to Amr from comment #31) Great. Please see my report at: Post in thread 'How to set battery charging thresholds on laptop...' https://forums.freebsd.org/threads/how-to-set-battery-charging-thresholds-on-laptop.79807/post-627456
I've checked that the latest patch still applies cleanly to the releng/14.0 branch and additionally still works on my T480s.