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>
This commit is contained in:
Shawn Nematbakhsh
2015-10-19 11:13:50 -07:00
committed by chrome-bot
parent cb4a76e802
commit 2bd7dce32e
7 changed files with 74 additions and 3 deletions

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -399,6 +399,14 @@
/* Minimum battery percentage for power on */
#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

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);