From 450389be05fd474eaa419e99f9297c6ac8d83592 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 29 Oct 2025 18:52:39 -0500 Subject: [PATCH] ec/google/chromeec: Add fan presence helper function Add google_chromeec_has_fan() to determine if a board has a fan or not. The function first tries the EC feature flag (EC_FEATURE_PWM_FAN), falling back to a RPM read test if the flag is unavailable. TEST=tested hooked up to a CFR option to enable auto fan control at boot, with option visibility controlled by fan presence, on a range of Chromebooks with and without PWM-controlled fans. Change-Id: I2a920709f0e6780c779a87568d6a8d18f817c76d Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/89829 Reviewed-by: Maximilian Brune Reviewed-by: Caveh Jalali Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- src/ec/google/chromeec/ec.c | 38 +++++++++++++++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 1 + 2 files changed, 39 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 66cf54c4b0..27c752b196 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -134,6 +134,44 @@ bool google_chromeec_has_kbbacklight(void) } } +bool google_chromeec_has_fan(void) +{ + /* Try the PWM fan feature flag (most reliable for modern ECs) */ + int feature_check = google_chromeec_check_feature(EC_FEATURE_PWM_FAN); + + if (feature_check > 0) { + printk(BIOS_DEBUG, "Chrome EC: Fan detected (feature flag)\n"); + return true; + } else if (feature_check == 0) { + printk(BIOS_DEBUG, "Chrome EC: No fan (feature flag)\n"); + return false; + } + + /* Feature flag unavailable, try reading fan duty as a fallback test */ + printk(BIOS_DEBUG, "Chrome EC: Feature flag unavailable, testing fan read\n"); + const struct ec_params_pwm_get_fan_duty params = { + .fan_idx = 0, + }; + struct ec_response_pwm_get_fan_rpm resp = {}; + struct chromeec_command cmd = { + .cmd_code = EC_CMD_PWM_GET_FAN_TARGET_RPM, + .cmd_version = 0, + .cmd_data_in = ¶ms, + .cmd_size_in = sizeof(params), + .cmd_data_out = &resp, + .cmd_size_out = sizeof(resp), + .cmd_dev_index = 0, + }; + + if (google_chromeec_command(&cmd) == 0) { + printk(BIOS_DEBUG, "Chrome EC: Fan detected (read test)\n"); + return true; + } else { + printk(BIOS_DEBUG, "Chrome EC: No fan (read test)\n"); + return false; + } +} + void google_chromeec_post(uint8_t postcode) { /* backlight is a percent. postcode is a uint8_t. diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 3c77eeb459..04d5fba1c3 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -81,6 +81,7 @@ uint64_t google_chromeec_get_events_b(void); int google_chromeec_clear_events_b(uint64_t mask); int google_chromeec_kbbacklight(int percent); bool google_chromeec_has_kbbacklight(void); +bool google_chromeec_has_fan(void); void google_chromeec_post(uint8_t postcode); uint8_t google_chromeec_get_switches(void); bool google_chromeec_get_ap_watchdog_flag(void);