summaryrefslogtreecommitdiff
path: root/driver/bc12/pi3usb9201.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/bc12/pi3usb9201.c')
-rw-r--r--driver/bc12/pi3usb9201.c48
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.
*/