Skip to content

Commit 5b30bd3

Browse files
Prashant MalaniEnric Balletbo i Serra
authored andcommitted
platform/chrome: cros_ec_typec: Add TBT compat support
Add mux control support for Thunderbolt compatibility mode. Suggested-by: Heikki Krogerus <[email protected]> Co-developed-by: Azhar Shaikh <[email protected]> Co-developed-by: Casey Bowman <[email protected]> Signed-off-by: Prashant Malani <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Signed-off-by: Enric Balletbo i Serra <[email protected]>
1 parent 5e48a03 commit 5b30bd3

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

drivers/platform/chrome/cros_ec_typec.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#include <linux/usb/typec_altmode.h>
1818
#include <linux/usb/typec_dp.h>
1919
#include <linux/usb/typec_mux.h>
20+
#include <linux/usb/typec_tbt.h>
2021
#include <linux/usb/role.h>
2122

2223
#define DRV_NAME "cros-ec-typec"
2324

2425
/* Supported alt modes. */
2526
enum {
2627
CROS_EC_ALTMODE_DP = 0,
28+
CROS_EC_ALTMODE_TBT,
2729
CROS_EC_ALTMODE_MAX,
2830
};
2931

@@ -165,6 +167,14 @@ static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
165167
port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
166168
port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
167169

170+
/*
171+
* Register TBT compatibility alt mode. The EC will not enter the mode
172+
* if it doesn't support it, so it's safe to register it unconditionally
173+
* here for now.
174+
*/
175+
port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
176+
port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
177+
168178
port->state.alt = NULL;
169179
port->state.mode = TYPEC_STATE_USB;
170180
port->state.data = NULL;
@@ -391,6 +401,62 @@ static int cros_typec_usb_safe_state(struct cros_typec_port *port)
391401
return typec_mux_set(port->mux, &port->state);
392402
}
393403

404+
/*
405+
* Spoof the VDOs that were likely communicated by the partner for TBT alt
406+
* mode.
407+
*/
408+
static int cros_typec_enable_tbt(struct cros_typec_data *typec,
409+
int port_num,
410+
struct ec_response_usb_pd_control_v2 *pd_ctrl)
411+
{
412+
struct cros_typec_port *port = typec->ports[port_num];
413+
struct typec_thunderbolt_data data;
414+
int ret;
415+
416+
if (typec->pd_ctrl_ver < 2) {
417+
dev_err(typec->dev,
418+
"PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
419+
return -ENOTSUPP;
420+
}
421+
422+
/* Device Discover Mode VDO */
423+
data.device_mode = TBT_MODE;
424+
425+
if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
426+
data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
427+
428+
/* Cable Discover Mode VDO */
429+
data.cable_mode = TBT_MODE;
430+
data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
431+
432+
if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
433+
data.cable_mode |= TBT_CABLE_OPTICAL;
434+
435+
if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
436+
data.cable_mode |= TBT_CABLE_LINK_TRAINING;
437+
438+
if (pd_ctrl->cable_gen)
439+
data.cable_mode |= TBT_CABLE_ROUNDED;
440+
441+
/* Enter Mode VDO */
442+
data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
443+
444+
if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
445+
data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
446+
447+
if (!port->state.alt) {
448+
port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
449+
ret = cros_typec_usb_safe_state(port);
450+
if (ret)
451+
return ret;
452+
}
453+
454+
port->state.data = &data;
455+
port->state.mode = TYPEC_TBT_MODE;
456+
457+
return typec_mux_set(port->mux, &port->state);
458+
}
459+
394460
/* Spoof the VDOs that were likely communicated by the partner. */
395461
static int cros_typec_enable_dp(struct cros_typec_data *typec,
396462
int port_num,
@@ -448,7 +514,9 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
448514
if (ret)
449515
return ret;
450516

451-
if (mux_flags & USB_PD_MUX_DP_ENABLED) {
517+
if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
518+
ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
519+
} else if (mux_flags & USB_PD_MUX_DP_ENABLED) {
452520
ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
453521
} else if (mux_flags & USB_PD_MUX_SAFE_MODE) {
454522
ret = cros_typec_usb_safe_state(port);

0 commit comments

Comments
 (0)