diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-08-14 15:28:20 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-19 01:50:21 +0000 |
commit | 4d382ad6401cbe178fa9c53309bdc8a460cf3413 (patch) | |
tree | 30822cab382bbba385db6a1891d5df3daa060613 /common/charge_manager.c | |
parent | aa14b36f1890e373424463afc584659b2834dce6 (diff) | |
download | chrome-ec-4d382ad6401cbe178fa9c53309bdc8a460cf3413.tar.gz |
charge_manager: Support multiple independent charge ceilings
We will soon have a need to independently set a charge ceiling from both
the PD state machine and from incoming host commands. Store these
ceilings separately, and have the minimum take effect.
BUG=chrome-os-partner:43285
TEST=Pass unit tests. Also, host command current limit takes effect with
subsequent commit.
BRANCH=None
Change-Id: I0ecfe888a7df0d5da5a68999c164c7c841da348b
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/293818
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'common/charge_manager.c')
-rw-r--r-- | common/charge_manager.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c index da465d2d73..4e21bdf2bd 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -45,10 +45,12 @@ static struct charge_port_info available_charge[CHARGE_SUPPLIER_COUNT] static timestamp_t registration_time[CONFIG_USB_PD_PORT_COUNT]; /* - * Charge ceiling for ports. This can be set to temporarily limit the charge - * pulled from a port, without influencing the port selection logic. + * Charge current ceiling (mA) for ports. This can be set to temporarily limit + * the charge pulled from a port, without influencing the port selection logic. + * The ceiling can be set independently from several requestors, with the + * minimum ceiling taking effect. */ -static int charge_ceil[CONFIG_USB_PD_PORT_COUNT]; +static int charge_ceil[CONFIG_USB_PD_PORT_COUNT][CEIL_REQUESTOR_COUNT]; /* Dual-role capability of attached partner port */ static enum dualrole_capabilities dualrole_capability[CONFIG_USB_PD_PORT_COUNT]; @@ -105,7 +107,8 @@ static void charge_manager_init(void) available_charge[j][i].voltage = CHARGE_VOLTAGE_UNINITIALIZED; } - charge_ceil[i] = CHARGE_CEIL_NONE; + for (j = 0; j < CEIL_REQUESTOR_COUNT; ++j) + charge_ceil[i][j] = CHARGE_CEIL_NONE; dualrole_capability[i] = spoof_capability ? CAP_DEDICATED : CAP_UNKNOWN; } @@ -317,6 +320,29 @@ static void charge_manager_cleanup_override_port(int port) } /** + * Return the computed charge ceiling for a port, which represents the + * minimum ceiling among all valid requestors. + * + * @param port Charge port. + * @return Charge ceiling (mA) or CHARGE_CEIL_NONE. + */ +static int charge_manager_get_ceil(int port) +{ + int ceil = CHARGE_CEIL_NONE; + int val, i; + + ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_COUNT); + for (i = 0; i < CEIL_REQUESTOR_COUNT; ++i) { + val = charge_ceil[port][i]; + if (val != CHARGE_CEIL_NONE && + (ceil == CHARGE_CEIL_NONE || val < ceil)) + ceil = val; + } + + return ceil; +} + +/** * Select the 'best' charge port, as defined by the supplier heirarchy and the * ability of the port to provide power. */ @@ -411,6 +437,7 @@ static void charge_manager_refresh(void) int new_charge_voltage, i; int updated_new_port = CHARGE_PORT_NONE; int updated_old_port = CHARGE_PORT_NONE; + int ceil; /* Hunt for an acceptable charge port */ while (1) { @@ -467,8 +494,9 @@ static void charge_manager_refresh(void) new_charge_current_uncapped); #endif /* CONFIG_CHARGE_RAMP_HW */ /* Enforce port charge ceiling. */ - if (charge_ceil[new_port] != CHARGE_CEIL_NONE) - new_charge_current = MIN(charge_ceil[new_port], + ceil = charge_manager_get_ceil(new_port); + if (ceil != CHARGE_CEIL_NONE) + new_charge_current = MIN(ceil, new_charge_current_uncapped); else new_charge_current = new_charge_current_uncapped; @@ -677,17 +705,20 @@ void charge_manager_update_dualrole(int port, enum dualrole_capabilities cap) } /** - * Update charge ceiling for a given port. + * Update charge ceiling for a given port. The ceiling can be set independently + * for several requestors, and the min. ceil will be enforced. * * @param port Charge port to update. + * @param requestor Charge ceiling requestor. * @param ceil Charge ceiling (mA). */ -void charge_manager_set_ceil(int port, int ceil) +void charge_manager_set_ceil(int port, enum ceil_requestor requestor, int ceil) { - ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_COUNT); + ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_COUNT && + requestor >= 0 && requestor < CEIL_REQUESTOR_COUNT); - if (charge_ceil[port] != ceil) { - charge_ceil[port] = ceil; + if (charge_ceil[port][requestor] != ceil) { + charge_ceil[port][requestor] = ceil; if (port == charge_port && charge_manager_is_seeded()) hook_call_deferred(charge_manager_refresh, 0); } |