Put some diagnostics in the tcpm log when there's an over or under voltage situation. Signed-off-by: Angus Ainslie (Purism) <angus@xxxxxxxx> --- drivers/usb/typec/tcpm/tcpci.c | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index c1f7073a56de..c6e0e48b9a2a 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -261,6 +261,39 @@ static int tcpci_set_pd_rx(struct tcpc_dev *tcpc, bool enable) return 0; } +static int tcpci_get_vbus_voltage(struct tcpc_dev *tcpc) +{ + struct tcpci *tcpci = tcpc_to_tcpci(tcpc); + u16 vbus_reg; + unsigned int vbus_voltage; + int ret, scale; + + ret = tcpci_read16(tcpci, TCPC_VBUS_VOLTAGE, &vbus_reg); + if (ret < 0) + return ret; + + vbus_voltage = vbus_reg & 0x3f; + switch ((ret >> 10) & 3) { + case 0: + scale = 1; + break; + case 1: + scale = 2; + break; + case 2: + scale = 4; + break; + case 3: + tcpm_log(tcpci->port, "invalid VBUS scale"); + return -1; + } + + if (scale != 1) + vbus_voltage *= scale; + + return vbus_voltage; +} + static int tcpci_get_vbus(struct tcpc_dev *tcpc) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); @@ -463,6 +496,17 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) else if (status & TCPC_ALERT_TX_FAILED) tcpm_pd_transmit_complete(tcpci->port, TCPC_TX_FAILED); + if (status & (TCPC_ALERT_V_ALARM_LO | TCPC_ALERT_V_ALARM_HI)) { + int ret; + + ret = tcpci_get_vbus_voltage(&tcpci->tcpc); + + if (IS_ERR(ret)) + tcpm_log(tcpci->port, "Can't read VBUS voltage"); + else + tcpm_log(tcpci->port, "Invalid VBUS voltage %d", ret); + } + return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(tcpci_irq); -- 2.17.1