summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2019-07-09 14:44:57 -0700
committerCommit Bot <commit-bot@chromium.org>2019-07-23 18:07:15 +0000
commitecb74cc5610c835b32ccfabc7ff67a24eb3acb9b (patch)
tree457e769e7abeef9fa54bb6d5014ceaf490c5f989
parentdb3058dffca5e7659a301256ef8869fa7929092a (diff)
downloadchrome-ec-ecb74cc5610c835b32ccfabc7ff67a24eb3acb9b.tar.gz
servo_v4: Support changing CC polarity
Support an argument pol0/pol1 to the console command to change the CC polarity. When CC polarity change, apply the Rd/Rp to the proper CC line and fake the proper CC voltage. BRANCH=servo BUG=b:136014621 TEST=Tried the console commands: * Typed "cc src pol0" on servo v4 and checked DUT detected CC1: Port C0 CC1, Ena - Role: SNK-DFP State: SNK_READY, Flags: 0x4946 * Typed "cc src pol1" on servo v4 and checked DUT detected CC2: Port C0 CC2, Ena - Role: SNK-DFP State: SNK_READY, Flags: 0x4946 * Typed "cc snk pol0" on servo v4 and checked DUT detected CC1: Port C0 CC1, Ena - Role: SRC-DFP-VC State: SRC_DISCOVERY, Flags: 0x1608 * Typed "cc snk pol1" on servo v4 and checked DUT detected CC2: Port C0 CC2, Ena - Role: SRC-DFP-VC State: SRC_DISCOVERY, Flags: 0x1608 * Typed "cc srcdts pol0" on servo v4 and checked DUT detected CC1: Port C0 CC1, Ena - Role: SNK-DFP State: SNK_READY, Flags: 0x14946 * Typed "cc srcdts pol1" on servo v4 but resulted some hard reset issue during PD negotiation; need further investigation. Port C0 CC2, Ena - Role: SNK-UFP State: SNK_DISCOVERY, Flags: 0x10608 TEST=Ran the entire PD FAFT suite passed on both CC polarities. Change-Id: I7f983179b13e87a219bd26fe3665446df36de86e Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1693843 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> (cherry picked from commit 2340951cd98db31e971e270319f52991b62ca77d) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1715624
-rw-r--r--board/servo_v4/usb_pd_config.h1
-rw-r--r--board/servo_v4/usb_pd_policy.c104
2 files changed, 68 insertions, 37 deletions
diff --git a/board/servo_v4/usb_pd_config.h b/board/servo_v4/usb_pd_config.h
index 0a67583ff1..101ac973d3 100644
--- a/board/servo_v4/usb_pd_config.h
+++ b/board/servo_v4/usb_pd_config.h
@@ -61,6 +61,7 @@
#define CC_ALLOW_SRC (1 << 2) /* Allow charge through by policy? */
#define CC_ENABLE_DRP (1 << 3) /* Enable dual-role port */
#define CC_SNK_WITH_PD (1 << 4) /* Force enabling PD comm for sink role */
+#define CC_POLARITY (1 << 5) /* CC polarity */
/* TX uses SPI1 on PB3-4 for CHG port, SPI2 on PB 13-14 for DUT port */
#define SPI_REGS(p) ((p) ? STM32_SPI2_REGS : STM32_SPI1_REGS)
diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c
index b09803b839..c9ce2db514 100644
--- a/board/servo_v4/usb_pd_policy.c
+++ b/board/servo_v4/usb_pd_policy.c
@@ -60,6 +60,28 @@
CC_ALLOW_SRC | CC_ENABLE_DRP, \
CC_DISABLE_DTS)
+/* Macros to apply Rd/Rp to CC lines */
+#define DUT_ACTIVE_CC_SET(r, flags) \
+ gpio_set_flags(cc_config & CC_POLARITY ? \
+ CONCAT2(GPIO_USB_DUT_CC2_, r) : \
+ CONCAT2(GPIO_USB_DUT_CC1_, r), \
+ flags)
+#define DUT_INACTIVE_CC_SET(r, flags) \
+ gpio_set_flags(cc_config & CC_POLARITY ? \
+ CONCAT2(GPIO_USB_DUT_CC1_, r) : \
+ CONCAT2(GPIO_USB_DUT_CC2_, r), \
+ flags)
+#define DUT_BOTH_CC_SET(r, flags) \
+ do { \
+ gpio_set_flags(CONCAT2(GPIO_USB_DUT_CC1_, r), flags); \
+ gpio_set_flags(CONCAT2(GPIO_USB_DUT_CC2_, r), flags); \
+ } while (0)
+
+#define DUT_ACTIVE_CC_PU(r) DUT_ACTIVE_CC_SET(r, GPIO_OUT_HIGH)
+#define DUT_INACTIVE_CC_PU(r) DUT_INACTIVE_CC_SET(r, GPIO_OUT_HIGH)
+#define DUT_ACTIVE_CC_PD(r) DUT_ACTIVE_CC_SET(r, GPIO_OUT_LOW)
+#define DUT_BOTH_CC_PD(r) DUT_BOTH_CC_SET(r, GPIO_OUT_LOW)
+#define DUT_BOTH_CC_OPEN(r) DUT_BOTH_CC_SET(r, GPIO_INPUT)
/*
* Dynamic PDO that reflects capabilities present on the CHG port. Allow for
@@ -372,19 +394,17 @@ int pd_adc_read(int port, int cc)
/*
* In servo v4 hardware logic, both CC lines are wired directly
* to DUT. When servo v4 as a snk, DUT may source Vconn to CC2
- * and make the voltage high as vRd-3.0, which makes the PD
- * state mess up. As the PD state machine doesn't handle this
- * case. It assumes that CC2 is separated by a Type-C cable,
- * resulting a voltage lower than the max of vRa.
+ * (CC1 if polarity flip) and make the voltage high as vRd-3.0,
+ * which makes the PD state mess up. As the PD state machine
+ * doesn't handle this case. It assumes that CC2 (CC1 if
+ * polarity flip) is separated by a Type-C cable, resulting a
+ * voltage lower than the max of vRa.
*
* It fakes the voltage within vRa.
- *
- * TODO(b/136014621): Servo v4 always applies Rd/Rp to CC1 and
- * leaves CC2 open. Need change when it supports switching CC
- * polarity.
*/
if ((cc_config & CC_DISABLE_DTS) &&
- cc_pull_stored == TYPEC_CC_RD && port == DUT && cc == 1)
+ cc_pull_stored == TYPEC_CC_RD && port == DUT &&
+ cc == (cc_config & CC_POLARITY ? 0 : 1))
mv = 0;
else
mv = adc_read_channel(cc ? ADC_DUT_CC2_PD :
@@ -410,17 +430,18 @@ static int board_set_rp(int rp)
if (cc_config & CC_DISABLE_DTS) {
/*
* DTS mode is disabled, so only present the requested Rp value
- * on CC1 and leave all Rp/Rd resistors on CC2 disconnected.
+ * on CC1 (active) and leave all Rp/Rd resistors on CC2
+ * (inactive) disconnected.
*/
switch (rp) {
case TYPEC_RP_USB:
- gpio_set_flags(GPIO_USB_DUT_CC1_RPUSB, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RPUSB);
break;
case TYPEC_RP_1A5:
- gpio_set_flags(GPIO_USB_DUT_CC1_RP1A5, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RP1A5);
break;
case TYPEC_RP_3A0:
- gpio_set_flags(GPIO_USB_DUT_CC1_RP3A0, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RP3A0);
break;
case TYPEC_RP_RESERVED:
/*
@@ -447,16 +468,16 @@ static int board_set_rp(int rp)
*/
switch (rp) {
case TYPEC_RP_USB:
- gpio_set_flags(GPIO_USB_DUT_CC1_RP3A0, GPIO_OUT_HIGH);
- gpio_set_flags(GPIO_USB_DUT_CC2_RP1A5, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RP3A0);
+ DUT_INACTIVE_CC_PU(RP1A5);
break;
case TYPEC_RP_1A5:
- gpio_set_flags(GPIO_USB_DUT_CC1_RP1A5, GPIO_OUT_HIGH);
- gpio_set_flags(GPIO_USB_DUT_CC2_RPUSB, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RP1A5);
+ DUT_INACTIVE_CC_PU(RPUSB);
break;
case TYPEC_RP_3A0:
- gpio_set_flags(GPIO_USB_DUT_CC1_RP3A0, GPIO_OUT_HIGH);
- gpio_set_flags(GPIO_USB_DUT_CC2_RPUSB, GPIO_OUT_HIGH);
+ DUT_ACTIVE_CC_PU(RP3A0);
+ DUT_INACTIVE_CC_PU(RPUSB);
break;
case TYPEC_RP_RESERVED:
/*
@@ -488,32 +509,28 @@ int pd_set_rp_rd(int port, int cc_pull, int rp_value)
/* By default disconnect all Rp/Rd resistors from both CC lines */
/* Set Rd for CC1/CC2 to High-Z. */
- gpio_set_flags(GPIO_USB_DUT_CC1_RD, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC2_RD, GPIO_INPUT);
+ DUT_BOTH_CC_OPEN(RD);
/* Set Rp for CC1/CC2 to High-Z. */
- gpio_set_flags(GPIO_USB_DUT_CC1_RP3A0, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC2_RP3A0, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC1_RP1A5, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC2_RP1A5, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC1_RPUSB, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC2_RPUSB, GPIO_INPUT);
-
+ DUT_BOTH_CC_OPEN(RP3A0);
+ DUT_BOTH_CC_OPEN(RP1A5);
+ DUT_BOTH_CC_OPEN(RPUSB);
/* Set TX Hi-Z */
- gpio_set_flags(GPIO_USB_DUT_CC1_TX_DATA, GPIO_INPUT);
- gpio_set_flags(GPIO_USB_DUT_CC2_TX_DATA, GPIO_INPUT);
+ DUT_BOTH_CC_OPEN(TX_DATA);
if (cc_pull == TYPEC_CC_RP) {
rv = board_set_rp(rp_value);
} else if (cc_pull == TYPEC_CC_RD) {
/*
- * The DUT port uses a captive cable. If can present Rd on both
+ * The DUT port uses a captive cable. It can present Rd on both
* CC1 and CC2. If DTS mode is enabled, then present Rd on both
* CC lines. However, if DTS mode is disabled only present Rd on
- * CC1.
+ * CC1 (active).
*/
- gpio_set_flags(GPIO_USB_DUT_CC1_RD, GPIO_OUT_LOW);
- if (!(cc_config & CC_DISABLE_DTS))
- gpio_set_flags(GPIO_USB_DUT_CC2_RD, GPIO_OUT_LOW);
+ if (cc_config & CC_DISABLE_DTS)
+ DUT_ACTIVE_CC_PD(RD);
+ else
+ DUT_BOTH_CC_PD(RD);
+
}
rp_value_stored = rp_value;
@@ -761,6 +778,8 @@ static void print_cc_mode(void)
gpio_get_level(GPIO_DUT_CHG_EN) ? "on" : "off");
ccprintf("chg allowed: %s\n", cc_config & CC_ALLOW_SRC ? "on" : "off");
ccprintf("drp enabled: %s\n", cc_config & CC_ENABLE_DRP ? "on" : "off");
+ ccprintf("cc polarity: %s\n", cc_config & CC_POLARITY ? "cc2" :
+ "cc1");
}
@@ -857,6 +876,13 @@ static int command_cc(int argc, char **argv)
return EC_ERROR_PARAM2;
}
+ if (!strcasecmp(argv[2], "cc1"))
+ cc_config_new &= ~CC_POLARITY;
+ else if (!strcasecmp(argv[2], "cc2"))
+ cc_config_new |= CC_POLARITY;
+ else if (argc >= 3)
+ return EC_ERROR_PARAM3;
+
do_cc(cc_config_new);
print_cc_mode();
@@ -864,7 +890,7 @@ static int command_cc(int argc, char **argv)
}
DECLARE_CONSOLE_COMMAND(cc, command_cc,
"[off|on|src|snk|pdsnk|drp|srcdts|snkdts|pdsnkdts|"
- "drpdts]",
+ "drpdts] [cc1|cc2]",
"Servo_v4 DTS and CHG mode");
static void fake_disconnect_end(void)
@@ -935,6 +961,10 @@ static int cmd_usbc_action(int argc, char *argv[])
/* Set the limit back to original */
user_limited_max_mv = 20000;
do_cc(CONFIG_PDSNK(cc_config));
+ } else if (!strcasecmp(argv[1], "pol0")) {
+ do_cc(cc_config & ~CC_POLARITY);
+ } else if (!strcasecmp(argv[1], "pol1")) {
+ do_cc(cc_config | CC_POLARITY);
} else if (!strcasecmp(argv[1], "drp")) {
/* Toggle the DRP state, compatible with Plankton. */
do_cc(cc_config ^ CC_ENABLE_DRP);
@@ -948,5 +978,5 @@ static int cmd_usbc_action(int argc, char *argv[])
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(usbc_action, cmd_usbc_action,
- "5v|12v|20v|dev|drp",
+ "5v|12v|20v|dev|pol0|pol1|drp",
"Set Servo v4 type-C port state");