From 02b3674198cc68745a80fc1f8d2c564103f17ce6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 24 Dec 2025 08:53:58 +0000 Subject: [PATCH] ec/google/chromeec: Add SoC calculation from battery dynamic info Implement google_chromeec_read_batt_state_of_charge_raw() to calculate the battery percentage using raw capacity metrics. Unlike the standard charge state command, this function retrieves data via EC_CMD_BATTERY_GET_DYNAMIC. It manually calculates the State of Charge (SoC) by comparing remaining_capacity against full_capacity. This provides a fallback mechanism for platforms where the high-level CHARGE_STATE_CMD_GET_STATE command is not implemented or when working directly with the fuel gauge's dynamic data cache. Includes: - Zero-capacity check to prevent division by zero. - 100% clamping to handle fuel gauge rounding/calibration drift. Change-Id: I86d6313884762140884762140884762140884762 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90615 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/ec/google/chromeec/ec.c | 34 ++++++++++++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 9 +++++++++ 2 files changed, 43 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index d7e956068c..70ad5eee7c 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1884,3 +1884,37 @@ int google_chromeec_read_batt_state_of_charge(uint32_t *state) *state = resp.get_state.batt_state_of_charge; return 0; } + +/* + * Calculates SoC from dynamic battery data. + * + * This function fetches "dynamic" battery metrics (voltage, current, and capacity) + * and manually calculates the percentage. This is often used when the high-level + * "Get Charge State" command is unavailable. + * + * Return: 0 on success, -1 on communication failure or invalid battery data. + * Return Value (state): Pointer to store the calculated State of Charge (0-100%). + */ +int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) +{ + struct ec_params_battery_dynamic_info params = { + .index = 0, + }; + struct ec_response_battery_dynamic_info resp; + + if (ec_cmd_battery_get_dynamic(PLAT_EC, ¶ms, &resp) != 0) + return -1; + + if (resp.full_capacity <= 0) + return -1; + + uint32_t soc = (uint32_t)resp.remaining_capacity * 100 / (uint32_t)resp.full_capacity; + + /* Clamp the value to 100% (some fuel gauges report slight overflows) */ + if (soc > 100) + soc = 100; + + *state = soc; + + return 0; +} diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index e4120dabeb..ffda39b5c1 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -546,4 +546,13 @@ void chipset_ioport_range(uint16_t *base, size_t *size); */ int google_chromeec_read_batt_state_of_charge(uint32_t *state); +/* + * Reads the current battery charge percentage from EC dynamic info CMD. + * This is often used when the high-level "Get Charge State" command is unavailable". + * + * @param state Pointer to a uint32_t where the battery state of charge (0-100) will be + * stored. + */ +int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state); + #endif /* _EC_GOOGLE_CHROMEEC_EC_H */