summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-10-19 11:13:50 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-10-27 13:19:51 -0700
commit2bd7dce32eed716b850c370f79717ad47da17c01 (patch)
treecdbb8d838c14d8e49ca159731e0f12a051c64235
parentcb4a76e8022c73fb0a0b50700912d86f41ea3dbb (diff)
downloadchrome-ec-2bd7dce32eed716b850c370f79717ad47da17c01.tar.gz
charger: Add LIMIT_POWER charger param for low bat + weak charger
Add support for two new configs to specify critical energy battery percentage and critical external charger power. When we are under both thresholds, set the LIMIT_POWER charger parameter to inform the AP that it should conserve power to avoid brownout, and consider jumping to EC RW to negotiate PD. In addition, modify the existing CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON to allow power-up regardless of power level if a 15W+ charger is attached, since there is a reasonable chance it may speak PD and provide sufficient power to boot the AP. BUG=chromium:537269 TEST=Manual on Glados. Set CHG_MW thresh to 20000, BAT_PCT to 50. Verify that LIMIT_POWER charger param is set until Zinger negotiates to 20V. Also veify that system can boot with Donette. BRANCH=None Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: Ic963c82fea4ad10e8a5d7e476c5ce3e5ae525dad Reviewed-on: https://chromium-review.googlesource.com/306774 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--common/charge_manager.c15
-rw-r--r--common/charge_state_v2.c35
-rw-r--r--include/charge_manager.h3
-rw-r--r--include/config.h8
-rw-r--r--include/ec_commands.h5
-rw-r--r--test/sbs_charging_v2.c10
-rw-r--r--util/ectool.c1
7 files changed, 74 insertions, 3 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c
index d88cc0cab8..2dec5210b6 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -804,6 +804,21 @@ int charge_manager_get_active_charge_port(void)
return charge_port;
}
+/**
+ * Return the power limit (uW) set by charge manager.
+ */
+int charge_manager_get_power_limit_uw(void)
+{
+ int current_ma = charge_current;
+ int voltage_mv = charge_voltage;
+
+ if (current_ma == CHARGE_CURRENT_UNINITIALIZED ||
+ voltage_mv == CHARGE_VOLTAGE_UNINITIALIZED)
+ return 0;
+ else
+ return current_ma * voltage_mv;
+}
+
#ifndef TEST_BUILD
static int hc_pd_power_info(struct host_cmd_handler_args *args)
{
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index b01f537b20..b4ffd06aa5 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -7,6 +7,7 @@
#include "battery.h"
#include "battery_smart.h"
+#include "charge_manager.h"
#include "charge_state.h"
#include "charger.h"
#include "chipset.h"
@@ -33,6 +34,9 @@
#define PRECHARGE_TIMEOUT_US (PRECHARGE_TIMEOUT * SECOND)
#define LFCC_EVENT_THRESH 5 /* Full-capacity change reqd for host event */
+/* Prior to negotiating PD, most PD chargers advertise 15W */
+#define LIKELY_PD_USBC_POWER_MW 15000
+
/*
* State for charger_task(). Here so we can reset it on a HOOK_INIT, and
* because stack space is more limited than .bss
@@ -907,6 +911,19 @@ int charge_prevent_power_on(void)
CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON)
prevent_power_on = 1;
+#ifdef CONFIG_CHARGER_LIMIT_POWER_THRESH_BAT_PCT
+ /*
+ * Allow power-on if our charger advertises more than
+ * LIKELY_PD_USBC_POWER_MW since it may speak PD and provide
+ * sufficient power once we enable PD communication.
+ */
+ if (prevent_power_on)
+ if (charge_manager_get_power_limit_uw() >=
+ MIN(LIKELY_PD_USBC_POWER_MW * 1000,
+ CONFIG_CHARGER_LIMIT_POWER_THRESH_CHG_MW * 1000));
+ prevent_power_on = 0;
+#endif
+
/*
* Factory override: Always allow power on if WP is disabled,
* except when EC is starting up, due to brown out potential.
@@ -1144,6 +1161,23 @@ static int charge_command_charge_state(struct host_cmd_handler_args *args)
case CS_PARAM_CHG_OPTION:
val = curr.chg.option;
break;
+ case CS_PARAM_LIMIT_POWER:
+#ifdef CONFIG_CHARGER_LIMIT_POWER_THRESH_BAT_PCT
+ /*
+ * LIMIT_POWER status is based on battery level
+ * and external charger power.
+ */
+ if ((curr.batt.is_present != BP_YES ||
+ curr.batt.state_of_charge <
+ CONFIG_CHARGER_LIMIT_POWER_THRESH_BAT_PCT)
+ && charge_manager_get_power_limit_uw() <
+ CONFIG_CHARGER_LIMIT_POWER_THRESH_CHG_MW
+ * 1000 && system_is_locked())
+ val = 1;
+ else
+#endif
+ val = 0;
+ break;
default:
rv = EC_RES_INVALID_PARAM;
}
@@ -1181,6 +1215,7 @@ static int charge_command_charge_state(struct host_cmd_handler_args *args)
rv = EC_RES_ERROR;
break;
case CS_PARAM_CHG_STATUS:
+ case CS_PARAM_LIMIT_POWER:
/* Can't set this */
rv = EC_RES_ACCESS_DENIED;
break;
diff --git a/include/charge_manager.h b/include/charge_manager.h
index 6cfd6cc7ce..d3f14117b5 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -74,6 +74,9 @@ int charge_manager_get_override(void);
/* Returns the current active charge port, as determined by charge manager */
int charge_manager_get_active_charge_port(void);
+/* Return the power limit (uW) set by charge manager. */
+int charge_manager_get_power_limit_uw(void);
+
#ifdef CONFIG_USB_PD_LOGGING
/* Save power state log entry for the given port */
void charge_manager_save_log(int port);
diff --git a/include/config.h b/include/config.h
index 26fced9a46..8f8469f3da 100644
--- a/include/config.h
+++ b/include/config.h
@@ -400,6 +400,14 @@
#undef CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON
/*
+ * Low energy thresholds - when battery level is below BAT_PCT and an external
+ * charger provides less than CHG_MW of power, inform the AP of the situation
+ * through the LIMIT_POWER host event.
+ */
+#undef CONFIG_CHARGER_LIMIT_POWER_THRESH_BAT_PCT
+#undef CONFIG_CHARGER_LIMIT_POWER_THRESH_CHG_MW
+
+/*
* Equivalent of CONFIG_BATTERY_OVERRIDE_PARAMS for use with
* CONFIG_CHARGER_V2
*/
diff --git a/include/ec_commands.h b/include/ec_commands.h
index b959db783e..54f91e3054 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2839,6 +2839,11 @@ enum charge_state_params {
CS_PARAM_CHG_INPUT_CURRENT, /* charger input current limit */
CS_PARAM_CHG_STATUS, /* charger-specific status */
CS_PARAM_CHG_OPTION, /* charger-specific options */
+ CS_PARAM_LIMIT_POWER, /*
+ * Check if power is limited due to
+ * low battery and / or a weak external
+ * charger. READ ONLY.
+ */
/* How many so far? */
CS_NUM_BASE_PARAMS,
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
index 7bf467d2be..5e11c722fe 100644
--- a/test/sbs_charging_v2.c
+++ b/test/sbs_charging_v2.c
@@ -454,7 +454,10 @@ static int test_hc_charge_state(void)
&params, sizeof(params),
&resp, sizeof(resp));
TEST_ASSERT(rv == EC_RES_SUCCESS);
- TEST_ASSERT(resp.get_param.value);
+ if (i != CS_PARAM_LIMIT_POWER)
+ TEST_ASSERT(resp.get_param.value);
+ else
+ TEST_ASSERT(!resp.get_param.value);
/* Bump it up a bit */
tmp = resp.get_param.value;
@@ -465,7 +468,8 @@ static int test_hc_charge_state(void)
tmp -= 128; /* Should be valid delta */
break;
case CS_PARAM_CHG_STATUS:
- /* This one can't be set */
+ case CS_PARAM_LIMIT_POWER:
+ /* These ones can't be set */
break;
case CS_PARAM_CHG_OPTION:
tmp = CHG_OPT2;
@@ -477,7 +481,7 @@ static int test_hc_charge_state(void)
rv = test_send_host_command(EC_CMD_CHARGE_STATE, 0,
&params, sizeof(params),
&resp, sizeof(resp));
- if (i == CS_PARAM_CHG_STATUS)
+ if (i == CS_PARAM_CHG_STATUS || i == CS_PARAM_LIMIT_POWER)
TEST_ASSERT(rv == EC_RES_ACCESS_DENIED);
else
TEST_ASSERT(rv == EC_RES_SUCCESS);
diff --git a/util/ectool.c b/util/ectool.c
index 1c409846e0..0b2f561211 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -5136,6 +5136,7 @@ static const char * const base_params[] = {
"chg_input_current",
"chg_status",
"chg_option",
+ "limit_power",
};
BUILD_ASSERT(ARRAY_SIZE(base_params) == CS_NUM_BASE_PARAMS);