summaryrefslogtreecommitdiff
path: root/common/charge_manager.c
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-11-18 11:28:00 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-21 04:37:50 +0000
commit2a9a859655689246630de3c86c7a254e611c1718 (patch)
tree2529e9db5b8aea1170bcefa564b4fab6f7db66bd /common/charge_manager.c
parent673255588bbf585aa3f9b79defe88dd85025eb36 (diff)
downloadchrome-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.c63
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);