[RESPONDED] Battery charge control thresholds in sysfs

Hello @Loell_Framework , any chance that this feature request can be taken into consideration by the DEV team?
I have the same request and several other forum users as well. Only problem is that these requests are a bit scattered around in the forum.

Given its open nature, I would totally expect FW to expose this bit via sysfs eventually.

As another user mentioned, keeping a value of 80% is great for extending battery lifespan, but being able to ramp up to 100% before a long flight/trip would be a great usability improvement, without the need to fiddle with the BIOS.

@DHowett tagging you as you kindly started working on this as well :slight_smile:

Thanks!

EDIT: other thread here

2 Likes

If you’re willing to run some rando’s third-party kernel module, you can test it out!

It also exposes things like fan speed and keyboard backlight to userland via sysfs.

5 Likes

Dhowett’s solution or bios is where were at for now.

1 Like

Thanks for the link

From the README however my understanding is that I’d need to compile my own kernel, not just the module, is that still the case?

I’m not familiar with that process at all, and of course when compared to compiling just a module, I think that it would be a different league of DIY :sweat_smile:

Hence my interest for this being upstreamed eventually. Are your upstream efforts still ongoing, and if so, is there an issue/URL I can monitor for progress?

Thanks a lot :slight_smile:

4 Likes

Thank you for this!

I’ve just built and installed the module on my 12th Gen running Fedora 39 without any problems. It was as simple as:

$ git clone https://github.com/DHowett/framework-laptop-kmod.git
$ cd framework-laptop-kmod/
$ make
$ sudo make modules_install
$ sudo modprobe framework_laptop
$ cat /sys/class/power_supply/BAT1/charge_control_end_threshold
80
# echo 100 > /sys/class/power_supply/BAT1/charge_control_end_threshold 
# cat /sys/class/power_supply/BAT1/charge_control_end_threshold 
100

After this, I could see it start charging up past 80%.

3 Likes

Love it!

Works like a charm on Gentoo.

Using linux-next kernel, which is now 6.9-rc6, no patch is needed.
lm-sensors reports the fan speed.

2 Likes

I’m on Ubuntu 22.04 with 5.15.0-97-generic and I get these errors:

