summaryrefslogtreecommitdiff
path: root/board/samus_pd/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/samus_pd/board.c')
-rw-r--r--board/samus_pd/board.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c
index 63b435bc33..d4432e73b6 100644
--- a/board/samus_pd/board.c
+++ b/board/samus_pd/board.c
@@ -32,6 +32,9 @@
/* Amount to offset the input current limit when sending to EC */
#define INPUT_CURRENT_LIMIT_OFFSET_MA 192
+/* Default input current limit when VBUS is present */
+#define DEFAULT_CURR_LIMIT 500 /* mA */
+
/* Chipset power state */
static enum power_state ps;
@@ -66,7 +69,8 @@ const int supplier_priority[] = {
[CHARGE_SUPPLIER_BC12_DCP] = 1,
[CHARGE_SUPPLIER_BC12_CDP] = 2,
[CHARGE_SUPPLIER_BC12_SDP] = 3,
- [CHARGE_SUPPLIER_OTHER] = 3
+ [CHARGE_SUPPLIER_OTHER] = 3,
+ [CHARGE_SUPPLIER_VBUS] = 4
};
BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT);
@@ -86,6 +90,19 @@ DECLARE_DEFERRED(pericom_port1_reenable_interrupts);
void vbus0_evt(enum gpio_signal signal)
{
+ struct charge_port_info charge;
+ int vbus_level = gpio_get_level(signal);
+
+ /*
+ * If VBUS is low, or VBUS is high and we are not outputting VBUS
+ * ourselves, then update the VBUS supplier.
+ */
+ if (!vbus_level || !gpio_get_level(GPIO_USB_C0_5V_EN)) {
+ charge.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge.current = vbus_level ? DEFAULT_CURR_LIMIT : 0;
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 0, &charge);
+ }
+
/*
* Re-enable interrupts on pericom charger detector since the
* chip may periodically reset itself, and come back up with
@@ -99,6 +116,19 @@ void vbus0_evt(enum gpio_signal signal)
void vbus1_evt(enum gpio_signal signal)
{
+ struct charge_port_info charge;
+ int vbus_level = gpio_get_level(signal);
+
+ /*
+ * If VBUS is low, or VBUS is high and we are not outputting VBUS
+ * ourselves, then update the VBUS supplier.
+ */
+ if (!vbus_level || !gpio_get_level(GPIO_USB_C1_5V_EN)) {
+ charge.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge.current = vbus_level ? DEFAULT_CURR_LIMIT : 0;
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 1, &charge);
+ }
+
/*
* Re-enable interrupts on pericom charger detector since the
* chip may periodically reset itself, and come back up with
@@ -359,7 +389,7 @@ static void board_init(void)
int pd_enable, i;
int slp_s5 = gpio_get_level(GPIO_PCH_SLP_S5_L);
int slp_s3 = gpio_get_level(GPIO_PCH_SLP_S3_L);
- struct charge_port_info charge;
+ struct charge_port_info charge_none, charge_vbus;
/*
* Enable CC lines after all GPIO have been initialized. Note, it is
@@ -373,26 +403,43 @@ static void board_init(void)
gpio_enable_interrupt(GPIO_USB_C1_VBUS_WAKE);
/* Initialize all pericom charge suppliers to 0 */
- charge.voltage = USB_BC12_CHARGE_VOLTAGE;
- charge.current = 0;
+ charge_none.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge_none.current = 0;
for (i = 0; i < PD_PORT_COUNT; i++) {
charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
i,
- &charge);
+ &charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_CDP,
i,
- &charge);
+ &charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_DCP,
i,
- &charge);
+ &charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_SDP,
i,
- &charge);
+ &charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_OTHER,
i,
- &charge);
+ &charge_none);
}
+ /* Initialize VBUS supplier based on whether or not VBUS is present */
+ charge_vbus.voltage = USB_BC12_CHARGE_VOLTAGE;
+ charge_vbus.current = DEFAULT_CURR_LIMIT;
+ if (gpio_get_level(GPIO_USB_C0_VBUS_WAKE))
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 0,
+ &charge_vbus);
+ else
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 0,
+ &charge_none);
+
+ if (gpio_get_level(GPIO_USB_C1_VBUS_WAKE))
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 1,
+ &charge_vbus);
+ else
+ charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, 1,
+ &charge_none);
+
/* Enable pericom BC1.2 interrupts. */
gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_L);
gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_L);
@@ -621,8 +668,11 @@ int board_set_active_charge_port(int charge_port)
{
/* charge port is a realy physical port */
int is_real_port = (charge_port >= 0 && charge_port < PD_PORT_COUNT);
+ /* check if we are source vbus on that port */
+ int source = gpio_get_level(charge_port == 0 ? GPIO_USB_C0_5V_EN :
+ GPIO_USB_C1_5V_EN);
- if (is_real_port && pd_get_role(charge_port) != PD_ROLE_SINK) {
+ if (is_real_port && source) {
CPRINTS("Skip enable p%d", charge_port);
return EC_ERROR_INVAL;
}