[PATCH] usb: typec: tcpci: report connection status for non-DRP devices

Dmitry Baryshkov posted 1 patch 21 hours ago
drivers/usb/typec/tcpm/tcpci.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
[PATCH] usb: typec: tcpci: report connection status for non-DRP devices
Posted by Dmitry Baryshkov 21 hours ago
TCPM core calls start_toggling() unconditionally, but TCPCI simply
returns -EOPNOTSUPP in such a case, ignoring the current 'connected'
status. Make TCPCI driver check CC lines status and report current
connected status.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index a56e31b20c214fc509423d2f8602d3599c1dd2c1..9d57c73b49674858d799790c5c8cb0d929841def 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -178,6 +178,8 @@ static int tcpci_apply_rc(struct tcpc_dev *tcpc, enum typec_cc_status cc,
 				  TCPC_ROLE_CTRL_CC_OPEN);
 }
 
+static int tcpci_get_cc(struct tcpc_dev *tcpc,
+			enum typec_cc_status *cc1, enum typec_cc_status *cc2);
 static int tcpci_start_toggling(struct tcpc_dev *tcpc,
 				enum typec_port_type port_type,
 				enum typec_cc_status cc)
@@ -186,8 +188,17 @@ static int tcpci_start_toggling(struct tcpc_dev *tcpc,
 	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
 	unsigned int reg = TCPC_ROLE_CTRL_DRP;
 
-	if (port_type != TYPEC_PORT_DRP)
+	if (port_type != TYPEC_PORT_DRP) {
+		enum typec_cc_status cc1, cc2;
+
+		ret = tcpci_get_cc(tcpc, &cc1, &cc2);
+		if (ret)
+			return ret;
+
+		tcpm_cc_change(tcpci->port);
+
 		return -EOPNOTSUPP;
+	}
 
 	/* Handle vendor drp toggling */
 	if (tcpci->data->start_drp_toggling) {

---
base-commit: be5d4872e528796df9d7425f2bd9b3893eb3a42c
change-id: 20250908-tcpci-non-drp-connection-bacd9a5d24bc

Best regards,
-- 
With best wishes
Dmitry
Re: [PATCH] usb: typec: tcpci: report connection status for non-DRP devices
Posted by Xu Yang 15 hours ago
On Tue, Sep 09, 2025 at 02:36:51AM +0300, Dmitry Baryshkov wrote:
> TCPM core calls start_toggling() unconditionally, but TCPCI simply
> returns -EOPNOTSUPP in such a case, ignoring the current 'connected'
> status. Make TCPCI driver check CC lines status and report current
> connected status.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
>  drivers/usb/typec/tcpm/tcpci.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> index a56e31b20c214fc509423d2f8602d3599c1dd2c1..9d57c73b49674858d799790c5c8cb0d929841def 100644
> --- a/drivers/usb/typec/tcpm/tcpci.c
> +++ b/drivers/usb/typec/tcpm/tcpci.c
> @@ -178,6 +178,8 @@ static int tcpci_apply_rc(struct tcpc_dev *tcpc, enum typec_cc_status cc,
>  				  TCPC_ROLE_CTRL_CC_OPEN);
>  }
>  
> +static int tcpci_get_cc(struct tcpc_dev *tcpc,
> +			enum typec_cc_status *cc1, enum typec_cc_status *cc2);
>  static int tcpci_start_toggling(struct tcpc_dev *tcpc,
>  				enum typec_port_type port_type,
>  				enum typec_cc_status cc)
> @@ -186,8 +188,17 @@ static int tcpci_start_toggling(struct tcpc_dev *tcpc,
>  	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
>  	unsigned int reg = TCPC_ROLE_CTRL_DRP;
>  
> -	if (port_type != TYPEC_PORT_DRP)
> +	if (port_type != TYPEC_PORT_DRP) {
> +		enum typec_cc_status cc1, cc2;
> +
> +		ret = tcpci_get_cc(tcpc, &cc1, &cc2);
> +		if (ret)
> +			return ret;
> +
> +		tcpm_cc_change(tcpci->port);

I suppose normally a CC change event will result in calling
tcpm_start_toggling() and then tcpci_start_toggling(). In this case, the
connected status will be reported by the state machine. So are you calling
tcpm_cc_change() repeatedly?

With this change, the tcpm log print another one log as below, is this what
you want? It looks like TCPM has detected an interference.

# cat /sys/kernel/debug/usb/tcpm-2-0050/log
[   26.804246] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_READY, polarity 0, disconnected]
[   26.804270] state change SRC_READY -> SRC_UNATTACHED [rev3 NONE_AMS]
[   26.806636] Start toggling
[   26.817832] CC1: 0 -> 0, CC2: 0 -> 0 [state SRC_UNATTACHED, polarity 0, disconnected]  <---
[   26.818403] VBUS off
[   26.818407] VBUS VSAFE0V

Thanks,
Xu Yang

> +
>  		return -EOPNOTSUPP;
> +	}
>  
>  	/* Handle vendor drp toggling */
>  	if (tcpci->data->start_drp_toggling) {
> 
> ---
> base-commit: be5d4872e528796df9d7425f2bd9b3893eb3a42c
> change-id: 20250908-tcpci-non-drp-connection-bacd9a5d24bc
> 
> Best regards,
> -- 
> With best wishes
> Dmitry
>