summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/aleena/board.c6
-rw-r--r--board/ampton/board.c2
-rw-r--r--board/bip/board.c2
-rw-r--r--board/careena/board.c6
-rw-r--r--board/cheza/board.c4
-rw-r--r--board/delan/board.c6
-rw-r--r--board/grunt/board.c6
-rw-r--r--board/liara/board.c6
-rw-r--r--board/nocturne/board.c13
-rw-r--r--common/usb_pd_protocol.c107
-rw-r--r--common/usbc_ppc.c99
-rw-r--r--driver/ppc/sn5s330.c5
-rw-r--r--include/usb_pd.h9
-rw-r--r--include/usbc_ppc.h74
14 files changed, 307 insertions, 38 deletions
diff --git a/board/aleena/board.c b/board/aleena/board.c
index 5ba79d81fa..5c235b7cad 100644
--- a/board/aleena/board.c
+++ b/board/aleena/board.c
@@ -116,12 +116,14 @@ void board_update_sensor_config_from_sku(void)
}
}
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
: GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
- gpio_set_level(signal, 0);
+ gpio_set_level(signal, lvl);
CPRINTS("p%d: overcurrent!", port);
}
diff --git a/board/ampton/board.c b/board/ampton/board.c
index 5f9c2a41cb..941aab7f00 100644
--- a/board/ampton/board.c
+++ b/board/ampton/board.c
@@ -316,7 +316,7 @@ void board_hibernate_late(void)
gpio_set_flags_by_mask(GPIO_KSI, 0xff, GPIO_INPUT);
}
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
/* TODO(b/78344554): pass this signal upstream once hardware reworked */
cprints(CC_USBPD, "p%d: overcurrent!", port);
diff --git a/board/bip/board.c b/board/bip/board.c
index 318a5bc178..fb4ff5e39a 100644
--- a/board/bip/board.c
+++ b/board/bip/board.c
@@ -125,7 +125,7 @@ const struct spi_device_t spi_devices[] = {
};
const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices);
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
/* TODO(b/78344554): pass this signal upstream once hardware reworked */
cprints(CC_USBPD, "p%d: overcurrent!", port);
diff --git a/board/careena/board.c b/board/careena/board.c
index 380a936fd1..0774cd9adc 100644
--- a/board/careena/board.c
+++ b/board/careena/board.c
@@ -101,12 +101,14 @@ const struct pwm_t pwm_channels[] = {
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
: GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
- gpio_set_level(signal, 0);
+ gpio_set_level(signal, lvl);
CPRINTS("p%d: overcurrent!", port);
}
diff --git a/board/cheza/board.c b/board/cheza/board.c
index fffdedf707..66121fc3bb 100644
--- a/board/cheza/board.c
+++ b/board/cheza/board.c
@@ -129,7 +129,7 @@ static void ppc_interrupt(enum gpio_signal signal)
static void usb1_oc_evt_deferred(void)
{
/* Only port-1 has overcurrent GPIO interrupt */
- board_overcurrent_event(0);
+ board_overcurrent_event(0, 1);
}
DECLARE_DEFERRED(usb1_oc_evt_deferred);
@@ -509,7 +509,7 @@ int board_is_sourcing_vbus(int port)
return EC_ERROR_INVAL;
}
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
/* TODO(b/120231371): Notify AP */
CPRINTS("p%d: overcurrent!", port);
diff --git a/board/delan/board.c b/board/delan/board.c
index f5b5f5b2dd..4304ce25e4 100644
--- a/board/delan/board.c
+++ b/board/delan/board.c
@@ -114,12 +114,14 @@ const struct pwm_t pwm_channels[] = {
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
: GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
- gpio_set_level(signal, 0);
+ gpio_set_level(signal, lvl);
CPRINTS("p%d: overcurrent!", port);
}
diff --git a/board/grunt/board.c b/board/grunt/board.c
index f60e3be18a..13e062589a 100644
--- a/board/grunt/board.c
+++ b/board/grunt/board.c
@@ -124,12 +124,14 @@ void board_update_sensor_config_from_sku(void)
gpio_enable_interrupt(GPIO_6AXIS_INT_L);
}
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
: GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
- gpio_set_level(signal, 0);
+ gpio_set_level(signal, lvl);
CPRINTS("p%d: overcurrent!", port);
}
diff --git a/board/liara/board.c b/board/liara/board.c
index 0e8a9abb5e..67e79d76c1 100644
--- a/board/liara/board.c
+++ b/board/liara/board.c
@@ -114,12 +114,14 @@ const struct pwm_t pwm_channels[] = {
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
: GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
- gpio_set_level(signal, 0);
+ gpio_set_level(signal, lvl);
CPRINTS("p%d: overcurrent!", port);
}
diff --git a/board/nocturne/board.c b/board/nocturne/board.c
index ffa8c65920..20b4b3983b 100644
--- a/board/nocturne/board.c
+++ b/board/nocturne/board.c
@@ -572,28 +572,29 @@ static void board_quirks(void)
}
DECLARE_HOOK(HOOK_INIT, board_quirks, HOOK_PRIO_DEFAULT);
-void board_overcurrent_event(int port)
+void board_overcurrent_event(int port, int is_overcurrented)
{
+ int lvl;
+
/* Sanity check the port. */
if ((port < 0) || (port >= CONFIG_USB_PD_PORT_COUNT))
return;
/* Note that the levels are inverted because the pin is active low. */
+ lvl = is_overcurrented ? 0 : 1;
+
switch (port) {
case 0:
- gpio_set_level(GPIO_USB_C0_OC_ODL, 0);
+ gpio_set_level(GPIO_USB_C0_OC_ODL, lvl);
break;
case 1:
- gpio_set_level(GPIO_USB_C1_OC_ODL, 0);
+ gpio_set_level(GPIO_USB_C1_OC_ODL, lvl);
break;
default:
return;
};
-
- /* TODO(b/69935262): Write a PD log entry for the OC event. */
- CPRINTS("C%d: overcurrent!", port);
}
static int read_gyro_sensor_temp(int idx, int *temp_ptr)
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 542d388a3e..a22d22fd4f 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -630,7 +630,19 @@ static inline void set_state(int port, enum pd_states next_state)
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
if (next_state != PD_STATE_DRP_AUTO_TOGGLE)
exit_low_power_mode(port);
-#endif
+
+#ifdef CONFIG_USBC_PPC
+ /* If we're entering DRP_AUTO_TOGGLE, there is no sink connected. */
+ if (next_state == PD_STATE_DRP_AUTO_TOGGLE) {
+ ppc_sink_is_connected(port, 0);
+ /*
+ * Clear the overcurrent event counter
+ * since we've detected a disconnect.
+ */
+ ppc_clear_oc_event_counter(port);
+ }
+#endif /* CONFIG_USBC_PPC */
+#endif /* CONFIG_USB_PD_TCPC_LOW_POWER */
#ifdef CONFIG_USB_PD_DUAL_ROLE
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
@@ -648,6 +660,23 @@ static inline void set_state(int port, enum pd_states next_state)
if (next_state == PD_STATE_SRC_DISCONNECTED ||
next_state == PD_STATE_SNK_DISCONNECTED) {
+#ifdef CONFIG_USBC_PPC
+ int cc1, cc2;
+
+ tcpm_get_cc(port, &cc1, &cc2);
+ /*
+ * Neither a debug accessory nor UFP attached.
+ * Tell the PPC module that there is no sink connected.
+ */
+ if (cc1 != TYPEC_CC_VOLT_RD && cc2 != TYPEC_CC_VOLT_RD) {
+ ppc_sink_is_connected(port, 0);
+ /*
+ * Clear the overcurrent event counter
+ * since we've detected a disconnect.
+ */
+ ppc_clear_oc_event_counter(port);
+ }
+#endif /* CONFIG_USBC_PPC */
/* Clear the input current limit */
pd_set_input_current_limit(port, 0, 0);
#ifdef CONFIG_CHARGE_MANAGER
@@ -2841,6 +2870,15 @@ void pd_task(void *u)
}
#endif
+#ifdef CONFIG_USBC_PPC
+ /*
+ * TODO: Useful for non-PPC cases as well, but only needed
+ * for PPC cases right now. Revisit later.
+ */
+ if (evt & PD_EVENT_SEND_HARD_RESET)
+ set_state(port, PD_STATE_HARD_RESET_SEND);
+#endif /* defined(CONFIG_USBC_PPC) */
+
/* process any potential incoming message */
incoming_packet = tcpm_has_pending_message(port);
if (incoming_packet) {
@@ -2985,9 +3023,23 @@ void pd_task(void *u)
if (get_time().val < pd[port].cc_debounce)
break;
- /* Debounce complete. UFP is attached */
+ /* Debounce complete */
+#ifdef CONFIG_USBC_PPC
+ /*
+ * If the port is latched off, just continue to
+ * monitor for a detach.
+ */
+ if (ppc_is_port_latched_off(port))
+ break;
+#endif /* CONFIG_USBC_PPC */
+
+ /* UFP is attached */
if (new_cc_state == PD_CC_UFP_ATTACHED ||
new_cc_state == PD_CC_DEBUG_ACC) {
+#ifdef CONFIG_USBC_PPC
+ /* Inform PPC that a sink is connected. */
+ ppc_sink_is_connected(port, 1);
+#endif /* CONFIG_USBC_PPC */
pd[port].polarity = (cc1 != TYPEC_CC_VOLT_RD);
set_polarity(port, pd[port].polarity);
@@ -4453,6 +4505,57 @@ void pd_update_contract(int port)
#endif /* CONFIG_USB_PD_DUAL_ROLE */
+#ifdef CONFIG_USBC_PPC
+static void pd_send_hard_reset(int port)
+{
+ task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_SEND_HARD_RESET, 0);
+}
+
+static uint32_t port_oc_reset_req;
+
+static void re_enable_ports(void)
+{
+ uint32_t ports = atomic_read_clear(&port_oc_reset_req);
+
+ while (ports) {
+ int port = __fls(ports);
+
+ ports &= ~(1 << port);
+
+ /*
+ * Let the board know that the overcurrent is
+ * over since we're going to attempt re-enabling
+ * the port.
+ */
+ board_overcurrent_event(port, 0);
+
+ pd_send_hard_reset(port);
+ /*
+ * TODO(b/117854867): PD3.0 to send an alert message
+ * indicating OCP after explicit contract.
+ */
+ }
+}
+DECLARE_DEFERRED(re_enable_ports);
+
+void pd_handle_overcurrent(int port)
+{
+ /* Keep track of the overcurrent events. */
+ CPRINTS("C%d: overcurrent!", port);
+#ifdef CONFIG_USB_PD_LOGGING
+ pd_log_event(PD_EVENT_PS_FAULT, PD_LOG_PORT_SIZE(port, 0), PS_FAULT_OCP,
+ NULL);
+#endif /* defined(CONFIG_USB_PD_LOGGING) */
+ ppc_add_oc_event(port);
+ /* Let the board specific code know about the OC event. */
+ board_overcurrent_event(port, 1);
+
+ /* Wait 1s before trying to re-enable the port. */
+ atomic_or(&port_oc_reset_req, (1 << port));
+ hook_call_deferred(&re_enable_ports_data, SECOND);
+}
+#endif /* defined(CONFIG_USBC_PPC) */
+
static int command_pd(int argc, char **argv)
{
int port;
diff --git a/common/usbc_ppc.c b/common/usbc_ppc.c
index 0961ba6e83..9ec33a3ec1 100644
--- a/common/usbc_ppc.c
+++ b/common/usbc_ppc.c
@@ -5,15 +5,26 @@
/* USB-C Power Path Controller Common Code */
+#include "atomic.h"
#include "common.h"
#include "console.h"
#include "hooks.h"
+#include "timer.h"
#include "usbc_ppc.h"
#include "util.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+/*
+ * A per-port table that indicates how many VBUS overcurrent events have
+ * occurred. This table is cleared after detecting a physical disconnect of the
+ * sink.
+ */
+static uint8_t oc_event_cnt_tbl[CONFIG_USB_PD_PORT_COUNT];
+
+static uint32_t connected_ports;
+
/* Simple wrappers to dispatch to the drivers. */
int ppc_init(int port)
@@ -32,6 +43,59 @@ int ppc_init(int port)
return rv;
}
+int ppc_add_oc_event(int port)
+{
+ if ((port < 0) || (port >= ppc_cnt))
+ return EC_ERROR_INVAL;
+
+ oc_event_cnt_tbl[port]++;
+
+ /* The port overcurrented, so don't clear it's OC events. */
+ atomic_clear(&connected_ports, 1 << port);
+
+ if (oc_event_cnt_tbl[port] >= PPC_OC_CNT_THRESH)
+ CPRINTS("C%d: OC event limit reached! "
+ "Source path disabled until physical disconnect.",
+ port);
+ return EC_SUCCESS;
+}
+
+static void clear_oc_tbl(void)
+{
+ int port;
+
+ for (port = 0; port < ppc_cnt; port++)
+ /*
+ * Only clear the table if the port partner is no longer
+ * attached after debouncing.
+ */
+ if ((!((1 << port) & connected_ports)) &&
+ oc_event_cnt_tbl[port]) {
+ oc_event_cnt_tbl[port] = 0;
+ CPRINTS("C%d: OC events cleared", port);
+ }
+}
+DECLARE_DEFERRED(clear_oc_tbl);
+
+int ppc_clear_oc_event_counter(int port)
+{
+ if ((port < 0) || (port >= ppc_cnt))
+ return EC_ERROR_INVAL;
+
+ /*
+ * If we are clearing our event table in quick succession, we may be in
+ * an overcurrent loop where we are also detecting a disconnect on the
+ * CC pins. Therefore, let's not clear it just yet and the let the
+ * limit be reached. This way, we won't send the hard reset and
+ * actually detect the physical disconnect.
+ */
+ if (oc_event_cnt_tbl[port]) {
+ hook_call_deferred(&clear_oc_tbl_data,
+ PPC_OC_COOLDOWN_DELAY_US);
+ }
+ return EC_SUCCESS;
+}
+
int ppc_is_sourcing_vbus(int port)
{
if ((port < 0) || (port >= ppc_cnt)) {
@@ -68,16 +132,41 @@ int ppc_discharge_vbus(int port, int enable)
return ppc_chips[port].drv->discharge_vbus(port, enable);
}
+int ppc_is_port_latched_off(int port)
+{
+ if ((port < 0) || (port >= ppc_cnt))
+ return 0;
+
+ return oc_event_cnt_tbl[port] >= PPC_OC_CNT_THRESH;
+}
+
#ifdef CONFIG_USBC_PPC_VCONN
int ppc_set_vconn(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
return EC_ERROR_INVAL;
+ /*
+ * Check our OC event counter. If we've exceeded our threshold, then
+ * let's latch our source path off to prevent continuous cycling. When
+ * the PD state machine detects a disconnection on the CC lines, we will
+ * reset our OC event counter.
+ */
+ if (enable && ppc_is_port_latched_off(port))
+ return EC_ERROR_ACCESS_DENIED;
+
return ppc_chips[port].drv->set_vconn(port, enable);
}
#endif
+void ppc_sink_is_connected(int port, int is_connected)
+{
+ if (is_connected)
+ atomic_or(&connected_ports, 1 << port);
+ else
+ atomic_clear(&connected_ports, 1 << port);
+}
+
int ppc_vbus_sink_enable(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
@@ -104,6 +193,15 @@ int ppc_vbus_source_enable(int port, int enable)
if ((port < 0) || (port >= ppc_cnt))
return EC_ERROR_INVAL;
+ /*
+ * Check our OC event counter. If we've exceeded our threshold, then
+ * let's latch our source path off to prevent continuous cycling. When
+ * the PD state machine detects a disconnection on the CC lines, we will
+ * reset our OC event counter.
+ */
+ if (enable && ppc_is_port_latched_off(port))
+ return EC_ERROR_ACCESS_DENIED;
+
return ppc_chips[port].drv->vbus_source_enable(port, enable);
}
@@ -119,7 +217,6 @@ int ppc_is_vbus_present(int port)
}
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
-
#ifdef CONFIG_CMD_PPC_DUMP
static int command_ppc_dump(int argc, char **argv)
{
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
index b90605a3e1..6b48c8650b 100644
--- a/driver/ppc/sn5s330.c
+++ b/driver/ppc/sn5s330.c
@@ -19,6 +19,7 @@
#include "timer.h"
#include "usb_charge.h"
#include "usb_pd_tcpm.h"
+#include "usb_pd.h"
#include "usbc_ppc.h"
#include "util.h"
@@ -641,9 +642,9 @@ static void sn5s330_handle_interrupt(int port)
read_reg(port, SN5S330_INT_TRIP_RISE_REG1, &rise);
read_reg(port, SN5S330_INT_TRIP_FALL_REG1, &fall);
- /* Let the board know about the overcurrent event. */
+ /* Notify the system about the overcurrent event. */
if (rise & SN5S330_ILIM_PP1_MASK)
- board_overcurrent_event(port);
+ pd_handle_overcurrent(port);
/* Clear the interrupt sources. */
write_reg(port, SN5S330_INT_TRIP_RISE_REG1, rise);
diff --git a/include/usb_pd.h b/include/usb_pd.h
index d87fcc8fa4..5ae89696dd 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -48,6 +48,7 @@ enum pd_rx_errors {
*/
#define PD_EVENT_DEVICE_ACCESSED (1<<7)
#define PD_EVENT_POWER_STATE_CHANGE (1<<8) /* Chipset power state changed */
+#define PD_EVENT_SEND_HARD_RESET (1<<9) /* Issue a Hard Reset. */
/* Ensure TCPC is out of low power mode before handling these events. */
#define PD_EXIT_LOW_POWER_EVENT_MASK \
@@ -1769,6 +1770,14 @@ int pd_get_polarity(int port);
int pd_get_partner_data_swap_capable(int port);
/**
+ * Handle an overcurrent protection event. The port acting as a source has
+ * reported an overcurrent event.
+ *
+ * @param port: USB-C port number.
+ */
+void pd_handle_overcurrent(int port);
+
+/**
* Request power swap command to be issued
*
* @param port USB-C port number
diff --git a/include/usbc_ppc.h b/include/usbc_ppc.h
index 06c2ff3f2f..a502ebe91e 100644
--- a/include/usbc_ppc.h
+++ b/include/usbc_ppc.h
@@ -11,6 +11,18 @@
/* Common APIs for USB Type-C Power Path Controllers (PPC) */
+/*
+ * Number of times a port may overcurrent before we latch off the port until a
+ * physical disconnect is detected.
+ */
+#define PPC_OC_CNT_THRESH 3
+
+/*
+ * Number of seconds until a latched-off port is re-enabled for sourcing after
+ * detecting a physical disconnect.
+ */
+#define PPC_OC_COOLDOWN_DELAY_US (2 * SECOND)
+
struct ppc_drv {
/**
* Initialize the PPC.
@@ -127,6 +139,31 @@ extern struct ppc_config_t ppc_chips[];
extern unsigned int ppc_cnt;
/**
+ * Increment the overcurrent event counter.
+ *
+ * @param port: The Type-C port that has overcurrented.
+ * @return EC_SUCCESS on success, EC_ERROR_INVAL if non-existent port.
+ */
+int ppc_add_oc_event(int port);
+
+/**
+ * Clear the overcurrent event counter.
+ *
+ * @param port: The Type-C port's counter to clear.
+ * @return EC_SUCCESS on success, EC_ERROR_INVAL if non-existent port.
+ */
+int ppc_clear_oc_event_counter(int port);
+
+/**
+ * Discharge PD VBUS on src/sink disconnect & power role swap
+ *
+ * @param port: The Type-C port number.
+ * @param enable: 1 -> discharge vbus, 0 -> stop discharging vbus
+ * @return EC_SUCCESS on success, error otherwise.
+ */
+int ppc_discharge_vbus(int port, int enable);
+
+/**
* Initializes the PPC for the specified port.
*
* @param port: The Type-C port number.
@@ -135,12 +172,12 @@ extern unsigned int ppc_cnt;
int ppc_init(int port);
/**
- * Determine if VBUS is present or not.
+ * Is the port latched off due to multiple overcurrent events in succession?
*
* @param port: The Type-C port number.
- * @return 1 if VBUS is present, 0 if not.
+ * @return 1 if the port is latched off, 0 if it is not latched off.
*/
-int ppc_is_vbus_present(int port);
+int ppc_is_port_latched_off(int port);
/**
* Is the port sourcing Vbus?
@@ -151,6 +188,25 @@ int ppc_is_vbus_present(int port);
int ppc_is_sourcing_vbus(int port);
/**
+ * Determine if VBUS is present or not.
+ *
+ * @param port: The Type-C port number.
+ * @return 1 if VBUS is present, 0 if not.
+ */
+int ppc_is_vbus_present(int port);
+
+/**
+ * Inform the PPC module that a sink is connected.
+ *
+ * This is used such that it can determine when to clear the overcurrent events
+ * counter for a port.
+ * @param port: The Type-C port number.
+ * @param is_connected: 1: if sink is connected on this port, 0: if not
+ * connected.
+ */
+void ppc_sink_is_connected(int port, int is_connected);
+
+/**
* Inform the PPC of the polarity of the CC pins.
*
* @param port: The Type-C port number.
@@ -177,15 +233,6 @@ int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp);
int ppc_set_vconn(int port, int enable);
/**
- * Discharge PD VBUS on src/sink disconnect & power role swap
- *
- * @param port: The Type-C port number.
- * @param enable: 1 -> discharge vbus, 0 -> stop discharging vbus
- * @return EC_SUCCESS on success, error otherwise.
- */
-int ppc_discharge_vbus(int port, int enable);
-
-/**
* Turn on/off the charge path FET, such that current flows into the
* system.
*
@@ -209,8 +256,9 @@ int ppc_vbus_source_enable(int port, int enable);
* Board specific callback when a port overcurrents.
*
* @param port: The Type-C port which overcurrented.
+ * @param is_overcurrented: 1 if port overcurrented, 0 if the condition is gone.
*/
-void board_overcurrent_event(int port);
+void board_overcurrent_event(int port, int is_overcurrented);
/**
* Put the PPC into its lowest power state. In this state it should still fire