summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-05-31 13:30:24 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-09 02:22:27 +0000
commit29b73cdc019645d60f799fefc4af16cd0b520fd9 (patch)
treeb0cfdeae667222aecc27ed9e26dced718c52a74e
parent76dbc1546096cb676badb6d545d0bf81730f36bf (diff)
downloadchrome-ec-29b73cdc019645d60f799fefc4af16cd0b520fd9.tar.gz
chgstv2: Add battery sustainer
This patch adds the battery sustainer. Given a target SoC by the host, the sustainer will try to keep the SoC stay close within the range near the target. The diagram below shows how the sustainer uses the charge mode to charge or discharge the battery as the SoC moves near the target: T-d% T% ----------|----------------------|----------- charge normally charge normally/slowly (mode=NORMAL) ... ----> +---------------------> | | <----------------------+ <----- ... discharge naturally discharge normally (mode=IDLE) (mode=DISCHARGE) When AC is unplugged, the sustainer is disabled. Currently, the sustainer requires CONFIG_CHARGER_DISCHARGE_ON_AC. > chgstate state_of_charge = 69% chg_ctl_mode = NORMAL manual_voltage = -1 manual_current = -1 Battery sustainer = off (-1% ~ -1%) > chgstate sustain 70 72 state_of_charge = 69% chg_ctl_mode = NORMAL manual_voltage = -1 manual_current = -1 Battery sustainer = on (70% ~ 72%) > battfake 71 > chgstate state_of_charge = 71% chg_ctl_mode = NORMAL > battfake 73 > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = -1 manual_current = -1 > battfake 71 > chgstate state_of_charge = 71% chg_ctl_mode = IDLE manual_voltage = 0 manual_current = 0 Unplug AC and EC keeps running. > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = -1 manual_current = -1 Replug AC. > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = 0 manual_current = 0 BUG=b:188457962 BRANCH=None TEST=Atlas. See the description above. Change-Id: I62b4e8bc9517900a5a32d2f35369c645fa8a60c3 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2929347 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3630102 Reviewed-by: Mike Lee <mike5@huaqin.corp-partner.google.com> Commit-Queue: wen zhang <zhangwen6@huaqin.corp-partner.google.com> Tested-by: wen zhang <zhangwen6@huaqin.corp-partner.google.com>
-rw-r--r--common/charge_state_v2.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 6c8cf971fb..9b86f008e4 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -16,6 +16,7 @@
#include "console.h"
#include "ec_ec_comm_master.h"
#include "ec_ec_comm_slave.h"
+#include "ec_commands.h"
#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
@@ -1046,6 +1047,9 @@ static const char * const batt_pres[] = {
"NO", "YES", "NOT_SURE",
};
+const char *mode_text[] = EC_CHARGE_MODE_TEXT;
+BUILD_ASSERT(ARRAY_SIZE(mode_text) == CHARGE_CONTROL_COUNT);
+
static void dump_charge_state(void)
{
#define DUMP(FLD, FMT) ccprintf(#FLD " = " FMT "\n", curr.FLD)
@@ -1083,7 +1087,9 @@ static void dump_charge_state(void)
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
DUMP(input_voltage, "%dmV");
#endif
- ccprintf("chg_ctl_mode = %d\n", chg_ctl_mode);
+ ccprintf("chg_ctl_mode = %s (%d)\n",
+ chg_ctl_mode < CHARGE_CONTROL_COUNT
+ ? mode_text[chg_ctl_mode] : "UNDEF", chg_ctl_mode);
ccprintf("manual_voltage = %d\n", manual_voltage);
ccprintf("manual_current = %d\n", manual_current);
ccprintf("user_current_limit = %dmA\n", user_current_limit);
@@ -1512,6 +1518,49 @@ const struct batt_params *charger_current_battery_params(void)
return &curr.batt;
}
+static void sustain_battery_soc(void)
+{
+ enum ec_charge_control_mode mode = chg_ctl_mode;
+ int soc;
+ int rv;
+
+ /* If either AC or battery is not present, nothing to do. */
+ if (!curr.ac || curr.batt.is_present != BP_YES
+ || !battery_sustainer_enabled())
+ return;
+
+ soc = charge_get_percent();
+
+ switch (chg_ctl_mode) {
+ case CHARGE_CONTROL_NORMAL:
+ /* Going up */
+ if (sustain_soc.upper < soc)
+ mode = CHARGE_CONTROL_DISCHARGE;
+ break;
+ case CHARGE_CONTROL_IDLE:
+ /* discharging naturally */
+ if (soc < sustain_soc.lower)
+ /* TODO: Charge slowly */
+ mode = CHARGE_CONTROL_NORMAL;
+ break;
+ case CHARGE_CONTROL_DISCHARGE:
+ /* discharging rapidly (discharge_on_ac) */
+ if (soc < sustain_soc.upper)
+ mode = CHARGE_CONTROL_IDLE;
+ break;
+ default:
+ return;
+ }
+
+ if (mode == chg_ctl_mode)
+ return;
+
+ rv = set_chg_ctrl_mode(mode);
+ CPRINTS("%s: %s control mode to %s",
+ __func__, rv == EC_SUCCESS ? "Switched" : "Failed to switch",
+ mode_text[mode]);
+}
+
/*****************************************************************************/
/* Hooks */
void charger_init(void)
@@ -1522,6 +1571,8 @@ void charger_init(void)
/* Manual voltage/current set to off */
manual_voltage = -1;
manual_current = -1;
+
+ battery_sustainer_disable();
}
DECLARE_HOOK(HOOK_INIT, charger_init, HOOK_PRIO_DEFAULT);
@@ -1661,7 +1712,7 @@ void charger_task(void *u)
}
} else {
/* Some things are only meaningful on AC */
- chg_ctl_mode = CHARGE_CONTROL_NORMAL;
+ set_chg_ctrl_mode(CHARGE_CONTROL_NORMAL);
battery_seems_to_be_dead = 0;
prev_ac = curr.ac;
}
@@ -1911,6 +1962,7 @@ wait_for_it:
(is_full != prev_full) ||
(curr.state != prev_state) ||
(curr.batt.display_charge != prev_disp_charge)) {
+ sustain_battery_soc();
show_charging_progress();
prev_charge = curr.batt.state_of_charge;
prev_disp_charge = curr.batt.display_charge;
@@ -2622,6 +2674,7 @@ static int command_chgstate(int argc, char **argv)
{
int rv;
int val;
+ char *e;
if (argc > 1) {
if (!strcasecmp(argv[1], "idle")) {
@@ -2656,6 +2709,20 @@ static int command_chgstate(int argc, char **argv)
return EC_ERROR_PARAM_COUNT;
if (!parse_bool(argv[2], &debugging))
return EC_ERROR_PARAM2;
+ } else if (!strcasecmp(argv[1], "sustain")) {
+ int lower, upper;
+
+ if (argc <= 3)
+ return EC_ERROR_PARAM_COUNT;
+ lower = strtoi(argv[2], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM2;
+ upper = strtoi(argv[3], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM3;
+ rv = battery_sustainer_set(lower, upper);
+ if (rv)
+ return EC_ERROR_INVAL;
} else {
return EC_ERROR_PARAM1;
}
@@ -2665,7 +2732,8 @@ static int command_chgstate(int argc, char **argv)
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(chgstate, command_chgstate,
- "[idle|discharge|debug on|off]",
+ "[idle|discharge|debug on|off]"
+ "\n[sustain <lower> <upper>]",
"Get/set charge state machine status");
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER