summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-10-17 14:12:38 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-01-20 10:09:48 +0000
commit91deb1e486a51f8d5519b39ffe393817bb4d2a8e (patch)
tree43149e096ed56f7f4767b017f7653d4a135c2641
parent9e887cba914d15939d06fcd604311cf8f6537860 (diff)
downloadchrome-ec-91deb1e486a51f8d5519b39ffe393817bb4d2a8e.tar.gz
pd: Limit input current to 500mA on PD voltage transition
Upon requesting a PD power contract at a new voltage, keep the input current limit at 500mA until PD_RDY is received. BUG=b:30744563,chrome-os-partner:59311,chrome-os-partner:44340 BRANCH=ryu, gru, glados TEST=Manual on kevin, set ilim to 5V through `chglim` console command, attach zinger. Set ilim to 20V through `chglim`, verify that ilim goes from 3A to 500mA to 3A. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I452f183cfb958780e336a9f99dc6398356de17a0 Reviewed-on: https://chromium-review.googlesource.com/399918 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/430245 (cherry picked from commit 92b3623dad47f47e06168bc5f4a04417254b7028) Reviewed-on: https://chromium-review.googlesource.com/430632 Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--common/charge_manager.c18
-rw-r--r--common/usb_pd_protocol.c13
-rw-r--r--include/charge_manager.h10
-rw-r--r--test/charge_manager.c8
4 files changed, 46 insertions, 3 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c
index 673a85ab6f..b055c5d28d 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -720,6 +720,24 @@ void charge_manager_set_ceil(int port, enum ceil_requestor requestor, int ceil)
}
}
+void charge_manager_force_ceil(int port, int ceil)
+{
+ ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_COUNT);
+
+ /*
+ * Force our input current to ceil if we're exceeding it, without
+ * waiting for our deferred task to run.
+ */
+ if (port == charge_port && ceil < charge_current)
+ board_set_charge_limit(ceil, CHARGE_SUPPLIER_PD);
+
+ /*
+ * Now inform charge_manager so it stays in sync with the state of
+ * the world.
+ */
+ charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, ceil);
+}
+
/**
* Select an 'override port', a port which is always the preferred charge port.
* Returns EC_SUCCESS on success, ec_error_list status on failure.
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 4c4ad4b40d..d3b1c4972a 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -606,9 +606,16 @@ static void pd_send_request_msg(int port, int always_send_request)
*/
return;
- /* Don't re-request the same voltage */
- if (!always_send_request && pd[port].prev_request_mv == supply_voltage)
- return;
+ if (!always_send_request) {
+ /* Don't re-request the same voltage */
+ if (pd[port].prev_request_mv == supply_voltage)
+ return;
+#ifdef CONFIG_CHARGE_MANAGER
+ /* Limit current to PD_MIN_MA during transition */
+ else
+ charge_manager_force_ceil(port, PD_MIN_MA);
+#endif
+ }
CPRINTF("Req C%d [%d] %dmV %dmA", port, RDO_POS(rdo),
supply_voltage, curr_limit);
diff --git a/include/charge_manager.h b/include/charge_manager.h
index faca0104eb..a88cbe6e06 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -54,6 +54,16 @@ enum ceil_requestor {
/* Update charge ceiling for a given port / requestor */
void charge_manager_set_ceil(int port, enum ceil_requestor requestor, int ceil);
+/*
+ * Update PD charge ceiling for a given port. In the event that our ceiling
+ * is currently above ceil, change the current limit before returning, without
+ * waiting for a charge manager refresh. This function should only be used in
+ * time-critical situations where we absolutely cannot proceed without limiting
+ * our input current, and it should only be called from the PD tasks.
+ * If you ever call this function then you are a terrible person.
+ */
+void charge_manager_force_ceil(int port, int ceil);
+
/* Select an 'override port', which is always the preferred charge port */
int charge_manager_set_override(int port);
int charge_manager_get_override(void);
diff --git a/test/charge_manager.c b/test/charge_manager.c
index 98871cd1b5..8bbfcf11ea 100644
--- a/test/charge_manager.c
+++ b/test/charge_manager.c
@@ -293,6 +293,14 @@ static int test_charge_ceil(void)
TEST_ASSERT(active_charge_port == 1);
TEST_ASSERT(active_charge_limit == 2500);
+ /* Verify forced ceil takes effect immediately */
+ charge_manager_force_ceil(1, 500);
+ TEST_ASSERT(active_charge_port == 1);
+ TEST_ASSERT(active_charge_limit == 500);
+ wait_for_charge_manager_refresh();
+ TEST_ASSERT(active_charge_port == 1);
+ TEST_ASSERT(active_charge_limit == 500);
+
return EC_SUCCESS;
}