From f4a41c58e93d41c5b2bf703a2d68be8053f0369e Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 26 Jul 2017 23:50:29 +0800 Subject: [PATCH] MLK-16013-10 staging: typec: add vbus detection for power sink Typec port controller may need enable vbus detection to detect the vbus from power source. Reviewed-by: Peter Chen Signed-off-by: Li Jun --- drivers/staging/typec/tcpci.c | 21 +++++++++++++++++++++ drivers/staging/typec/tcpm.c | 11 +++++++++-- drivers/staging/typec/tcpm.h | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c index 5e5be74c7850..2b3b73b732f4 100644 --- a/drivers/staging/typec/tcpci.c +++ b/drivers/staging/typec/tcpci.c @@ -313,6 +313,26 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc, return 0; } +static int tcpci_vbus_detect(struct tcpc_dev *tcpc, bool enable) +{ + struct tcpci *tcpci = tcpc_to_tcpci(tcpc); + int ret; + + if (enable) { + ret = regmap_write(tcpci->regmap, TCPC_COMMAND, + TCPC_CMD_ENABLE_VBUS_DETECT); + if (ret < 0) + return ret; + } else { + ret = regmap_write(tcpci->regmap, TCPC_COMMAND, + TCPC_CMD_DISABLE_VBUS_DETECT); + if (ret < 0) + return ret; + } + + return 0; +} + static int tcpci_init(struct tcpc_dev *tcpc) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); @@ -465,6 +485,7 @@ static int tcpci_probe(struct i2c_client *client, tcpci->tcpc.set_polarity = tcpci_set_polarity; tcpci->tcpc.set_vconn = tcpci_set_vconn; tcpci->tcpc.start_drp_toggling = tcpci_start_drp_toggling; + tcpci->tcpc.vbus_detect = tcpci_vbus_detect; tcpci->tcpc.set_pd_rx = tcpci_set_pd_rx; tcpci->tcpc.set_roles = tcpci_set_roles; diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index d8f4574f292f..cf414de2b76f 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -2040,6 +2040,12 @@ static void tcpm_acc_detach(struct tcpm_port *port) tcpm_detach(port); } +static void tcpm_vbus_det(struct tcpm_port *port, bool enable) +{ + if (port->tcpc && port->tcpc->vbus_detect) + port->tcpc->vbus_detect(port->tcpc, true); +} + static inline enum tcpm_state hard_reset_state(struct tcpm_port *port) { if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) @@ -2265,10 +2271,11 @@ static void run_state_machine(struct tcpm_port *port) if ((port->cc1 == TYPEC_CC_OPEN && port->cc2 != TYPEC_CC_OPEN) || (port->cc1 != TYPEC_CC_OPEN && - port->cc2 == TYPEC_CC_OPEN)) + port->cc2 == TYPEC_CC_OPEN)) { tcpm_set_state(port, SNK_DEBOUNCED, PD_T_CC_DEBOUNCE); - else if (tcpm_port_is_disconnected(port)) + tcpm_vbus_det(port, true); + } else if (tcpm_port_is_disconnected(port)) tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE); break; diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h index 969b365e6549..e504399d8c2f 100644 --- a/drivers/staging/typec/tcpm.h +++ b/drivers/staging/typec/tcpm.h @@ -121,6 +121,7 @@ struct tcpc_dev { int (*try_role)(struct tcpc_dev *dev, int role); int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type, const struct pd_message *msg); + int (*vbus_detect)(struct tcpc_dev *dev, bool enable); struct tcpc_mux_dev *mux; }; -- 2.17.1