summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2019-05-08 15:52:18 +0800
committerchrome-bot <chrome-bot@chromium.org>2019-05-14 23:57:49 -0700
commit1598a615eb150916ea323e212b87298c3a6fcfb6 (patch)
tree073d65cfd6d64055e0ab07d042144376c61d2938
parentf2dcc64ad4d7f2bca17410e8b2036f31b0499745 (diff)
downloadchrome-ec-stabilize-12206.B.tar.gz
charge_manager: Revisit charge supplier priority.stabilize-12206.B
According to USB-C spec 1.3 Table 4-17 "Precedence of power source usage", the supplier's priority should be: USB-C 3.0A/1.5A > BC1.2 > USB-C under 1.5A. This CL propose to raise the BC1.2 priority to fix that charge_manager won't choose BC1.2 when the port reports it can supply both TYPEC 500ma and BC1.2 supplier. According to the spec mentioned aboved, we should prefer BC1.2 rather than TYPEC. Besdies, charge_manager is able to pick the supplier which provides the higheste power. The CL simplifies the supplier priority a bit by taking advantage of the feature. TEST=Charge kukui with 5V/2A charger and see it can drain 1.34A (DCP current bound of mt6370 is 1.5A) rather than 0.5A. TEST=Charge kukui with Type-C 5V3A/CDP/DCP/SDP/PD charger randomly and see that the current it drains is reasonable. TEST=Charge soraka with 'A', and plug another port with 'B', and see it can transist the sinking port from A to B. Here (A, B) are: 1. (SDP 5V0.5A, Type-C 5V3A) 2. (CDP 5V1.5A, PD) 3. (SDP 5V0.5A, CDP 5V1.5A) 4. (CDP 5V1.5A, Type-C 5V3A) 5. (Type-C 5V3A, PD) BUG=b:131126720 BRANCH=None Change-Id: I46384e09d764aa926129358657d0593fca4923c2 Signed-off-by: Yilun Lin <yllin@google.com> Reviewed-on: https://chromium-review.googlesource.com/1581859 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Yilun Lin <yllin@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/host/board.h1
-rw-r--r--common/charge_manager.c74
-rw-r--r--include/charge_manager.h1
-rw-r--r--test/charge_manager.c1
4 files changed, 58 insertions, 19 deletions
diff --git a/board/host/board.h b/board/host/board.h
index 494edf5eb3..2d7c492238 100644
--- a/board/host/board.h
+++ b/board/host/board.h
@@ -50,6 +50,7 @@ enum {
CHARGE_SUPPLIER_TEST7,
CHARGE_SUPPLIER_TEST8,
CHARGE_SUPPLIER_TEST9,
+ CHARGE_SUPPLIER_TEST10,
CHARGE_SUPPLIER_TEST_COUNT
};
diff --git a/common/charge_manager.c b/common/charge_manager.c
index cdc3bc228b..8095c63517 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -28,7 +28,22 @@
#define POWER_SWAP_TIMEOUT (PD_T_SRC_RECOVER_MAX + PD_T_SRC_TURN_ON + \
PD_T_SAFE_0V + 500 * MSEC)
-/* Charge supplier priority: lower number indicates higher priority. */
+/*
+ * Charge supplier priority: lower number indicates higher priority.
+ *
+ * - Always pick dedicated charge if present since that is the best product
+ * decision.
+ * - Pick PD negotiated chargers over everything else since they have the most
+ * power potential and they may not currently be negotiated at a high power.
+ * (and they can at least provide 15W)
+ * - Pick Type-C which supplier current >= 1.5A, which has higher prioirty
+ * than the BC1.2 and Type-C with current under 1.5A. (USB-C spec 1.3
+ * Table 4-17: TYPEC 3.0A, 1.5A > BC1.2 > TYPEC under 1.5A)
+ * - Then pick among the propreitary and BC1.2 chargers which ever has the
+ * highest available power.
+ * - Last, pick one from the rest suppliers. Also note that some boards assume
+ * wireless suppliers as low priority.
+ */
test_mockable const int supplier_priority[] = {
#if CONFIG_DEDICATED_CHARGE_PORT_COUNT > 0
[CHARGE_SUPPLIER_DEDICATED] = 0,
@@ -37,17 +52,18 @@ test_mockable const int supplier_priority[] = {
[CHARGE_SUPPLIER_TYPEC] = 2,
[CHARGE_SUPPLIER_TYPEC_DTS] = 2,
#ifdef CHARGE_MANAGER_BC12
- [CHARGE_SUPPLIER_PROPRIETARY] = 2,
+ [CHARGE_SUPPLIER_PROPRIETARY] = 3,
[CHARGE_SUPPLIER_BC12_DCP] = 3,
- [CHARGE_SUPPLIER_BC12_CDP] = 4,
- [CHARGE_SUPPLIER_BC12_SDP] = 5,
- [CHARGE_SUPPLIER_OTHER] = 6,
- [CHARGE_SUPPLIER_VBUS] = 7,
+ [CHARGE_SUPPLIER_BC12_CDP] = 3,
+ [CHARGE_SUPPLIER_BC12_SDP] = 3,
+ [CHARGE_SUPPLIER_TYPEC_UNDER_1_5A] = 4,
+ [CHARGE_SUPPLIER_OTHER] = 4,
+ [CHARGE_SUPPLIER_VBUS] = 4,
#endif
#ifdef CONFIG_WIRELESS_CHARGER_P9221_R7
- [CHARGE_SUPPLIER_WPC_BPP] = 6,
- [CHARGE_SUPPLIER_WPC_EPP] = 6,
- [CHARGE_SUPPLIER_WPC_GPP] = 6,
+ [CHARGE_SUPPLIER_WPC_BPP] = 5,
+ [CHARGE_SUPPLIER_WPC_EPP] = 5,
+ [CHARGE_SUPPLIER_WPC_GPP] = 5,
#endif
};
@@ -900,7 +916,16 @@ void typec_set_input_current_limit(int port, typec_current_t max_ma,
uint32_t supply_voltage)
{
struct charge_port_info charge;
+ int i;
+ int supplier;
int dts = !!(max_ma & TYPEC_CURRENT_DTS_MASK);
+ static const enum charge_supplier typec_suppliers[] = {
+ CHARGE_SUPPLIER_TYPEC,
+ CHARGE_SUPPLIER_TYPEC_DTS,
+#ifdef CHARGE_MANAGER_BC12
+ CHARGE_SUPPLIER_TYPEC_UNDER_1_5A,
+#endif /* CHARGE_MANAGER_BC12 */
+ };
charge.current = max_ma & TYPEC_CURRENT_ILIM_MASK;
charge.voltage = supply_voltage;
@@ -913,19 +938,30 @@ void typec_set_input_current_limit(int port, typec_current_t max_ma,
if (dts)
charge.current = MIN(charge.current, 500);
#endif
- charge_manager_update_charge(dts ? CHARGE_SUPPLIER_TYPEC_DTS :
- CHARGE_SUPPLIER_TYPEC,
- port, &charge);
+
+ supplier = dts ? CHARGE_SUPPLIER_TYPEC_DTS : CHARGE_SUPPLIER_TYPEC;
+
+#ifdef CHARGE_MANAGER_BC12
+ /*
+ * According to USB-C spec 1.3 Table 4-17 "Precedence of power source
+ * usage", the priority should be: USB-C 3.0A, 1.5A > BC1.2 > USB-C
+ * under 1.5A. Choosed the corresponding supplier type, according to
+ * charge current, to update.
+ */
+ if (charge.current < 1500)
+ supplier = CHARGE_SUPPLIER_TYPEC_UNDER_1_5A;
+#endif /* CHARGE_MANAGER_BC12 */
+
+ charge_manager_update_charge(supplier, port, &charge);
/*
- * Zero TYPEC / TYPEC-DTS when zero'ing the other, since they are
- * mutually exclusive and DTS status of port partner will no longer
- * be reflected on disconnect.
+ * TYPEC / TYPEC-DTS / TYPEC-UNDER_1_5A should be mutually exclusive.
+ * Zero'ing all the other suppliers.
*/
- if (max_ma == 0 || supply_voltage == 0)
- charge_manager_update_charge(dts ? CHARGE_SUPPLIER_TYPEC :
- CHARGE_SUPPLIER_TYPEC_DTS,
- port, &charge);
+ for (i = 0; i < ARRAY_SIZE(typec_suppliers); ++i)
+ if (supplier != typec_suppliers[i])
+ charge_manager_update_charge(typec_suppliers[i], port,
+ NULL);
}
void charge_manager_update_charge(int supplier,
diff --git a/include/charge_manager.h b/include/charge_manager.h
index 6177408acb..cb32eb623d 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -39,6 +39,7 @@ enum charge_supplier {
CHARGE_SUPPLIER_BC12_CDP,
CHARGE_SUPPLIER_BC12_SDP,
CHARGE_SUPPLIER_PROPRIETARY,
+ CHARGE_SUPPLIER_TYPEC_UNDER_1_5A,
CHARGE_SUPPLIER_OTHER,
CHARGE_SUPPLIER_VBUS,
#endif /* CHARGE_MANAGER_BC12 */
diff --git a/test/charge_manager.c b/test/charge_manager.c
index 90bdf37a66..e50e0e38ee 100644
--- a/test/charge_manager.c
+++ b/test/charge_manager.c
@@ -27,6 +27,7 @@ const int supplier_priority[] = {
[CHARGE_SUPPLIER_TEST7] = 5,
[CHARGE_SUPPLIER_TEST8] = 6,
[CHARGE_SUPPLIER_TEST9] = 6,
+ [CHARGE_SUPPLIER_TEST10] = 7,
};
BUILD_ASSERT((int)CHARGE_SUPPLIER_COUNT == (int)CHARGE_SUPPLIER_TEST_COUNT);
BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT);