如果 Windows 有这个功能,大概率可以 Linux 实现。难易程度主要看硬件实现的方式,我简单描述下方法,你可以先尝试一下。
一般来说,电池都会通过 ACPI 提供像电量、充电状态信息等等接口,然后通过 sysfs 抽象供用户空间的应用使用。
所以第一步是看 /sys/class/power_supply 的设备,笔记本上 power_supply 类型一般有电源和电池。
能找到对应的电池的话,可以顺着 /sys/class/power_supply/XXX 链接去找对应的电池设备,看看有没有类似 charge_control_end_threshold 这类名字的抽象,这个名字都是厂家自己定义的,但是看字面意义一般就能猜出来。
如果存在的话,可以直接尝试写入。通常电池还会有另一个属性 status ,取值大概是 full/unknown/charging/discharging/not charging ,这个属性几乎都是一样的。not charging 就代表外接电源通电但电池未充电,可以据此判断充电限制是否生效。
还有一种可能是并没有一个 threshold 之类的属性可供设置,但有个类似 limit/switch 命名的属性,代表是否开启充电。通过写 0/1 来测试是否生效。
上面说的都是比较理想的情况。不太理想的情况是,这个充电控制是 EC 完成的,并没有暴露在 sysfs 里面。
那就需要你去 Windows 里,使用
https://github.com/hirschmann/nbfc 这个项目里的 ec_probe 工具,用来检测 EC 寄存器的变化。通过切换软件的充电控制开关,观察 EC 寄存器的变化,用控制变量的方法最终确定相应的地址,然后尝试改写寄存器的值,判断充电控制是否生效。
如果能找到对应的地址和值,用 ec_probe 的 Linux 版本做相应操作即可。(如果开启 SafeBoot 的话,Linux 会进入 Kernel Lockdown 模式,不允许修改 MSR 的值,这就需要
https://github.com/musikid/acpi_ec 的内核模块来修改)
如果 EC 接口也没用,那大概率这个功能是 WMI 驱动完成的,这就需要把 Windows 版的控制程序拿来逆向,然后改写成 Linux 可用的内核驱动模块。这个方法比较复杂就不多说了,如果真遇到了可以再聊。