diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2018-05-24 13:49:52 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-24 18:17:00 +0200 |
commit | 05826ff135ee083d28c006fbde6e810f17437166 (patch) | |
tree | d23df820b6b1b08419d652f18c7211b395ec83df /drivers/usb | |
parent | cb296846860531defe93ebf75221e280970907f0 (diff) |
usb: typec: wcove: Remove dependency on HW FSM
The USB Type-C PHY in Intel WhiskeyCove PMIC has build-in
USB Type-C state machine which we were relying on to
configure the CC lines correctly. This patch removes that
dependency and configures the CC line according to commands
from the port manager (tcpm.c) in wcove_set_cc().
This fixes an issue where USB devices attached to the USB
Type-C port do not get enumerated. When acting as
source/host, the HW FSM sometimes fails to configure the PHY
correctly.
Fixes: 3c4fb9f16921 ("usb: typec: wcove: start using tcpm for USB PD support")
Cc: stable@vger.kernel.org
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/typec/typec_wcove.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c index 39cff11ec7a2..423208e19383 100644 --- a/drivers/usb/typec/typec_wcove.c +++ b/drivers/usb/typec/typec_wcove.c @@ -202,6 +202,10 @@ static int wcove_init(struct tcpc_dev *tcpc) struct wcove_typec *wcove = tcpc_to_wcove(tcpc); int ret; + ret = regmap_write(wcove->regmap, USBC_CONTROL1, 0); + if (ret) + return ret; + /* Unmask everything */ ret = regmap_write(wcove->regmap, USBC_IRQMASK1, 0); if (ret) @@ -285,8 +289,30 @@ static int wcove_get_cc(struct tcpc_dev *tcpc, enum typec_cc_status *cc1, static int wcove_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc) { - /* XXX: Relying on the HW FSM to configure things correctly for now */ - return 0; + struct wcove_typec *wcove = tcpc_to_wcove(tcpc); + unsigned int ctrl; + + switch (cc) { + case TYPEC_CC_RD: + ctrl = USBC_CONTROL1_MODE_SNK; + break; + case TYPEC_CC_RP_DEF: + ctrl = USBC_CONTROL1_CURSRC_UA_80 | USBC_CONTROL1_MODE_SRC; + break; + case TYPEC_CC_RP_1_5: + ctrl = USBC_CONTROL1_CURSRC_UA_180 | USBC_CONTROL1_MODE_SRC; + break; + case TYPEC_CC_RP_3_0: + ctrl = USBC_CONTROL1_CURSRC_UA_330 | USBC_CONTROL1_MODE_SRC; + break; + case TYPEC_CC_OPEN: + ctrl = 0; + break; + default: + return -EINVAL; + } + + return regmap_write(wcove->regmap, USBC_CONTROL1, ctrl); } static int wcove_set_polarity(struct tcpc_dev *tcpc, enum typec_cc_polarity pol) |