summaryrefslogtreecommitdiff
path: root/common/charge_state_v2.c
diff options
context:
space:
mode:
authorPhilip Chen <philipchen@google.com>2018-05-17 18:55:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-21 18:19:22 -0700
commit453647e21a9e584cd0ee8567efef3d81371ae27f (patch)
treecd1a505e1945c2233cef34a40bf3a9f0a555544e /common/charge_state_v2.c
parentd8186821885b7403d3118810ab56fc617068db1d (diff)
downloadchrome-ec-453647e21a9e584cd0ee8567efef3d81371ae27f.tar.gz
charge_state_v2: Throttle AP in low battery voltage
When EC sees voltage drops below BAT_LOW_VOLTAGE_THRESH, we kick off a timer and ask AP to throttle. When the timer expires which means EC hasn't seen under-voltage for BAT_UVP_TIMEOUT_US, we ask AP to stop throttling. We reset the throttling status and do nothing when AP is off (S5). BUG=b:73050145, chromium:838754 BRANCH=scarlet TEST=manually test on scarlet, confirm EC sends EC_HOST_EVENT_THROTTLE_START and EC_HOST_EVENT_THROTTLE_STOP host events when entering/exiting UVP. Change-Id: Ia760989f760f95549f7a8a8acb1d01de23feab5a Signed-off-by: Philip Chen <philipchen@google.com> Reviewed-on: https://chromium-review.googlesource.com/1064983 Commit-Ready: Philip Chen <philipchen@chromium.org> Tested-by: Philip Chen <philipchen@chromium.org> Reviewed-by: David Schneider <dnschneid@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'common/charge_state_v2.c')
-rw-r--r--common/charge_state_v2.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index f237e84bc1..28ec48c3b0 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -55,6 +55,14 @@
(BAT_MAX_DISCHG_CURRENT * BAT_OCP_HYSTERESIS_PCT / 100) /* mA */
#endif /* CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT */
+#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE
+#ifndef CONFIG_HOSTCMD_EVENTS
+#error "CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE needs CONFIG_HOSTCMD_EVENTS"
+#endif /* CONFIG_HOSTCMD_EVENTS */
+#define BAT_UVP_TIMEOUT_US (60 * SECOND)
+static timestamp_t uvp_throttle_start_time;
+#endif /* CONFIG_THROTTLE_AP_ON_BAT_OLTAGE */
+
static int charge_request(int voltage, int current);
/*
@@ -1320,7 +1328,7 @@ static int shutdown_on_critical_battery(void)
* host events. We send these even if the AP is off, since the AP will read and
* discard any events it doesn't care about the next time it wakes up.
*/
-static void notify_host_of_low_battery(void)
+static void notify_host_of_low_battery_charge(void)
{
/* We can't tell what the current charge is. Assume it's okay. */
if (curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)
@@ -1343,6 +1351,29 @@ static void set_charge_state(enum charge_state_v2 state)
curr.state = state;
}
+static void notify_host_of_low_battery_voltage(void)
+{
+#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE
+ if ((curr.batt.flags & BATT_FLAG_BAD_VOLTAGE) ||
+ chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ return;
+
+ if (curr.batt.voltage < BAT_LOW_VOLTAGE_THRESH) {
+ if (!uvp_throttle_start_time.val) {
+ throttle_ap(THROTTLE_ON, THROTTLE_SOFT,
+ THROTTLE_SRC_BAT_VOLTAGE);
+ }
+ uvp_throttle_start_time = get_time();
+ } else if (uvp_throttle_start_time.val &&
+ (get_time().val > uvp_throttle_start_time.val +
+ BAT_UVP_TIMEOUT_US)) {
+ throttle_ap(THROTTLE_OFF, THROTTLE_SOFT,
+ THROTTLE_SRC_BAT_VOLTAGE);
+ uvp_throttle_start_time.val = 0;
+ }
+#endif
+}
+
static void notify_host_of_over_current(struct batt_params *batt)
{
#ifdef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT
@@ -1400,6 +1431,16 @@ DECLARE_HOOK(HOOK_AC_CHANGE, charge_wakeup, HOOK_PRIO_DEFAULT);
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_base_reset, HOOK_PRIO_DEFAULT);
#endif
+#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE
+static void bat_low_voltage_throttle_reset(void)
+{
+ uvp_throttle_start_time.val = 0;
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN,
+ bat_low_voltage_throttle_reset,
+ HOOK_PRIO_DEFAULT);
+#endif
+
static int get_desired_input_current(enum battery_present batt_present,
const struct charger_info * const info)
{
@@ -1702,7 +1743,8 @@ wait_for_it:
/* Wait on the dynamic info until the static info is good. */
if (!need_static)
update_dynamic_battery_info();
- notify_host_of_low_battery();
+ notify_host_of_low_battery_charge();
+ notify_host_of_low_battery_voltage();
/* And the EC console */
is_full = calc_is_full();