mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 00:21:46 +00:00
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>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
@@ -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, ®val);
|
||||
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)
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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?
|
||||
|
||||
Reference in New Issue
Block a user