From 2eb6cba5bd049bc74f84691dda7abcec650a9d10 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Thu, 23 Oct 2014 16:46:05 -0700 Subject: charge_manager: Move supplier list and priority hierarchy to board Allow the list of charge suppliers and port selection priority to be specified at the board level. BUG=chrome-os-partner:32650 TEST=Manual on samus_pd. Plug + unplug PD and BC1.2 chargers, verify that PD is always preferred and higher power port / supplier is always selected. BRANCH=Samus Change-Id: Ic867a40120c809111bf76bf290ed6f204eab1168 Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/225292 Reviewed-by: Alec Berg --- board/samus_pd/board.c | 8 ++++++++ board/samus_pd/board.h | 12 +++++++++++- board/samus_pd/usb_pd_policy.c | 1 + common/charge_manager.c | 31 ++++++++++++++++++------------- include/charge_manager.h | 14 +++----------- 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c index 9c46b97952..74b0bf9b19 100644 --- a/board/samus_pd/board.c +++ b/board/samus_pd/board.c @@ -40,6 +40,14 @@ const struct pwm_t pwm_channels[] = { }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); +/* Charge supplier priority: lower number indicates higher priority. */ +const int supplier_priority[] = { + [CHARGE_SUPPLIER_PD] = 0, + [CHARGE_SUPPLIER_TYPEC] = 1, + [CHARGE_SUPPLIER_BC12] = 1, +}; +BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT); + void vbus0_evt(enum gpio_signal signal) { ccprintf("VBUS %d, %d!\n", signal, gpio_get_level(signal)); diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 8729cdc2a2..06fae2e79e 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -67,7 +67,6 @@ #define TIM_CLOCK32 2 #define TIM_ADC 3 -#include "charge_manager.h" #include "gpio_signal.h" /* ADC signal */ @@ -87,6 +86,17 @@ enum pwm_channel { PWM_CH_COUNT }; +/* Charge suppliers */ +enum charge_supplier { + CHARGE_SUPPLIER_PD, + CHARGE_SUPPLIER_TYPEC, + CHARGE_SUPPLIER_BC12, + CHARGE_SUPPLIER_COUNT +}; + +/* supplier_priority table defined in board.c */ +extern const int supplier_priority[]; + /* Charge current limit min / max, based on PWM duty cycle */ #define PWM_0_MA 500 #define PWM_100_MA 4000 diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index ea297b8c13..99eebf3f0d 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -4,6 +4,7 @@ */ #include "atomic.h" +#include "charge_manager.h" #include "common.h" #include "console.h" #include "gpio.h" diff --git a/common/charge_manager.c b/common/charge_manager.c index a7a787247d..af648f2cfd 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -68,33 +68,33 @@ static int charge_manager_is_seeded(void) */ static void charge_manager_refresh(void) { - enum charge_supplier new_supplier = CHARGE_SUPPLIER_NONE; + int new_supplier = CHARGE_SUPPLIER_NONE; int new_port = CHARGE_PORT_NONE; int new_charge_current, new_charge_voltage, i, j; /* * Charge supplier selection logic: - * 1. Prefer higher priority (lower CHARGE_SUPPLIER index) supply. - * 2. Prefer higher power over lower. + * 1. Prefer higher priority supply. + * 2. Prefer higher power over lower in case priority is tied. * available_charge can be changed at any time by other tasks, * so make no assumptions about its consistency. */ for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i) for (j = 0; j < PD_PORT_COUNT; ++j) if (available_charge[i][j].current > 0 && - available_charge[i][j].voltage > 0) { + available_charge[i][j].voltage > 0 && + (new_supplier == CHARGE_SUPPLIER_NONE || + supplier_priority[i] < + supplier_priority[new_supplier] || + (supplier_priority[i] == + supplier_priority[new_supplier] && + POWER(available_charge[i][j]) > + POWER(available_charge[new_supplier] + [new_port])))) { new_supplier = i; new_port = j; - goto got_supplier; } -got_supplier: - if (new_supplier != CHARGE_SUPPLIER_NONE) - for (i = new_port + 1; i < PD_PORT_COUNT; ++i) - if (POWER(available_charge[new_supplier][i]) > - POWER(available_charge[new_supplier][new_port])) - new_port = i; - if (new_supplier == CHARGE_SUPPLIER_NONE) new_charge_current = new_charge_voltage = 0; else { @@ -125,10 +125,15 @@ DECLARE_DEFERRED(charge_manager_refresh); * @param charge_port Charge port to update. * @param charge Charge port current / voltage. */ -void charge_manager_update(enum charge_supplier supplier, +void charge_manager_update(int supplier, int charge_port, struct charge_port_info *charge) { + if (supplier < 0 || supplier >= CHARGE_SUPPLIER_COUNT) { + CPRINTS("Invalid charge supplier: %d", supplier); + return; + } + /* Update charge table if needed. */ if (available_charge[supplier][charge_port].current != charge->current || diff --git a/include/charge_manager.h b/include/charge_manager.h index a5b4b6d275..44ed605a23 100644 --- a/include/charge_manager.h +++ b/include/charge_manager.h @@ -7,23 +7,15 @@ #define __CHARGE_MANAGER_H /* Charge port that indicates no active port */ +#define CHARGE_SUPPLIER_NONE -1 #define CHARGE_PORT_NONE -1 + /* Initial charge state */ #define CHARGE_CURRENT_UNINITIALIZED -1 #define CHARGE_VOLTAGE_UNINITIALIZED -1 #define POWER(charge_port) ((charge_port.current) * (charge_port.voltage)) -/* Charge suppliers, sorted by priority */ -enum charge_supplier { - CHARGE_SUPPLIER_NONE = -1, - /* Highest priority supplier first */ - CHARGE_SUPPLIER_PD = 0, - CHARGE_SUPPLIER_TYPEC = 1, - CHARGE_SUPPLIER_BC12 = 2, - CHARGE_SUPPLIER_COUNT -}; - /* Charge tasks report available current and voltage */ struct charge_port_info { int current; @@ -31,7 +23,7 @@ struct charge_port_info { }; /* Called by charging tasks to update their available charge */ -void charge_manager_update(enum charge_supplier supplier, +void charge_manager_update(int supplier, int charge_port, struct charge_port_info *charge); -- cgit v1.2.1