From 5cc260eb5247184fb3df539a68ef7929407f1938 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Fri, 23 Apr 2021 11:37:14 -0700 Subject: Battery: Add command to export display SoC Currently, CrOS EC passes the battery remaining capacity (mAh) and the full capacity (mAh) through ACPI to the AP so that the host can calculate the battery SoC. The host further manipulates the SoC to get the display SoC, which is used to determine user visible behaviors. To get consistent behaviors in all power states, this change enables the EC to send the display SoC to the host via EC_CMD_DISPLAY_SOC command. The Powerd's part is I5bd1371f2569d21d55df1b50a3d709b98bbf0325. BUG=b:174433637, b:181506409, b:80270446, b:109954565 BRANCH=dedede, trogdor, nami, hatch TEST=Storo, CoachZ Signed-off-by: Daisuke Nojiri Change-Id: Idc6992625d992a73be141987d02ed220508d3b74 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2853142 Reviewed-by: Tim Wawrzynczak Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3872711 --- common/battery.c | 57 +++++++++++++++++++++++++++++++++++++++------------ include/config.h | 38 ++++++++++++++++++++++++++++++++++ include/ec_commands.h | 10 +++++++++ 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/common/battery.c b/common/battery.c index 117bbbb111..f048a1db91 100644 --- a/common/battery.c +++ b/common/battery.c @@ -203,8 +203,7 @@ static void print_battery_info(void) print_item_name("Cap-full:"); if (check_print_error(battery_full_charge_capacity(&value))) - ccprintf("%d mAh (%d mAh with %d %% compensation)\n", - value, value*batt_full_factor/100, batt_full_factor); + ccprintf("%d mAh\n", value); #ifdef CONFIG_CHARGER_V2 print_item_name("Display:"); @@ -239,6 +238,12 @@ static void print_battery_info(void) } ccprintf("%dh:%d\n", hour, minute); } + + print_item_name("full_factor:"); + ccprintf("0.%d\n", batt_host_full_factor); + + print_item_name("shutdown_soc:"); + ccprintf("%d %%\n", batt_host_shutdown_pct); } void print_battery_debug(void) @@ -582,22 +587,33 @@ void battery_compensate_params(struct batt_params *batt) if (*remain <= 0 || *full <= 0) return; - /* full_factor is effectively disabled in powerd. */ - *full = *full * batt_full_factor / 100; + /* Some batteries don't update full capacity as often. */ + if (!IS_ENABLED(CONFIG_BATTERY_EXPORT_DISPLAY_SOC)) + /* full_factor is effectively disabled in powerd. */ + *full = *full * batt_full_factor / 100; if (*remain > *full) *remain = *full; /* - * Powerd uses the following equation to calculate display percentage: - * charge = 100 * remain / full - * display = 100 * (charge - shutdown_pct) / - * (full_factor - shutdown_pct) - * = 100 * ((100 * remain / full) - shutdown_pct) / - * (full_factor - shutdown_pct) - * = 100 * ((100 * remain) - (full * shutdown_pct)) / - * (full * (full_factor - shutdown_pct)) + * EC calculates the display SoC like how Powerd used to do. Powerd + * reads the display SoC from the EC. This design allows the system to + * behave consistently on a single SoC value across all power states. + * + * Display SoC is computed as follows: * - * The unit of the following batt->display_charge is 0.1%. + * actual_soc = 100 * remain / full + * + * actual_soc - shutdown_pct + * display_soc = --------------------------- x 1000 + * full_factor - shutdown_pct + * + * (100 * remain / full) - shutdown_pct + * = ------------------------------------ x 1000 + * full_factor - shutdown_pct + * + * 100 x remain - full x shutdown_pct + * = ----------------------------------- x 1000 + * full x (full_factor - shutdown_pct) */ numer = 1000 * ((100 * *remain) - (*full * batt_host_shutdown_pct)); denom = *full * (batt_host_full_factor - batt_host_shutdown_pct); @@ -609,6 +625,21 @@ void battery_compensate_params(struct batt_params *batt) batt->display_charge = 1000; } +#ifdef CONFIG_BATTERY_EXPORT_DISPLAY_SOC +static int battery_display_soc(struct host_cmd_handler_args *args) +{ + struct ec_response_display_soc *r = args->response; + + r->display_soc = charge_get_display_charge(); + r->full_factor = batt_host_full_factor * 10; + r->shutdown_soc = batt_host_shutdown_pct * 10; + args->response_size = sizeof(*r); + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_DISPLAY_SOC, battery_display_soc, EC_VER_MASK(0)); +#endif + __overridable void board_battery_compensate_params(struct batt_params *batt) { } diff --git a/include/config.h b/include/config.h index 91d4b5ba89..faa1f5ed3c 100644 --- a/include/config.h +++ b/include/config.h @@ -498,6 +498,22 @@ * Some batteries don't update full capacity timely or don't update it at all. * On such systems, compensation is required to guarantee remaining_capacity * will be equal to full_capacity eventually. This used to be done in ACPI. + * + * When CONFIG_BATTERY_EXPORT_DISPLAY_SOC is enabled, CONFIG_BATT_FULL_FACTOR + * has no effect. Also CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE is used by Powerd + * as the threshold for low battery shutdown. For example, if we have: + * + * CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON = 3 + * CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE = 2, + * BATTERY_LEVEL_SHUTDOWN = 1 + * + * the battery range is divided as follows (assuming system is powered only by + * internal battery): + * + * 0% ------------------- 1% ------------------- 2% ------------------- 3% + * EC refuses to boot -> + * Powerd shuts down system -> + * EC shuts down system -> */ #define CONFIG_BATT_FULL_FACTOR 98 #define CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE 4 @@ -505,9 +521,31 @@ /* * Powerd's full_factor. The value comes from: * src/platform2/power_manager/default_prefs/power_supply_full_factor + * + * When CONFIG_BATTERY_EXPORT_DISPLAY_SOC is enabled, this value is exported + * to the host (i.e. Powerd). It's used to calculate the ETA for full charge. */ #define CONFIG_BATT_HOST_FULL_FACTOR 97 +/* + * This option enables EC to be the origin of the display SoC and allows the + * host (i.e. Powerd) to retrieve it through EC_CMD_DISPLAY_SOC. + * + * The display SoC is computed from the remaining capacity, the last full + * charge, CONFIG_BATT_FULL_FACTOR, CONFIG_BATT_HOST_FULL_FACTOR, and + * CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE. + * + * If this option is disabled, the EC and the host will individually compute + * the display SoC, which may result in inconsistent behaviors since the numbers + * do not necessarily match. As such, this option is going to be enabled by + * default and the old behavior (#undef CONFIG_BATTERY_EXPORT_DISPLAY_SOC) will + * be deprecated. + * + * TODO: Define CONFIG_BATTERY_EXPORT_DISPLAY_SOC by default and remove + * CONFIG_BATTERY_EXPORT_DISPLAY_SOC and CONFIG_BATT_FULL_FACTOR. + */ +#undef CONFIG_BATTERY_EXPORT_DISPLAY_SOC + /* * Expose some data when it is needed. * For example, battery disconnect state diff --git a/include/ec_commands.h b/include/ec_commands.h index 7559d11018..d3747ec8a0 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -5260,6 +5260,16 @@ struct ec_response_locate_chip { }; } __ec_align2; + +#define EC_CMD_DISPLAY_SOC 0x0137 + +struct ec_response_display_soc { + int16_t display_soc; /* Display charge in 10ths of a % (1000=100.0%) */ + int16_t full_factor; /* Full factor in 10ths of a % (1000=100.0%) */ + int16_t shutdown_soc; /* Shutdown SoC in 10ths of a % (1000=100.0%) */ +} __ec_align2; + + /*****************************************************************************/ /* The command range 0x200-0x2FF is reserved for Rotor. */ -- cgit v1.2.1