Repository navigation
Description
Summary
The EC on the Framework Laptop 13 (AMD Ryzen AI 300 Series) does not implement EC_CMD_PWM_GET_FAN_DUTY (0x0027), and it implements EC_CMD_THERMAL_AUTO_FAN_CTRL (0x0052) only up to version 1. Because of this, the Linux cros_ec_hwmon driver does not register pwm1, pwm1_enable or the fan's thermal cooling device. The fan duty cannot be read at all, and controlling the fan from Linux requires raw EC access as root (framework_tool --fansetduty) instead of the standard hwmon interface.
Both commands are implemented upstream in Chromium EC and are already on this repository's main, fwk-sakura-20260429 and fwk-sunflower-dahlia-2026-09-30 branches, but not on fwk-lilac-27116.
System
- Framework Laptop 13 (AMD Ryzen AI 300 Series), AMD Ryzen AI 9 HX 370
- BIOS 04.02 (06/09/2026)
- EC
lilac-4.0.2-fdbf549(2026-06-08) - Linux 7.0.0-42-generic (Ubuntu), framework_tool 0.6.2
What the EC reports
Asking the EC which versions of each command it supports (EC_CMD_GET_CMD_VERSIONS, 0x0008):
$ sudo framework_tool --host-command 0x08 0 0x27
EC command failed: Response(InvalidParameter)
$ sudo framework_tool --host-command 0x08 0 0x24
Response (4 bytes):
00000000: 0300 0000 ....
$ sudo framework_tool --host-command 0x08 0 0x52
Response (4 bytes):
00000000: 0300 0000 ....
So EC_CMD_PWM_SET_FAN_DUTY supports versions 0 and 1, EC_CMD_THERMAL_AUTO_FAN_CTRL supports versions 0 and 1, and EC_CMD_PWM_GET_FAN_DUTY is not implemented. This matches common/fan.c on fwk-lilac-27116.
The cros_ec hwmon device accordingly has only fan1_input, fan1_target and fan1_fault for the fan.
Why this matters
Since Linux 6.18 (commits fb8e659309f7 "hwmon: (cros_ec) add PWM control over fans" and 5798b62867b4 "hwmon: (cros_ec) register fans into thermal framework cooling devices"), cros_ec_hwmon exposes pwmN (duty, readable and writable) and pwmN_enable (manual or automatic control), and registers each fan as a thermal cooling device. It does so only when the EC supports all three of these (cros_ec_hwmon_probe_fan_control_supported() in drivers/hwmon/cros_ec_hwmon.c):
EC_CMD_PWM_GET_FAN_DUTYversion 0EC_CMD_PWM_SET_FAN_DUTYversion 1EC_CMD_THERMAL_AUTO_FAN_CTRLversion 2
With them:
- The fan duty is readable without root. The EC holds the fan at a target RPM by adjusting the duty, so the duty it needs for a given RPM is a useful fan health signal over time (bearing wear, dust).
- Userspace fan control tools can use the standard hwmon interface instead of raw EC access as root.
- Whether the EC is in automatic fan control can be queried (
pwm1_enable), so a tool which exited without restoring automatic control can be detected.
Proposed fix
Cherry-pick these upstream commits (Sung-Chi Li, April 2025, already on main here) onto fwk-lilac-27116:
- efe67f7 ec_commands: add EC_CMD_PWM_GET_FAN_DUTY for getting fan duty cycle (https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6466952)
- 9b34398 fan: implement host command of getting fan duty cycle (https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6466953)
- e7e322c ec_commands: add v2 structs for EC_CMD_THERMAL_AUTO_FAN_CTRL (https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6466954)
- 6b9702f fan: extend handling of command EC_CMD_THERMAL_AUTO_FAN_CTRL for v2 (https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6466955)
- 1e6bccc fan: fix host command response size (https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6475850)
They apply cleanly to fwk-lilac-27116 (common/fan.c, include/ec_commands.h, zephyr/test/drivers/fan/src/fan.c, 160 insertions and 7 deletions). I have not built or tested the result. The change adds one read-only command and a new version of an existing one. Versions 0 and 1 of EC_CMD_THERMAL_AUTO_FAN_CTRL keep their behavior, except that an out-of-range fan index returns EC_RES_INVALID_PARAM instead of EC_RES_ERROR.
The same commits are also missing on fwk-tulip-29169, fwk-dogwood-27111, fwk-lotus-azalea-19573 and fwk-sunflower-26784, so the same backport would help the boards built from those branches too.
Related: #69 (the EC stops reading its temperature sensors and the fan stays off) is a separate problem, but the workarounds posted there run framework_tool --fansetduty in a loop as root. With these commands they could use the standard hwmon pwm1 interface instead.
I can open a pull request against fwk-lilac-27116 with these cherry-picks if that is the preferred way.
Activity