summaryrefslogtreecommitdiff
path: root/driver/ppc
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2018-01-25 16:13:22 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-01-31 22:38:56 -0800
commit11bda19561bd4d5dcbc6419e08ee94c05e9ae862 (patch)
treedbde4b8307382e30986031f809b8684aeb5ba757 /driver/ppc
parenteb60e291e8c7c178e0814c5d2a5cbe6c207182d2 (diff)
downloadchrome-ec-11bda19561bd4d5dcbc6419e08ee94c05e9ae862.tar.gz
sn5s330: Enable VBUS interrupts
If the sn5s330 PPC is being used to detect VBUS presence (CONFIG_USB_PD_VBUS_DETECT_PPC), then enable interrupts and call usb_charger_vbus_change when VBUS_GOOD changes. BUG=b:72007153,b:72007492 BRANCH=none TEST=Connect 3A and 1A USB-A chargers to each of Grunt's USB-C ports, check that BC1.2 detection is working: With 1A: > chgsup port=0/1, type=7, cur=500mA, vtg=5000mV, lsm=1 With 3A: > chgsup port=0/1, type=7, cur=2400mA, vtg=5000mV, lsm=1 TEST=Boot Grunt to OS, then connect USB2 mouse or USB3 flash drive to each of Grunt's USB-C ports. Devices do not work due to b:71772180, but gpioget shows EC is setting USB_C0/1_BC12_VBUS_ON_L correctly. Change-Id: Iffc352105a321997adb364b9fbb8bafef248c224 Signed-off-by: Edward Hill <ecgh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/887938 Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'driver/ppc')
-rw-r--r--driver/ppc/sn5s330.c43
-rw-r--r--driver/ppc/sn5s330.h12
2 files changed, 45 insertions, 10 deletions
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
index d21dba0f66..2d5d457abf 100644
--- a/driver/ppc/sn5s330.c
+++ b/driver/ppc/sn5s330.c
@@ -17,6 +17,7 @@
#include "i2c.h"
#include "system.h"
#include "timer.h"
+#include "usb_charge.h"
#include "usb_pd_tcpm.h"
#include "usbc_ppc.h"
#include "util.h"
@@ -326,7 +327,8 @@ static int sn5s330_init(int port)
/*
* Before turning on the PP2 FET, let's mask off all interrupts except
* for the PP1 overcurrent condition and then clear all pending
- * interrupts.
+ * interrupts. If PPC is being used to detect VBUS, then also enable
+ * interrupts for VBUS presence.
*
* TODO(aaboagye): Unmask fast-role swap events once fast-role swap is
* implemented in the PD stack.
@@ -362,15 +364,22 @@ static int sn5s330_init(int port)
return status;
}
+#if defined(CONFIG_USB_PD_VBUS_DETECT_PPC) && defined(CONFIG_USB_CHARGER)
+ /* If PPC is being used to detect VBUS, enable VBUS interrupts. */
+ regval = ~SN5S330_VBUS_GOOD_MASK;
+#else
+ regval = 0xFF;
+#endif /* CONFIG_USB_PD_VBUS_DETECT_PPC && CONFIG_USB_CHARGER */
+
status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_RISE_REG3,
- 0xFF);
+ regval);
if (status) {
CPRINTS("Failed to write INT_MASK_RISE3!");
return status;
}
status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_FALL_REG3,
- 0xFF);
+ regval);
if (status) {
CPRINTS("Failed to write INT_MASK_FALL3!");
return status;
@@ -416,16 +425,18 @@ static int sn5s330_init(int port)
}
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-static int sn5s330_is_vbus_present(int port, int *vbus_present)
+static int sn5s330_is_vbus_present(int port)
{
int regval;
int rv;
rv = read_reg(port, SN5S330_INT_STATUS_REG3, &regval);
- if (!rv)
- *vbus_present = !!(regval & SN5S330_VBUS_GOOD);
+ if (rv) {
+ CPRINTS("p%d: VBUS present error (%d)", port, rv);
+ return 0;
+ }
- return rv;
+ return !!(regval & SN5S330_VBUS_GOOD);
}
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
@@ -436,7 +447,7 @@ static int sn5s330_is_sourcing_vbus(int port)
rv = sn5s330_is_pp_fet_enabled(port, SN5S330_PP1, &is_sourcing_vbus);
if (rv) {
- CPRINTS("C%d: Failed to determine source FET status! (%d)",
+ CPRINTS("p%d: Failed to determine source FET status! (%d)",
port, rv);
return 0;
}
@@ -520,7 +531,7 @@ static void sn5s330_handle_interrupt(int port)
/*
* The only interrupts that should be enabled are the PP1 overcurrent
- * condition.
+ * condition, and for VBUS_GOOD if PPC is being used to detect VBUS.
*/
read_reg(port, SN5S330_INT_TRIP_RISE_REG1, &rise);
read_reg(port, SN5S330_INT_TRIP_FALL_REG1, &fall);
@@ -532,6 +543,20 @@ static void sn5s330_handle_interrupt(int port)
/* Clear the interrupt sources. */
write_reg(port, SN5S330_INT_TRIP_RISE_REG1, rise);
write_reg(port, SN5S330_INT_TRIP_FALL_REG1, fall);
+
+#if defined(CONFIG_USB_PD_VBUS_DETECT_PPC) && defined(CONFIG_USB_CHARGER)
+ read_reg(port, SN5S330_INT_TRIP_RISE_REG3, &rise);
+ read_reg(port, SN5S330_INT_TRIP_FALL_REG3, &fall);
+
+ /* Inform other modules about VBUS level */
+ if (rise & SN5S330_VBUS_GOOD_MASK
+ || fall & SN5S330_VBUS_GOOD_MASK)
+ usb_charger_vbus_change(port, sn5s330_is_vbus_present(port));
+
+ /* Clear the interrupt sources. */
+ write_reg(port, SN5S330_INT_TRIP_RISE_REG3, rise);
+ write_reg(port, SN5S330_INT_TRIP_FALL_REG3, fall);
+#endif /* CONFIG_USB_PD_VBUS_DETECT_PPC && CONFIG_USB_CHARGER */
}
static void sn5s330_irq_deferred(void)
diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h
index 18f1929c0f..e8850faf57 100644
--- a/driver/ppc/sn5s330.h
+++ b/driver/ppc/sn5s330.h
@@ -120,13 +120,23 @@ enum sn5s330_pp_idx {
*/
#define SN5S330_ILIM_PP1_MASK (1 << 4)
+/*
+ * INT_MASK_RISE/FALL_EDGE_3
+ *
+ * The VBUS_GOOD bit indicates VBUS has increased beyond a 4.0V threshold.
+ * For rising edge registers, this indicates VBUS has risen above 4.0V.
+ * For falling edge registers, this indicates VBUS has fallen below 4.0V.
+ */
+#define SN5S330_VBUS_GOOD_MASK (1 << 0)
+
extern const struct ppc_drv sn5s330_drv;
/**
* Interrupt Handler for the SN5S330.
*
* By default, the only interrupt sources that are unmasked are overcurrent
- * conditions for PP1.
+ * conditions for PP1, and VBUS_GOOD if PPC is being used to detect VBUS
+ * (CONFIG_USB_PD_VBUS_DETECT_PPC).
*
* @param port: The Type-C port which triggered the interrupt.
*/