summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2015-04-28 14:42:59 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-04-30 02:31:18 +0000
commit63786f247e2f8a058465b75cd476ef0c7ec5979f (patch)
tree8c380b1dbf448fc70b159d9872329f1d0eabd6ae /common
parentfab26ee8914ad9f111d982388aeec61c13d6b1c6 (diff)
downloadchrome-ec-63786f247e2f8a058465b75cd476ef0c7ec5979f.tar.gz
samus_pd: Request different DP pin modes including multi-function.
Previously samus_pd just picked pin mode E without regard to what the UFP was requesting. This change surveys the UFP's DP pin capabilities and then requests the appropriate pin config. Additionally if the UFP supports multi-function and has preferred it during the initial DP status message, samus will configure its type-c mux in 'dock' mode. Signed-off-by: Todd Broch <tbroch@chromium.org> BRANCH=samus BUG=chrome-os-partner:38728 TEST=manual, 1. hoho + samus, pin mode = 'C' 2. dingdong + samus, pin mode = 'E'. 3. apple type-C HDMI multiport + samus, pin mode = 'D' and USB device enumerates as SuperSpeed. 4. plankton + samus w/ patch asserting alternate mode with multi-function preferred sets config to 'F' now and only drives DP out on 2 lanes w/ other two allowing USB key to be seen. Change-Id: Ie4764c33f108e8a88f0052b64ddb96cb92e5a78b Reviewed-on: https://chromium-review.googlesource.com/267796 Commit-Queue: Todd Broch <tbroch@chromium.org> Tested-by: Todd Broch <tbroch@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_policy.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 9d12b48434..bd0915a50b 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -406,6 +406,53 @@ static void dfp_consume_attention(int port, uint32_t *payload)
modep->fx->attention(port, payload);
}
+/*
+ * This algorithm defaults to choosing higher pin config over lower ones. Pin
+ * configs are organized in pairs with the following breakdown.
+ *
+ * NAME | SIGNALING | OUTPUT TYPE | MULTI-FUNCTION | PIN CONFIG
+ * -------------------------------------------------------------
+ * A | USB G2 | ? | no | 00_0001
+ * B | USB G2 | ? | yes | 00_0010
+ * C | DP | CONVERTED | no | 00_0100
+ * D | PD | CONVERTED | yes | 00_1000
+ * E | DP | DP | no | 01_0000
+ * F | PD | DP | yes | 10_0000
+ *
+ * if UFP has NOT asserted multi-function preferred code masks away B/D/F
+ * leaving only A/C/E. For single-output dongles that should leave only one
+ * possible pin config depending on whether its a converter DP->(VGA|HDMI) or DP
+ * output. If someone creates a multi-output dongle presumably they would need
+ * to either offer different mode capabilities depending upon connection type or
+ * the DFP would need additional system policy to expose those options.
+ */
+int pd_dfp_dp_get_pin_mode(int port, uint32_t status)
+{
+ struct svdm_amode_data *modep = get_modep(port, USB_SID_DISPLAYPORT);
+ uint32_t mode_caps;
+ uint32_t pin_caps;
+ if (!modep)
+ return 0;
+
+ mode_caps = modep->data->mode_vdo[modep->opos - 1];
+
+ /* TODO(crosbug.com/p/39656) revisit with DFP that can be a sink */
+ pin_caps = PD_VDO_MODE_DP_SRCP(mode_caps);
+
+ /* if don't want multi-function then ignore those pin configs */
+ if (!PD_VDO_DPSTS_MF_PREF(status))
+ pin_caps &= ~MODE_DP_PIN_MF_MASK;
+
+ /* TODO(crosbug.com/p/39656) revisit if DFP drives USB Gen 2 signals */
+ pin_caps &= ~MODE_DP_PIN_BR2_MASK;
+
+ /* get_next_bit returns undefined for zero */
+ if (!pin_caps)
+ return 0;
+
+ return 1 << get_next_bit(&pin_caps);
+}
+
int pd_dfp_exit_mode(int port, uint16_t svid, int opos)
{
struct svdm_amode_data *modep;