summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2019-06-13 13:32:28 -0700
committerCommit Bot <commit-bot@chromium.org>2019-07-23 17:14:50 +0000
commit51e0541a296b342137d9a3c8d5e9f745246cff49 (patch)
tree0fd077975a54febaac48ccda6f64d135c4005591
parent2b7747278d47a557a5192e45698eb28ac4e2b496 (diff)
downloadchrome-ec-51e0541a296b342137d9a3c8d5e9f745246cff49.tar.gz
servo_v4: Fake CC2 voltage when servo v4 as snk
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. It fakes the voltage within vRa so the PD state machine checks the value as expected. This is an issue only happening on servo v4 as it wires both CC lines to DUT. BUG=b:134700685 BRANCH=servo TEST=Servo v4 as snk, verified the CC2 is sensed vRa, i.e. the output "CC1:0" (TYPEC_CC_VOLT_OPEN), instead of "CC1:7" (TYPEC_CC_VOLT_SNK_3_0). 2019-06-18 15:05:47 > cc snk 2019-06-18 15:05:50 cc: on 2019-06-18 15:05:50 dts mode: off 2019-06-18 15:05:50 chg mode: off 2019-06-18 15:05:50 chg allowed: off 2019-06-18 15:05:50 > C1 st2 SNK_DISCONNECTED 2019-06-18 15:05:50 C1 st3 SNK_DISCONNECTED_DEBOUNCE 2019-06-18 15:05:50 C1 st5 SNK_DISCOVERY 2019-06-18 15:05:51 > tcpc 1 state 2019-06-18 15:05:53 Port C1, Dis - CC:2, CC0:6, CC1:0 2019-06-18 15:05:53 Alert: 0x00 Mask: 0x007d 2019-06-18 15:05:53 Power Status: 0x48 Mask: 0x00 TEST=Ran the PD FAFT test firmware_PDConnect passed. Change-Id: I10f1ffe80768100ee3ed4c374598df7c2f9a8d05 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1666468 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> (cherry picked from commit 1f14229fa7e499dfcee07d17add187598ff0a46c) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1686276
-rw-r--r--board/servo_v4/usb_pd_policy.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c
index 32a1a046d2..e45a920b1e 100644
--- a/board/servo_v4/usb_pd_policy.c
+++ b/board/servo_v4/usb_pd_policy.c
@@ -99,6 +99,10 @@ static int pd_src_rd_threshold[TYPEC_RP_RESERVED] = {
/* Saved value for the duration of faking PD disconnect */
static int fake_pd_disconnect_duration_us;
+/* Shadow what would be in TCPC register state. */
+static int rp_value_stored = TYPEC_RP_USB;
+static int cc_pull_stored = TYPEC_CC_RD;
+
/*
* Set the USB PD max voltage to value appropriate for the board version.
* The red/blue versions of servo_v4 have an ESD between VBUS and CC1/CC2
@@ -319,9 +323,28 @@ int pd_adc_read(int port, int cc)
if (port == 0)
mv = adc_read_channel(cc ? ADC_CHG_CC2_PD : ADC_CHG_CC1_PD);
- else if (!disable_cc)
- mv = adc_read_channel(cc ? ADC_DUT_CC2_PD : ADC_DUT_CC1_PD);
- else {
+ else if (!disable_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.
+ *
+ * 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 (disable_dts_mode && cc_pull_stored == TYPEC_CC_RD &&
+ port == DUT && cc == 1)
+ mv = 0;
+ else
+ mv = adc_read_channel(cc ? ADC_DUT_CC2_PD :
+ ADC_DUT_CC1_PD);
+ } else {
/*
* When disable_cc, fake the voltage on CC to 0 to avoid
* triggering some debounce logic.
@@ -407,10 +430,6 @@ static int board_set_rp(int rp)
return EC_SUCCESS;
}
-/* Shadow what would be in TCPC register state. */
-static int rp_value_stored = TYPEC_RP_USB;
-static int cc_pull_stored = TYPEC_CC_RD;
-
int pd_set_rp_rd(int port, int cc_pull, int rp_value)
{
int rv = EC_SUCCESS;