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 <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/89829
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
Reviewed-by: Caveh Jalali <caveh@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Alicja Michalska <ahplka19@gmail.com>
This commit is contained in:
Matt DeVillier 2025-10-29 18:52:39 -05:00
commit 450389be05
2 changed files with 39 additions and 0 deletions

View file

@ -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 = &params,
.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.

View file

@ -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);