diff --git a/drivers/usb/typec/mmi_tcpc/inc/tcpci.h b/drivers/usb/typec/mmi_tcpc/inc/tcpci.h index 26e07aeccd12..1e1c4466d174 100644 --- a/drivers/usb/typec/mmi_tcpc/inc/tcpci.h +++ b/drivers/usb/typec/mmi_tcpc/inc/tcpci.h @@ -87,6 +87,7 @@ int tcpci_init_alert_mask(struct tcpc_device *tcpc); int tcpci_get_cc(struct tcpc_device *tcpc); int tcpci_set_cc(struct tcpc_device *tcpc, int pull); int tcpci_set_polarity(struct tcpc_device *tcpc, int polarity); +int tcpci_set_port_type(struct tcpc_device *tcpc, int mode); int tcpci_set_low_rp_duty(struct tcpc_device *tcpc, bool low_rp); int tcpci_set_vconn(struct tcpc_device *tcpc, int enable); diff --git a/drivers/usb/typec/mmi_tcpc/inc/tcpci_core.h b/drivers/usb/typec/mmi_tcpc/inc/tcpci_core.h index e7c0f2d93097..2dc4cd9253e1 100644 --- a/drivers/usb/typec/mmi_tcpc/inc/tcpci_core.h +++ b/drivers/usb/typec/mmi_tcpc/inc/tcpci_core.h @@ -214,7 +214,7 @@ struct tcpc_ops { int (*set_vconn)(struct tcpc_device *tcpc, int enable); int (*deinit)(struct tcpc_device *tcpc); int (*alert_vendor_defined_handler)(struct tcpc_device *tcpc); - + int (*set_port_type)(struct tcpc_device *tcpc, int mode); #ifdef CONFIG_TCPC_VSAFE0V_DETECT_IC int (*is_vsafe0v)(struct tcpc_device *tcpc); #endif /* CONFIG_TCPC_VSAFE0V_DETECT_IC */ diff --git a/drivers/usb/typec/mmi_tcpc/inc/tcpm.h b/drivers/usb/typec/mmi_tcpc/inc/tcpm.h index 8e78d23b1812..f7b0094c8da8 100644 --- a/drivers/usb/typec/mmi_tcpc/inc/tcpm.h +++ b/drivers/usb/typec/mmi_tcpc/inc/tcpm.h @@ -874,6 +874,9 @@ extern int tcpm_typec_role_swap( extern int tcpm_typec_change_role( struct tcpc_device *tcpc, uint8_t typec_role); +extern int tcpm_typec_change_mode( + struct tcpc_device *tcpc, uint8_t mode); + extern int tcpm_typec_change_role_postpone( struct tcpc_device *tcpc, uint8_t typec_role, bool postpone); @@ -1369,6 +1372,12 @@ static inline int tcpm_typec_change_role( return TCPM_ERROR_NO_IMPLEMENT; } +static inline int tcpm_typec_change_mode( + struct tcpc_device *tcpc, uint8_t mode) +{ + return TCPM_ERROR_NO_IMPLEMENT; +} + static inline int tcpm_typec_change_role_postpone( struct tcpc_device *tcpc, uint8_t typec_role, bool postpone) { diff --git a/drivers/usb/typec/mmi_tcpc/rt_pd_manager.c b/drivers/usb/typec/mmi_tcpc/rt_pd_manager.c index c9e04e9bd831..92ee9198a32e 100644 --- a/drivers/usb/typec/mmi_tcpc/rt_pd_manager.c +++ b/drivers/usb/typec/mmi_tcpc/rt_pd_manager.c @@ -770,6 +770,12 @@ static int tcpc_typec_port_type_set(const struct typec_capability *cap, dev_info(rpmd->dev, "%s type = %d, as_sink = %d\n", __func__, type, as_sink); + if (0 == tcpm_typec_change_mode(rpmd->tcpc, type)) { + dev_info(rpmd->dev, "%s Only type C mode and not support PD\n", + __func__); + return 0; + } + switch (type) { case TYPEC_PORT_SNK: if (as_sink) diff --git a/drivers/usb/typec/mmi_tcpc/tcpci.c b/drivers/usb/typec/mmi_tcpc/tcpci.c index e3ba53409493..3b6bab9e8cb9 100644 --- a/drivers/usb/typec/mmi_tcpc/tcpci.c +++ b/drivers/usb/typec/mmi_tcpc/tcpci.c @@ -268,6 +268,16 @@ int tcpci_set_polarity(struct tcpc_device *tcpc, int polarity) return tcpc->ops->set_polarity(tcpc, polarity); } +int tcpci_set_port_type(struct tcpc_device *tcpc, int mode) +{ + if (tcpc->ops->set_port_type == NULL) + return -ENOTSUPP; + else + tcpc->ops->set_port_type(tcpc, mode); + + return 0; +} + int tcpci_set_low_rp_duty(struct tcpc_device *tcpc, bool low_rp) { #ifdef CONFIG_TYPEC_CAP_LOW_RP_DUTY diff --git a/drivers/usb/typec/mmi_tcpc/tcpm.c b/drivers/usb/typec/mmi_tcpc/tcpm.c index 1275e805b797..5e9cf0e4e6c5 100644 --- a/drivers/usb/typec/mmi_tcpc/tcpm.c +++ b/drivers/usb/typec/mmi_tcpc/tcpm.c @@ -288,6 +288,19 @@ int tcpm_typec_role_swap(struct tcpc_device *tcpc) } EXPORT_SYMBOL(tcpm_typec_role_swap); +int tcpm_typec_change_mode( + struct tcpc_device *tcpc, uint8_t mode) +{ + int ret = 0; + + tcpci_lock_typec(tcpc); + ret = tcpci_set_port_type(tcpc, mode); + tcpci_unlock_typec(tcpc); + + return ret; +} +EXPORT_SYMBOL(tcpm_typec_change_mode); + int tcpm_typec_change_role( struct tcpc_device *tcpc, uint8_t typec_role) {