@@ -15,7 +15,7 @@
#include <linux/usb/typec_dp.h>
#include "displayport.h"
-#define DP_HEADER(_dp, cmd) (VDO((_dp)->alt->svid, 1, cmd) | \
+#define DP_HEADER(_dp, cmd) (VDO((_dp)->alt->svid, 1, SVDM_VER_1_0, cmd) | \
VDO_OPOS(USB_TYPEC_DP_MODE))
enum {
@@ -1544,17 +1544,17 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
case CMD_DISCOVER_IDENT:
/* 6.4.4.3.1 */
svdm_consume_identity(port, p, cnt);
- response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID);
+ response[0] = VDO(USB_SID_PD, 1, SVDM_VER_1_0, CMD_DISCOVER_SVID);
rlen = 1;
break;
case CMD_DISCOVER_SVID:
/* 6.4.4.3.2 */
if (svdm_consume_svids(port, p, cnt)) {
- response[0] = VDO(USB_SID_PD, 1,
+ response[0] = VDO(USB_SID_PD, 1, SVDM_VER_1_0,
CMD_DISCOVER_SVID);
rlen = 1;
} else if (modep->nsvids && supports_modal(port)) {
- response[0] = VDO(modep->svids[0], 1,
+ response[0] = VDO(modep->svids[0], 1, SVDM_VER_1_0,
CMD_DISCOVER_MODES);
rlen = 1;
}
@@ -1565,7 +1565,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
modep->svid_index++;
if (modep->svid_index < modep->nsvids) {
u16 svid = modep->svids[modep->svid_index];
- response[0] = VDO(svid, 1, CMD_DISCOVER_MODES);
+ response[0] = VDO(svid, 1, SVDM_VER_1_0, CMD_DISCOVER_MODES);
rlen = 1;
} else {
tcpm_register_partner_altmodes(port);
@@ -1695,7 +1695,7 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
break;
case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL:
if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
- response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE);
+ response[0] = VDO(adev->svid, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
response[0] |= VDO_OPOS(adev->mode);
rlen = 1;
}
@@ -1729,7 +1729,7 @@ static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd,
/* set VDM header with VID & CMD */
header = VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ?
- 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), cmd);
+ 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), SVDM_VER_1_0, cmd);
tcpm_queue_vdm(port, header, data, count);
}
@@ -2024,7 +2024,7 @@ static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo)
struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
u32 header;
- header = VDO(altmode->svid, vdo ? 2 : 1, CMD_ENTER_MODE);
+ header = VDO(altmode->svid, vdo ? 2 : 1, SVDM_VER_1_0, CMD_ENTER_MODE);
header |= VDO_OPOS(altmode->mode);
tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0);
@@ -2036,7 +2036,7 @@ static int tcpm_altmode_exit(struct typec_altmode *altmode)
struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
u32 header;
- header = VDO(altmode->svid, 1, CMD_EXIT_MODE);
+ header = VDO(altmode->svid, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
header |= VDO_OPOS(altmode->mode);
tcpm_queue_vdm_unlocked(port, header, NULL, 0);
@@ -83,7 +83,7 @@ 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, CMD_ENTER_MODE);
+ dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_ENTER_MODE);
dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
dp->header |= VDO_CMDT(CMDT_RSP_ACK);
@@ -120,7 +120,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
if (ret < 0)
goto out_unlock;
- dp->header = VDO(USB_TYPEC_DP_SID, 1, CMD_EXIT_MODE);
+ dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
dp->header |= VDO_CMDT(CMDT_RSP_ACK);
@@ -200,7 +200,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
switch (cmd_type) {
case CMDT_INIT:
- dp->header = VDO(USB_TYPEC_DP_SID, 1, cmd);
+ dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, cmd);
dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
switch (cmd) {
@@ -21,22 +21,24 @@
* ----------
* <31:16> :: SVID
* <15> :: VDM type ( 1b == structured, 0b == unstructured )
- * <14:13> :: Structured VDM version (can only be 00 == 1.0 currently)
+ * <14:13> :: Structured VDM version
* <12:11> :: reserved
* <10:8> :: object position (1-7 valid ... used for enter/exit mode only)
* <7:6> :: command type (SVDM only?)
* <5> :: reserved (SVDM), command type (UVDM)
* <4:0> :: command
*/
-#define VDO(vid, type, custom) \
+#define VDO(vid, type, ver, custom) \
(((vid) << 16) | \
((type) << 15) | \
+ ((ver) << 13) | \
((custom) & 0x7FFF))
#define VDO_SVDM_TYPE (1 << 15)
#define VDO_SVDM_VERS(x) ((x) << 13)
#define VDO_OPOS(x) ((x) << 8)
#define VDO_CMDT(x) ((x) << 6)
+#define VDO_SVDM_VERS_MASK VDO_SVDM_VERS(0x3)
#define VDO_OPOS_MASK VDO_OPOS(0x7)
#define VDO_CMDT_MASK VDO_CMDT(0x3)
@@ -74,6 +76,7 @@
#define PD_VDO_VID(vdo) ((vdo) >> 16)
#define PD_VDO_SVDM(vdo) (((vdo) >> 15) & 1)
+#define PD_VDO_SVDM_VER(vdo) (((vdo) >> 13) & 0x3)
#define PD_VDO_OPOS(vdo) (((vdo) >> 8) & 0x7)
#define PD_VDO_CMD(vdo) ((vdo) & 0x1f)
#define PD_VDO_CMDT(vdo) (((vdo) >> 6) & 0x3)
PD Rev 3.0 introduces SVDM Version 2.0. This patch makes the field configuable in the header in order to be able to be compatible with older SVDM version. Signed-off-by: Kyle Tso <kyletso@google.com> --- drivers/usb/typec/altmodes/displayport.c | 2 +- drivers/usb/typec/tcpm/tcpm.c | 16 ++++++++-------- drivers/usb/typec/ucsi/displayport.c | 6 +++--- include/linux/usb/pd_vdo.h | 7 +++++-- 4 files changed, 17 insertions(+), 14 deletions(-)