summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/grunt/usb_pd_policy.c11
-rw-r--r--common/usb_charger.c3
-rw-r--r--common/usbc_ppc.c10
-rw-r--r--driver/ppc/sn5s330.c43
-rw-r--r--driver/ppc/sn5s330.h12
-rw-r--r--include/usbc_ppc.h18
6 files changed, 58 insertions, 39 deletions
diff --git a/board/grunt/usb_pd_policy.c b/board/grunt/usb_pd_policy.c
index ca2545c436..3f873beee4 100644
--- a/board/grunt/usb_pd_policy.c
+++ b/board/grunt/usb_pd_policy.c
@@ -173,16 +173,7 @@ void typec_set_source_current_limit(int port, int rp)
int pd_snk_is_vbus_provided(int port)
{
- int vbus_present = 0;
- int rv;
-
- rv = ppc_is_vbus_present(port, &vbus_present);
- if (rv) {
- CPRINTS("p%d: VBUS present error (%d)", port, rv);
- return 0;
- }
-
- return vbus_present;
+ return ppc_is_vbus_present(port);
}
int board_vbus_source_enabled(int port)
diff --git a/common/usb_charger.c b/common/usb_charger.c
index 1c01695d0e..3e7d52f646 100644
--- a/common/usb_charger.c
+++ b/common/usb_charger.c
@@ -75,7 +75,8 @@ void usb_charger_vbus_change(int port, int vbus_level)
task_set_event(USB_CHG_PORT_TO_TASK_ID(port), USB_CHG_EVENT_VBUS, 0);
#endif
-#ifdef CONFIG_USB_PD_VBUS_DETECT_CHARGER
+#if (defined(CONFIG_USB_PD_VBUS_DETECT_CHARGER) \
+ || defined(CONFIG_USB_PD_VBUS_DETECT_PPC))
/* USB PD task */
task_wake(PD_PORT_TO_TASK_ID(port));
#endif
diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c
index 34cfbabf50..4cea6813bc 100644
--- a/common/usbc_ppc.c
+++ b/common/usbc_ppc.c
@@ -75,12 +75,14 @@ int ppc_vbus_source_enable(int port, int enable)
}
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-int ppc_is_vbus_present(int port, int *vbus_present)
+int ppc_is_vbus_present(int port)
{
- if (port >= ppc_cnt)
- return EC_ERROR_INVAL;
+ if ((port < 0) || (port >= ppc_cnt)) {
+ CPRINTS("%s(%d) Invalid port!", __func__, port);
+ return 0;
+ }
- return ppc_chips[port].drv->is_vbus_present(port, vbus_present);
+ return ppc_chips[port].drv->is_vbus_present(port);
}
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
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.
*/
diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h
index 4fbb913a11..eec8362959 100644
--- a/include/usbc_ppc.h
+++ b/include/usbc_ppc.h
@@ -77,21 +77,13 @@ struct ppc_drv {
#endif /* defined(CONFIG_CMD_PPC_DUMP) */
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
- /*
- * TODO(aaboagye): In order for VBUS detection to work properly for our
- * system, we need to enable VBUS interrupts and send the appropriate
- * notifications.
- */
-
/**
* Determine if VBUS is present or not.
*
* @param port: The Type-C port number.
- * @param vbus_present: 1: VBUS is present. 0: VBUS is not present.
- * @return EC_SUCCESS if able to determine VBUS status, otherwise an
- * error.
+ * @return 1 if VBUS is present, 0 if not.
*/
- int (*is_vbus_present)(int port, int *vbus_present);
+ int (*is_vbus_present)(int port);
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
};
@@ -116,11 +108,9 @@ int ppc_init(int port);
* Determine if VBUS is present or not.
*
* @param port: The Type-C port number.
- * @param vbus_present: 1: VBUS is present. 0: VBUS is not present.
- * @return EC_SUCCESS if able to determine VBUS status, otherwise an
- * error.
+ * @return 1 if VBUS is present, 0 if not.
*/
-int ppc_is_vbus_present(int port, int *vbus_present);
+int ppc_is_vbus_present(int port);
/**
* Is the port sourcing Vbus?