korvin@sigma:~/work/framework/framework-laptop-kmod$ make
make -C /lib/modules/`uname -r`/build M=$PWD modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-97-generic'
  CC [M]  /home/korvin/work/framework/framework-laptop-kmod/framework_laptop.o
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_get_fan_speed’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:268:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  268 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_set_target_rpm’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:300:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  300 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:307:15: error: implicit declaration of function ‘cros_ec_cmd’; did you mean ‘cros_ec_cmd_xfer’? [-Werror=implicit-function-declaration]
  307 |         ret = cros_ec_cmd(ec, 1, EC_CMD_PWM_SET_FAN_TARGET_RPM, &params,
      |               ^~~~~~~~~~~
      |               cros_ec_cmd_xfer
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_get_target_rpm’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:321:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  321 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘fw_fan_target_show’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:366:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  366 |         u32 val;
      |         ^~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_set_auto_fan_ctrl’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:412:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  412 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_set_fan_duty’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:455:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  455 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘ec_count_fans’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:505:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  505 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:513:9: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
  513 |         for (size_t i = 0; i < EC_FAN_SPEED_ENTRIES; i++) {
      |         ^~~
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:513:9: note: use option ‘-std=c99’, ‘-std=gnu99’, ‘-std=c11’ or ‘-std=gnu11’ to compile your code
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c: In function ‘framework_probe’:
/home/korvin/work/framework/framework-laptop-kmod/framework_laptop.c:690:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  690 |         struct cros_ec_device *ec = dev_get_drvdata(ec_device);
      |         ^~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:297: /home/korvin/work/framework/framework-laptop-kmod/framework_laptop.o] Error 1
make[1]: *** [Makefile:1911: /home/korvin/work/framework/framework-laptop-kmod] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-97-generic'
make: *** [Makefile:12: modules] Error 2

gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

The module has not been tested on a kernel that old. It could probably work with some modifications.

2 Likes

Same here. I am happy compiling and installing a kernel module. A little less compiling a full kernel, especially since that means having to redo it on every (security or other) fedora supplied kernel update.

On Arch Linux, I installed linux-mainline-6.11rc4-1 from the chaotic-aur repo. I see that the keyboard backlight control and fan/temp sensors are working now, but /sys/class/power_supply/BAT1/charge_control_end_threshold is still missing, and I don’t see the option to control it in KDE. According to the pull request, this should be provided by the cros_charge_control driver, and I do see that the driver is present and loaded

filename:       /lib/modules/6.11.0-rc4-1-mainline/kernel/drivers/power/supply/cros_charge-control.ko.zst
license:        GPL
author:         Thomas Weißschuh <linux@weissschuh.net>
description:    ChromeOS EC charge control
srcversion:     92B77CD0EA61B7EE89557CE
alias:          platform:cros-charge-control
depends:        
retpoline:      Y
intree:         Y
name:           cros_charge_control
vermagic:       6.11.0-rc4-1-mainline SMP preempt mod_unload 
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        32:D4:0F:FB:42:23:18:F3:60:32:42:67:82:C8:52:B0:40:99:F6:17
sig_hashalgo:   sha512
signature:      30:66:02:31:00:97:7D:A2:59:7B:20:22:BF:F4:C0:38:81:0E:3C:0C:
                00:D6:82:8C:69:9B:5E:F3:4C:FA:E9:7B:A8:A1:DA:B6:62:1F:AF:88:
                90:53:3E:CA:95:1C:8D:FE:D0:90:1D:B1:A8:02:31:00:94:1A:B6:41:
                6D:FE:1A:1E:F7:6C:6C:1D:B6:12:E0:0F:08:C3:96:ED:BD:0C:95:1C:
                11:6F:FB:EF:6D:5D:DD:DC:FC:C5:D8:C3:68:9B:09:C2:1E:3C:10:D2:
                9D:0A:12:24
parm:           probe_with_fwk_charge_control:Probe the driver in the presence of the custom Framework EC charge control (bool)

Is this just something that will work once the final 6.11 release is out?

You need to set the module parameter probe_with_fwk_charge_control and make sure not to use any other charge control tools. (UEFI setup, ectool, framework-laptop-kmod)

2 Likes

It is coming up for two years since @DHowett wrote (this thread, above) that ‘I’m planning on seeking upstream approval for this patch soon.’ When can we expect the kernel (or some more of less official, and easily available, module) to have the functionality at issue, please?

As soon as you have a support contract with whom you expect it from.

1 Like

Thank you for the reply. I am afraid that ‘contract with whom you expect it from’ makes little sense. Do you mean that I am expecting a paid level of service for a product for which I have not paid? If so: yet, I have paid. For, I bought a Framework laptop and that laptop is supposed to work with Linux.

You quoted @DHowett before.
He is not involved with Framework.
Neither is the person doing the mainline work for these drivers (me).
It’s a community forum, your messages are read by the community.
You could also have read this very thread which does contain the answers you are “expecting”.

4 Likes

Hi, it’s a while since my last visit to this thread. I tried to catch-up on the status quo today, and my understanding as per last comments is that we need module cros_charge_control to be loaded and its param probe_with_fwk_charge_control to be set.

So I did just that, but KDE still isn’t showing any battery charge limit option. What am I doing wrong?

❯ uname -r
6.11.2-1-default
❯ sudo modinfo cros_charge_control
[sudo] password for root: 
filename:       /usr/lib/modules/6.11.2-1-default/kernel/drivers/power/supply/cros_charge-control.ko.zst
license:        GPL
author:         Thomas Weißschuh <linux@weissschuh.net>
description:    ChromeOS EC charge control
suserelease:    openSUSE Tumbleweed
srcversion:     92B77CD0EA61B7EE89557CE
alias:          platform:cros-charge-control
depends:        battery
retpoline:      Y
intree:         Y
name:           cros_charge_control
vermagic:       6.11.2-1-default SMP preempt mod_unload modversions 
sig_id:         PKCS#7
signer:         openSUSE Secure Boot CA
sig_key:        FA:BE:D8:BF:40:9A:5E:65
sig_hashalgo:   sha256
signature:      28:15:FB:17:5E:D3:1F:DF:BE:1C:F6:FE:2C:F6:B6:89:2D:FA:8E:26:
                0F:8D:EE:89:56:54:D6:EC:ED:5A:83:56:A5:10:32:A0:4F:7C:C0:FD:
                66:C0:56:FB:6B:91:32:27:ED:30:6B:50:D9:6E:2E:18:EC:6B:D7:36:
                BF:2B:98:D6:AF:44:1F:9F:DC:22:99:D1:46:11:51:E4:A8:7C:34:03:
                88:DB:32:27:8C:A8:00:AD:1B:E7:5B:62:76:42:FA:9D:EA:8C:60:74:
                BD:08:3B:F0:59:F8:C8:CD:AA:A2:C0:7C:2E:0E:EF:C3:10:F1:7B:65:
                37:B8:0A:B8:26:DE:47:03:D7:38:B9:E5:38:F5:9C:4C:0B:6D:E4:A7:
                2C:E6:65:12:B5:5A:CD:2A:51:E3:91:FC:0D:75:E8:85:A2:5F:C7:B2:
                76:54:C6:51:36:EB:A3:2A:57:8B:AB:8C:2C:B5:32:4B:C0:AA:20:FA:
                A0:05:4C:51:0E:16:2F:CF:CB:90:8C:65:45:AE:06:D6:F4:61:A7:AA:
                32:9B:D4:87:70:42:A7:37:C3:BC:96:38:9F:62:A7:2F:4C:4B:C0:CD:
                C1:FA:F7:96:41:A8:50:38:95:C9:AE:EA:D5:6F:63:C9:39:90:5E:D5:
                CB:29:BA:9E:49:E1:03:17:21:85:C1:2B:50:C5:8D:EE
parm:           probe_with_fwk_charge_control:Probe the driver in the presence of the custom Framework EC charge control (bool)
❯ cat /sys/module/cros_charge_control/parameters/*
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: /sys/module/cros_charge_control/parameters/probe_with_fwk_charge_control
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ Y
───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Finally, I have also disabled charge control from UEFI, or at least I think so: since I couldn’t find an on/off toggle, I just changed the current value (80) to 100. I guess this would be equivalent to disabling firmware-level charge control (but please correct me if I’m wrong).

Thank you in advance for any help.

P.S. is it because of a limitation that this module can’t control directly the value set by UEFI?

I’ve got the same problem. See Request: Testing of Linux drivers on all laptop models - #22 by Roy_Meissner

Which device are you using? I see your username but want to make sure.

There are two completely separate battery control mechanisms in the EC.
The UEFI is using one, the driver the other.

Also I have no idea how KDE works in this regard.
Donyou have the raw sysfs attributes?

I think I was looking in the wrong place.

Now I can see the setting in the KDE UI (it’s under Advanced Power Settings).

The problem is that now power-profiles-daemon seems a bit messed up, or at least plasma can’t interact with it anymore.

It also looks like once 80% is reached, the battery is allowed to discharge (I’m now at 79%) and I dunno at which point it will fill up again. I’d rather avoid a situation where it constantly goes 80 → 75 → 80 → etc. That’s something that wasn’t happening when using the UEFI charge limit (unless the load on the system was so high, the power adapter couldn’t feed it enough juice to run on electrical outlet power only).

I think I’m back to UEFI charge control, at least for now (EDIT: it dropped to 78% now)