diff options
-rw-r--r-- | driver/bc12/pi3usb9201.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/driver/bc12/pi3usb9201.c b/driver/bc12/pi3usb9201.c index d6e82c3c57..ba4ab9e496 100644 --- a/driver/bc12/pi3usb9201.c +++ b/driver/bc12/pi3usb9201.c @@ -37,6 +37,9 @@ struct bc12_status { int current_limit; }; +/* Used to store last BC1.2 detection result */ +static enum charge_supplier bc12_supplier[CONFIG_USB_PD_PORT_COUNT]; + static const struct bc12_status bc12_chg_limits[] = { [CHG_OTHER] = {CHARGE_SUPPLIER_OTHER, 500}, [CHG_2_4A] = {CHARGE_SUPPLIER_PROPRIETARY, 2400}, @@ -136,6 +139,23 @@ static int pi3usb9201_get_status(int port, int *client, int *host) return rv; } +static void bc12_update_supplier(enum charge_supplier supplier, int port, + struct charge_port_info *new_chg) +{ + /* + * If most recent supplier type is not CHARGE_SUPPLIER_NONE, then the + * charge manager table entry for that supplier type needs to be cleared + * out. + */ + if (bc12_supplier[port] != CHARGE_SUPPLIER_NONE) + charge_manager_update_charge(bc12_supplier[port], port, NULL); + /* Now update the current supplier type */ + bc12_supplier[port] = supplier; + /* If new supplier type != NONE, then notify charge manager */ + if (supplier != CHARGE_SUPPLIER_NONE) + charge_manager_update_charge(supplier, port, new_chg); +} + static void bc12_update_charge_manager(int port, int client_status) { struct charge_port_info new_chg; @@ -159,7 +179,7 @@ static void bc12_update_charge_manager(int port, int client_status) /* bc1.2 is complete and start bit does not auto clear */ pi3usb9201_bc12_detect_ctrl(port, 0); /* Inform charge manager of new supplier type and current limit */ - charge_manager_update_charge(supplier, port, &new_chg); + bc12_update_supplier(supplier, port, &new_chg); } static int bc12_detect_start(int port) @@ -192,8 +212,11 @@ static void bc12_power_down(int port) pi3usb9201_bc12_detect_ctrl(port, 0); /* Mask interrupts unitl next bc1.2 detection event */ pi3usb9201_interrupt_mask(port, 1); - /* Let charge manager know there's no more charge available. */ - charge_manager_update_charge(CHARGE_SUPPLIER_NONE, port, NULL); + /* + * Let charge manager know there's no more charge available for the + * supplier type that was most recently detected. + */ + bc12_update_supplier(CHARGE_SUPPLIER_NONE, port, NULL); #if defined(CONFIG_POWER_PP5000_CONTROL) && defined(HAS_TASK_CHIPSET) /* Indicate PP5000_A rail is not required by USB_CHG task. */ power_5v_enable(task_get_current(), 0); @@ -215,6 +238,14 @@ void usb_charger_task(void *u) { int port = (task_get_current() == TASK_ID_USB_CHG_P0 ? 0 : 1); uint32_t evt; + int i; + + /* + * Set most recent bc1.2 detection supplier result to + * CHARGE_SUPPLIER_NONE for all ports. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) + bc12_supplier[port] = CHARGE_SUPPLIER_NONE; /* * The is no specific initialization required for the pi3usb9201 other @@ -260,9 +291,9 @@ void usb_charger_task(void *u) new_chg.voltage = USB_CHARGER_VOLTAGE_MV; new_chg.current = USB_CHARGER_MIN_CURR_MA; - charge_manager_update_charge( - CHARGE_SUPPLIER_OTHER, - port, &new_chg); + /* Save supplier type and notify chg manager */ + bc12_update_supplier(CHARGE_SUPPLIER_OTHER, + port, &new_chg); CPRINTS("pi3usb9201[p%d]: bc1.2 failed use " "defaults", port); } @@ -279,6 +310,11 @@ void usb_charger_task(void *u) int rv; /* + * Update the charge manager if bc1.2 client mode is + * currently active. + */ + bc12_update_supplier(CHARGE_SUPPLIER_NONE, port, NULL); + /* * If the port is in DFP mode, then need to set mode to * CDP_HOST which will auto close D+/D- switches. */ |