From: Li Jun <jun.li@xxxxxxx> Since the typec port data role is separated from power role, so check the port data capability when setting data role. Signed-off-by: Li Jun <jun.li@xxxxxxx> --- drivers/usb/typec/tcpm/tcpm.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 56fc356..1f0d82e 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -780,7 +780,7 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached, enum typec_role role, enum typec_data_role data) { enum typec_orientation orientation; - enum usb_role usb_role; + enum usb_role usb_role = USB_ROLE_NONE; int ret; if (port->polarity == TYPEC_POLARITY_CC1) @@ -788,10 +788,20 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached, else orientation = TYPEC_ORIENTATION_REVERSE; - if (data == TYPEC_HOST) - usb_role = USB_ROLE_HOST; - else - usb_role = USB_ROLE_DEVICE; + if (port->typec_caps.data == TYPEC_PORT_DRD) { + if (data == TYPEC_HOST) + usb_role = USB_ROLE_HOST; + else + usb_role = USB_ROLE_DEVICE; + } else if (port->typec_caps.data == TYPEC_PORT_DFP) { + if (data == TYPEC_HOST) + usb_role = USB_ROLE_HOST; + data = TYPEC_HOST; + } else { + if (data == TYPEC_DEVICE) + usb_role = USB_ROLE_DEVICE; + data = TYPEC_DEVICE; + } ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation); if (ret < 0) @@ -1817,7 +1827,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_set_state(port, SOFT_RESET, 0); break; case PD_CTRL_DR_SWAP: - if (port->port_type != TYPEC_PORT_DRP) { + if (port->typec_caps.data != TYPEC_PORT_DRD) { tcpm_queue_message(port, PD_MSG_CTRL_REJECT); break; } @@ -3969,7 +3979,7 @@ static int tcpm_dr_set(struct typec_port *p, enum typec_data_role data) mutex_lock(&port->swap_lock); mutex_lock(&port->lock); - if (port->port_type != TYPEC_PORT_DRP) { + if (port->typec_caps.data != TYPEC_PORT_DRD) { ret = -EINVAL; goto port_unlock; } -- 2.7.4