summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-04-23 11:37:14 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-13 17:33:54 +0000
commit5cc260eb5247184fb3df539a68ef7929407f1938 (patch)
tree4d72fcb4ade63cbe85a8241a269c9f8a5dac4e4b
parent8664258a45b3ccfa2b06f740afba80fa10964e97 (diff)
downloadchrome-ec-5cc260eb5247184fb3df539a68ef7929407f1938.tar.gz
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 <dnojiri@chromium.org> Change-Id: Idc6992625d992a73be141987d02ed220508d3b74 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2853142 Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3872711
-rw-r--r--common/battery.c57
-rw-r--r--include/config.h38
-rw-r--r--include/ec_commands.h10
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,10 +521,32 @@
/*
* 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. */