diff mbox series

[2/2] usb: typec: fusb302: Resolve fixed power role contract setup

Message ID 383410593681e2fed025a4b538ea0840ff370a9a.1537975081.git.Adam.Thomson.Opensource@diasemi.com (mailing list archive)
State New, archived
Headers show
Series usb: typec: fusb302: Resolve fixed role power configuration | expand

Commit Message

Adam Thomson Sept. 26, 2018, 3:23 p.m. UTC
When the controller is configured for a fixed power role (Source
only or Sink only), attach does not proceed within the TCPM state
machine as there is no CC event generated by this driver to update
the CC line status.

To rectify this, when CC is configured as Source or Sink we now
make use of the hardware's automatic fixed Source or Sink
toggling mechanism, which detects attaches in the same way as for
DRP toggling. In this way the result of toggling is handled in the
same way by the 'fusb302_handle_togdone()' function, and CC events
are generated as expected for TCPM allowing a contract to be
established.

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
 drivers/usb/typec/tcpm/fusb302.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Comments

Guenter Roeck Sept. 26, 2018, 4:30 p.m. UTC | #1
On Wed, Sep 26, 2018 at 04:23:52PM +0100, Adam Thomson wrote:
> When the controller is configured for a fixed power role (Source
> only or Sink only), attach does not proceed within the TCPM state
> machine as there is no CC event generated by this driver to update
> the CC line status.
> 
> To rectify this, when CC is configured as Source or Sink we now
> make use of the hardware's automatic fixed Source or Sink
> toggling mechanism, which detects attaches in the same way as for
> DRP toggling. In this way the result of toggling is handled in the
> same way by the 'fusb302_handle_togdone()' function, and CC events
> are generated as expected for TCPM allowing a contract to be
> established.
> 
> Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

> ---
>  drivers/usb/typec/tcpm/fusb302.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
> index fd851d8..43b64d9 100644
> --- a/drivers/usb/typec/tcpm/fusb302.c
> +++ b/drivers/usb/typec/tcpm/fusb302.c
> @@ -679,6 +679,7 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
>  	int ret = 0;
>  	bool pull_up, pull_down;
>  	u8 rd_mda;
> +	enum toggling_mode mode;
>  
>  	mutex_lock(&chip->lock);
>  	switch (cc) {
> @@ -764,6 +765,29 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
>  		chip->intr_comp_chng = false;
>  	}
>  	fusb302_log(chip, "cc := %s", typec_cc_status_name[cc]);
> +
> +	/* Enable detection for fixed SNK or SRC only roles */
> +	switch (cc) {
> +	case TYPEC_CC_RD:
> +		mode = TOGGLING_MODE_SNK;
> +		break;
> +	case TYPEC_CC_RP_DEF:
> +	case TYPEC_CC_RP_1_5:
> +	case TYPEC_CC_RP_3_0:
> +		mode = TOGGLING_MODE_SRC;
> +		break;
> +	default:
> +		mode = TOGGLING_MODE_OFF;
> +		break;
> +	}
> +
> +	if (mode != TOGGLING_MODE_OFF) {
> +		ret = fusb302_set_toggling(chip, mode);
> +		if (ret < 0)
> +			fusb302_log(chip,
> +				    "cannot set fixed role toggling mode, ret=%d",
> +				    ret);
> +	}
>  done:
>  	mutex_unlock(&chip->lock);
>  
> -- 
> 1.9.1
>
Heikki Krogerus Sept. 27, 2018, 10:54 a.m. UTC | #2
On Wed, Sep 26, 2018 at 04:23:52PM +0100, Adam Thomson wrote:
> When the controller is configured for a fixed power role (Source
> only or Sink only), attach does not proceed within the TCPM state
> machine as there is no CC event generated by this driver to update
> the CC line status.
> 
> To rectify this, when CC is configured as Source or Sink we now
> make use of the hardware's automatic fixed Source or Sink
> toggling mechanism, which detects attaches in the same way as for
> DRP toggling. In this way the result of toggling is handled in the
> same way by the 'fusb302_handle_togdone()' function, and CC events
> are generated as expected for TCPM allowing a contract to be
> established.
> 
> Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/usb/typec/tcpm/fusb302.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
> index fd851d8..43b64d9 100644
> --- a/drivers/usb/typec/tcpm/fusb302.c
> +++ b/drivers/usb/typec/tcpm/fusb302.c
> @@ -679,6 +679,7 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
>  	int ret = 0;
>  	bool pull_up, pull_down;
>  	u8 rd_mda;
> +	enum toggling_mode mode;
>  
>  	mutex_lock(&chip->lock);
>  	switch (cc) {
> @@ -764,6 +765,29 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
>  		chip->intr_comp_chng = false;
>  	}
>  	fusb302_log(chip, "cc := %s", typec_cc_status_name[cc]);
> +
> +	/* Enable detection for fixed SNK or SRC only roles */
> +	switch (cc) {
> +	case TYPEC_CC_RD:
> +		mode = TOGGLING_MODE_SNK;
> +		break;
> +	case TYPEC_CC_RP_DEF:
> +	case TYPEC_CC_RP_1_5:
> +	case TYPEC_CC_RP_3_0:
> +		mode = TOGGLING_MODE_SRC;
> +		break;
> +	default:
> +		mode = TOGGLING_MODE_OFF;
> +		break;
> +	}
> +
> +	if (mode != TOGGLING_MODE_OFF) {
> +		ret = fusb302_set_toggling(chip, mode);
> +		if (ret < 0)
> +			fusb302_log(chip,
> +				    "cannot set fixed role toggling mode, ret=%d",
> +				    ret);
> +	}
>  done:
>  	mutex_unlock(&chip->lock);
>  
> -- 
> 1.9.1
diff mbox series

Patch

diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index fd851d8..43b64d9 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -679,6 +679,7 @@  static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
 	int ret = 0;
 	bool pull_up, pull_down;
 	u8 rd_mda;
+	enum toggling_mode mode;
 
 	mutex_lock(&chip->lock);
 	switch (cc) {
@@ -764,6 +765,29 @@  static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
 		chip->intr_comp_chng = false;
 	}
 	fusb302_log(chip, "cc := %s", typec_cc_status_name[cc]);
+
+	/* Enable detection for fixed SNK or SRC only roles */
+	switch (cc) {
+	case TYPEC_CC_RD:
+		mode = TOGGLING_MODE_SNK;
+		break;
+	case TYPEC_CC_RP_DEF:
+	case TYPEC_CC_RP_1_5:
+	case TYPEC_CC_RP_3_0:
+		mode = TOGGLING_MODE_SRC;
+		break;
+	default:
+		mode = TOGGLING_MODE_OFF;
+		break;
+	}
+
+	if (mode != TOGGLING_MODE_OFF) {
+		ret = fusb302_set_toggling(chip, mode);
+		if (ret < 0)
+			fusb302_log(chip,
+				    "cannot set fixed role toggling mode, ret=%d",
+				    ret);
+	}
 done:
 	mutex_unlock(&chip->lock);