Skip to content

Commit

Permalink
usb: typec: fusb302: Resolve fixed power role contract setup
Browse files Browse the repository at this point in the history
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>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Adam Thomson authored and Greg Kroah-Hartman committed Sep 28, 2018
1 parent 40326e8 commit ea3b4d5
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/usb/typec/tcpm/fusb302.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit ea3b4d5

Please sign in to comment.