summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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. */