diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-11-18 11:28:00 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-21 04:37:50 +0000 |
commit | 2a9a859655689246630de3c86c7a254e611c1718 (patch) | |
tree | 2529e9db5b8aea1170bcefa564b4fab6f7db66bd /common/charge_manager.c | |
parent | 673255588bbf585aa3f9b79defe88dd85025eb36 (diff) | |
download | chrome-ec-2a9a859655689246630de3c86c7a254e611c1718.tar.gz |
pd: if our request is rejected, go to SNK_READY
If our request is rejected, go to SNK_READY, but don't set
explicit contract flag.
This also changes charge manager slightly to avoid new power
request loops. A new power request is only requested if the
charge port changes, or if the active charge port changes its
voltage/current offering. A new power request does not occur
if the current ceiling changes, since the existing contract
still suffices.
BUG=chrome-os-partner:33692, chrome-os-partner:28332
BRANCH=samus
TEST=make buildall. use samus and make sure we negotiate for 20V
as normal. modify zinger to send a REJECT and make sure we go from
PD_STATE_SNK_REQUESTED to PD_STATE_SNK_READY and explicit contract
bit is 0.
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Change-Id: Iec02663364dcdc4aa66c681ec08911db7424abbc
Reviewed-on: https://chromium-review.googlesource.com/230522
Reviewed-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common/charge_manager.c')
-rw-r--r-- | common/charge_manager.c | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c index ba0afd5958..d8990e56da 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -26,6 +26,8 @@ static int charge_ceil[PD_PORT_COUNT]; /* Store current state of port enable / charge current. */ static int charge_port = CHARGE_PORT_NONE; static int charge_current = CHARGE_CURRENT_UNINITIALIZED; +static int charge_current_uncapped = CHARGE_CURRENT_UNINITIALIZED; +static int charge_voltage; static int charge_supplier = CHARGE_SUPPLIER_NONE; static int override_port = OVERRIDE_OFF; @@ -82,7 +84,10 @@ static void charge_manager_refresh(void) { int new_supplier = CHARGE_SUPPLIER_NONE; int new_port = CHARGE_PORT_NONE; - int new_charge_current, new_charge_voltage, i, j, old_port; + int new_charge_current, new_charge_current_uncapped; + int new_charge_voltage, i, j; + int updated_new_port = CHARGE_PORT_NONE; + int updated_old_port = CHARGE_PORT_NONE; /* Skip port selection on OVERRIDE_DONT_CHARGE. */ if (override_port != OVERRIDE_DONT_CHARGE) { @@ -135,15 +140,19 @@ static void charge_manager_refresh(void) override_port = OVERRIDE_OFF; } - if (new_supplier == CHARGE_SUPPLIER_NONE) - new_charge_current = new_charge_voltage = 0; - else { - new_charge_current = + if (new_supplier == CHARGE_SUPPLIER_NONE) { + new_charge_current = 0; + new_charge_current_uncapped = 0; + new_charge_voltage = 0; + } else { + new_charge_current_uncapped = available_charge[new_supplier][new_port].current; /* Enforce port charge ceiling. */ - if (charge_ceil[new_port] != CHARGE_CEIL_NONE && - charge_ceil[new_port] < new_charge_current) - new_charge_current = charge_ceil[new_port]; + if (charge_ceil[new_port] != CHARGE_CEIL_NONE) + new_charge_current = MIN(charge_ceil[new_port], + new_charge_current_uncapped); + else + new_charge_current = new_charge_current_uncapped; new_charge_voltage = available_charge[new_supplier][new_port].voltage; @@ -156,17 +165,35 @@ static void charge_manager_refresh(void) new_charge_current, new_charge_voltage); board_set_charge_limit(new_charge_current); board_set_active_charge_port(new_port); - - charge_current = new_charge_current; - charge_supplier = new_supplier; - old_port = charge_port; - charge_port = new_port; - - if (new_port != CHARGE_PORT_NONE) - pd_set_new_power_request(new_port); - if (old_port != CHARGE_PORT_NONE) - pd_set_new_power_request(old_port); } + + /* + * Signal new power request only if the port changed, the voltage + * on the same port changed, or the actual uncapped current + * on the same port changed (don't consider ceil). + */ + if (new_port != CHARGE_PORT_NONE && + (new_port != charge_port || + new_charge_current_uncapped != charge_current_uncapped || + new_charge_voltage != charge_voltage)) + updated_new_port = new_port; + + /* Signal new power request on old port if we're switching away. */ + if (charge_port != new_port && charge_port != CHARGE_PORT_NONE) + updated_old_port = charge_port; + + /* Update globals to reflect current state. */ + charge_current = new_charge_current; + charge_current_uncapped = new_charge_current_uncapped; + charge_voltage = new_charge_voltage; + charge_supplier = new_supplier; + charge_port = new_port; + + /* New power requests must be set only after updating the globals. */ + if (updated_new_port != CHARGE_PORT_NONE) + pd_set_new_power_request(updated_new_port); + if (updated_old_port != CHARGE_PORT_NONE) + pd_set_new_power_request(updated_old_port); } DECLARE_DEFERRED(charge_manager_refresh); |