From 86ab7efb58025601b7799eedee29ba9d9d5f10a6 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Mon, 16 Apr 2018 12:46:33 -0600 Subject: tcpci: reset TCPC if alert mask is reset The PS8751 TCPC expresses that it has been reset by resetting the alert mask. Handle its re-init case. BRANCH=none BUG=b:77551454,b:77639399 TEST=Verify that TCPC is reset on yorp C1 after reinsertion Change-Id: Ie1a819a3627a1225c3fad65a60a4aca126a69f53 Signed-off-by: Jett Rink Reviewed-on: https://chromium-review.googlesource.com/1014355 Reviewed-by: Aseda Aboagye --- driver/tcpm/tcpci.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'driver') diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 3c1234810f..76d01adeae 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -288,12 +288,37 @@ int tcpci_tcpm_transmit(int port, enum tcpm_transmit_type type, return rv; } +/* Returns true if TCPC has reset based on reading mask registers. */ +static int register_mask_reset(int port) +{ + int mask; + + mask = 0; + tcpc_read16(port, TCPC_REG_ALERT_MASK, &mask); + if (mask == TCPC_REG_ALERT_MASK_ALL) + return 1; + + mask = 0; + tcpc_read(port, TCPC_REG_POWER_STATUS_MASK, &mask); + if (mask == TCPC_REG_POWER_STATUS_MASK_ALL) + return 1; + + return 0; +} + void tcpci_tcpc_alert(int port) { int status; /* Read the Alert register from the TCPC */ tcpm_alert_status(port, &status); + /* + * Check registers to see if we can tell that the TCPC has reset. If + * so, perform tcpc_init inline. + */ + if (register_mask_reset(port)) + task_set_event(PD_PORT_TO_TASK_ID(port), + PD_EVENT_TCPC_RESET, 0); /* * Clear alert status for everything except RX_STATUS, which shouldn't @@ -309,28 +334,16 @@ void tcpci_tcpc_alert(int port) } if (status & TCPC_REG_ALERT_POWER_STATUS) { int reg = 0; - - tcpc_read(port, TCPC_REG_POWER_STATUS_MASK, ®); - - if (reg == TCPC_REG_POWER_STATUS_MASK_ALL) { - /* - * If power status mask has been reset, then the TCPC - * has reset. - */ - task_set_event(PD_PORT_TO_TASK_ID(port), - PD_EVENT_TCPC_RESET, 0); - } else { - /* Read Power Status register */ - tcpci_tcpm_get_power_status(port, ®); - /* Update VBUS status */ - tcpc_vbus[port] = reg & - TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; + /* Read Power Status register */ + tcpci_tcpm_get_power_status(port, ®); + /* Update VBUS status */ + tcpc_vbus[port] = reg & + TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; #if defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) && defined(CONFIG_USB_CHARGER) - /* Update charge manager with new VBUS state */ - usb_charger_vbus_change(port, tcpc_vbus[port]); - task_wake(PD_PORT_TO_TASK_ID(port)); + /* Update charge manager with new VBUS state */ + usb_charger_vbus_change(port, tcpc_vbus[port]); + task_wake(PD_PORT_TO_TASK_ID(port)); #endif /* CONFIG_USB_PD_VBUS_DETECT_TCPC && CONFIG_USB_CHARGER */ - } } if (status & TCPC_REG_ALERT_RX_STATUS) { /* message received */ -- cgit v1.2.1