]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
usb: typec: ucsi: Determine common SVDM Version
authorKyle Tso <kyletso@google.com>
Fri, 5 Feb 2021 03:34:12 +0000 (11:34 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Feb 2021 10:48:55 +0000 (11:48 +0100)
This patch implements the following requirement in the Spec.

PD Spec Revision 3.0 Version 2.0 + ECNs 2020-12-10
  6.4.4.2.3 Structured VDM Version
  "The Structured VDM Version field of the Discover Identity Command
  sent and received during VDM discovery Shall be used to determine the
  lowest common Structured VDM Version supported by the Port Partners or
  Cable Plug and Shall continue to operate using this Specification
  Revision until they are Detached."

Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Kyle Tso <kyletso@google.com>
Link: https://lore.kernel.org/r/20210205033415.3320439-5-kyletso@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/displayport.c
drivers/usb/typec/ucsi/ucsi.c

index 1d387bddefb9f4ae1ed8c0db4b22c132bdea6268..73cd5bf350472fcb88756a4faa94c0757edab1fe 100644 (file)
@@ -49,6 +49,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
 {
        struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
        struct ucsi *ucsi = dp->con->ucsi;
+       int svdm_version;
        u64 command;
        u8 cur = 0;
        int ret;
@@ -83,7 +84,13 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
         * mode, and letting the alt mode driver continue.
         */
 
-       dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_ENTER_MODE);
+       svdm_version = typec_altmode_get_svdm_version(alt);
+       if (svdm_version < 0) {
+               ret = svdm_version;
+               goto err_unlock;
+       }
+
+       dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, CMD_ENTER_MODE);
        dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
        dp->header |= VDO_CMDT(CMDT_RSP_ACK);
 
@@ -101,6 +108,7 @@ err_unlock:
 static int ucsi_displayport_exit(struct typec_altmode *alt)
 {
        struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
+       int svdm_version;
        u64 command;
        int ret = 0;
 
@@ -120,7 +128,13 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
        if (ret < 0)
                goto out_unlock;
 
-       dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
+       svdm_version = typec_altmode_get_svdm_version(alt);
+       if (svdm_version < 0) {
+               ret = svdm_version;
+               goto out_unlock;
+       }
+
+       dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, CMD_EXIT_MODE);
        dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
        dp->header |= VDO_CMDT(CMDT_RSP_ACK);
 
@@ -186,6 +200,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
        struct ucsi_dp *dp = typec_altmode_get_drvdata(alt);
        int cmd_type = PD_VDO_CMDT(header);
        int cmd = PD_VDO_CMD(header);
+       int svdm_version;
 
        mutex_lock(&dp->con->lock);
 
@@ -198,9 +213,20 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
                return -EOPNOTSUPP;
        }
 
+       svdm_version = typec_altmode_get_svdm_version(alt);
+       if (svdm_version < 0) {
+               mutex_unlock(&dp->con->lock);
+               return svdm_version;
+       }
+
        switch (cmd_type) {
        case CMDT_INIT:
-               dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, cmd);
+               if (PD_VDO_SVDM_VER(header) < svdm_version) {
+                       typec_partner_set_svdm_version(dp->con->partner, PD_VDO_SVDM_VER(header));
+                       svdm_version = PD_VDO_SVDM_VER(header);
+               }
+
+               dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, cmd);
                dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
 
                switch (cmd) {
index ca3f4194ad903265daf436c9f7827e329cc0c50f..244270755ae61f999d952f281eb8aee8c5fb67cf 100644 (file)
@@ -1052,6 +1052,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
 
        cap->revision = ucsi->cap.typec_version;
        cap->pd_revision = ucsi->cap.pd_version;
+       cap->svdm_version = SVDM_VER_2_0;
        cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
 
        if (con->cap.op_mode & UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY)