diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-10-19 11:13:50 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-10-27 13:19:51 -0700 |
commit | 2bd7dce32eed716b850c370f79717ad47da17c01 (patch) | |
tree | cdbb8d838c14d8e49ca159731e0f12a051c64235 | |
parent | cb4a76e8022c73fb0a0b50700912d86f41ea3dbb (diff) | |
download | chrome-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.c | 15 | ||||
-rw-r--r-- | common/charge_state_v2.c | 35 | ||||
-rw-r--r-- | include/charge_manager.h | 3 | ||||
-rw-r--r-- | include/config.h | 8 | ||||
-rw-r--r-- | include/ec_commands.h | 5 | ||||
-rw-r--r-- | test/sbs_charging_v2.c | 10 | ||||
-rw-r--r-- | util/ectool.c | 1 |
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) ¶ms, 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, ¶ms, 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); |