aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/typec/tcpci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/typec/tcpci.c')
-rw-r--r--drivers/staging/typec/tcpci.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c
index df72d8b01e73..39e2aee0b1a3 100644
--- a/drivers/staging/typec/tcpci.c
+++ b/drivers/staging/typec/tcpci.c
@@ -28,6 +28,15 @@
#define PD_RETRY_COUNT 3
+#define tcpc_presenting_cc1_rd(reg) \
+ (!(TCPC_ROLE_CTRL_DRP & (reg)) && \
+ (((reg) & (TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT)) == \
+ (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT)))
+#define tcpc_presenting_cc2_rd(reg) \
+ (!(TCPC_ROLE_CTRL_DRP & (reg)) && \
+ (((reg) & (TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT)) == \
+ (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT)))
+
struct tcpci {
struct device *dev;
struct i2c_client *client;
@@ -149,19 +158,25 @@ static int tcpci_get_cc(struct tcpc_dev *tcpc,
enum typec_cc_status *cc1, enum typec_cc_status *cc2)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
- unsigned int reg;
+ unsigned int reg, role_control;
int ret;
+ ret = regmap_read(tcpci->regmap, TCPC_ROLE_CTRL, &role_control);
+ if (ret < 0)
+ return ret;
+
ret = regmap_read(tcpci->regmap, TCPC_CC_STATUS, &reg);
if (ret < 0)
return ret;
*cc1 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC1_SHIFT) &
TCPC_CC_STATUS_CC1_MASK,
- reg & TCPC_CC_STATUS_TERM);
+ reg & TCPC_CC_STATUS_TERM ||
+ tcpc_presenting_cc1_rd(role_control));
*cc2 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC2_SHIFT) &
TCPC_CC_STATUS_CC2_MASK,
- reg & TCPC_CC_STATUS_TERM);
+ reg & TCPC_CC_STATUS_TERM ||
+ tcpc_presenting_cc2_rd(role_control));
return 0;
}