Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: typec: ucsi: Determine common SVDM Version

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>

authored by

Kyle Tso and committed by
Greg Kroah-Hartman
372adf07 5e1d4c49

+30 -3
+29 -3
drivers/usb/typec/ucsi/displayport.c
··· 49 49 { 50 50 struct ucsi_dp *dp = typec_altmode_get_drvdata(alt); 51 51 struct ucsi *ucsi = dp->con->ucsi; 52 + int svdm_version; 52 53 u64 command; 53 54 u8 cur = 0; 54 55 int ret; ··· 84 83 * mode, and letting the alt mode driver continue. 85 84 */ 86 85 87 - dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_ENTER_MODE); 86 + svdm_version = typec_altmode_get_svdm_version(alt); 87 + if (svdm_version < 0) { 88 + ret = svdm_version; 89 + goto err_unlock; 90 + } 91 + 92 + dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, CMD_ENTER_MODE); 88 93 dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE); 89 94 dp->header |= VDO_CMDT(CMDT_RSP_ACK); 90 95 ··· 108 101 static int ucsi_displayport_exit(struct typec_altmode *alt) 109 102 { 110 103 struct ucsi_dp *dp = typec_altmode_get_drvdata(alt); 104 + int svdm_version; 111 105 u64 command; 112 106 int ret = 0; 113 107 ··· 128 120 if (ret < 0) 129 121 goto out_unlock; 130 122 131 - dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_EXIT_MODE); 123 + svdm_version = typec_altmode_get_svdm_version(alt); 124 + if (svdm_version < 0) { 125 + ret = svdm_version; 126 + goto out_unlock; 127 + } 128 + 129 + dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, CMD_EXIT_MODE); 132 130 dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE); 133 131 dp->header |= VDO_CMDT(CMDT_RSP_ACK); 134 132 ··· 200 186 struct ucsi_dp *dp = typec_altmode_get_drvdata(alt); 201 187 int cmd_type = PD_VDO_CMDT(header); 202 188 int cmd = PD_VDO_CMD(header); 189 + int svdm_version; 203 190 204 191 mutex_lock(&dp->con->lock); 205 192 ··· 213 198 return -EOPNOTSUPP; 214 199 } 215 200 201 + svdm_version = typec_altmode_get_svdm_version(alt); 202 + if (svdm_version < 0) { 203 + mutex_unlock(&dp->con->lock); 204 + return svdm_version; 205 + } 206 + 216 207 switch (cmd_type) { 217 208 case CMDT_INIT: 218 - dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, cmd); 209 + if (PD_VDO_SVDM_VER(header) < svdm_version) { 210 + typec_partner_set_svdm_version(dp->con->partner, PD_VDO_SVDM_VER(header)); 211 + svdm_version = PD_VDO_SVDM_VER(header); 212 + } 213 + 214 + dp->header = VDO(USB_TYPEC_DP_SID, 1, svdm_version, cmd); 219 215 dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE); 220 216 221 217 switch (cmd) {
+1
drivers/usb/typec/ucsi/ucsi.c
··· 1052 1052 1053 1053 cap->revision = ucsi->cap.typec_version; 1054 1054 cap->pd_revision = ucsi->cap.pd_version; 1055 + cap->svdm_version = SVDM_VER_2_0; 1055 1056 cap->prefer_role = TYPEC_NO_PREFERRED_ROLE; 1056 1057 1057 1058 if (con->cap.op_mode & UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY)