summaryrefslogtreecommitdiff
path: root/common/charge_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/charge_manager.c')
-rw-r--r--common/charge_manager.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c
index 6f8a796999..d95f5cb809 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -140,7 +140,7 @@ enum charge_manager_change_type {
static int is_pd_port(int port)
{
- return port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT;
+ return port >= 0 && port < board_get_usb_pd_port_count();
}
static int is_sink(int port)
@@ -151,6 +151,25 @@ static int is_sink(int port)
return pd_get_role(port) == PD_ROLE_SINK;
}
+/**
+ * Some of the SKUs in certain boards have less number of USB PD ports than
+ * defined in CONFIG_USB_PD_PORT_MAX_COUNT. With the charge port configuration
+ * for DEDICATED_PORT towards the end, this will lead to holes in the static
+ * configuration. The ports that fall in that hole are invalid and this function
+ * is used to check the validity of the ports.
+ */
+static int is_valid_port(int port)
+{
+ if (port < 0 || port >= CHARGE_PORT_COUNT)
+ return 0;
+
+ /* Check if the port falls in the hole */
+ if (port >= board_get_usb_pd_port_count() &&
+ port < CONFIG_USB_PD_PORT_MAX_COUNT)
+ return 0;
+ return 1;
+}
+
#ifndef TEST_BUILD
static int is_connected(int port)
{
@@ -190,6 +209,8 @@ static void charge_manager_init(void)
int i, j;
for (i = 0; i < CHARGE_PORT_COUNT; ++i) {
+ if (!is_valid_port(i))
+ continue;
for (j = 0; j < CHARGE_SUPPLIER_COUNT; ++j) {
available_charge[j][i].current =
CHARGE_CURRENT_UNINITIALIZED;
@@ -221,14 +242,17 @@ static int charge_manager_is_seeded(void)
if (is_seeded)
return 1;
- for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i)
- for (j = 0; j < CHARGE_PORT_COUNT; ++j)
+ for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i) {
+ for (j = 0; j < CHARGE_PORT_COUNT; ++j) {
+ if (!is_valid_port(j))
+ continue;
if (available_charge[i][j].current ==
CHARGE_CURRENT_UNINITIALIZED ||
available_charge[i][j].voltage ==
CHARGE_VOLTAGE_UNINITIALIZED)
return 0;
-
+ }
+ }
is_seeded = 1;
return 1;
}
@@ -506,6 +530,9 @@ static int charge_manager_get_ceil(int port)
int ceil = CHARGE_CEIL_NONE;
int val, i;
+ if (!is_valid_port(port))
+ return ceil;
+
for (i = 0; i < CEIL_REQUESTOR_COUNT; ++i) {
val = charge_ceil[port][i];
if (val != CHARGE_CEIL_NONE &&
@@ -544,6 +571,10 @@ static void charge_manager_get_best_charge_port(int *new_port,
*/
for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i)
for (j = 0; j < CHARGE_PORT_COUNT; ++j) {
+ /* Skip this port if it is not valid. */
+ if (!is_valid_port(j))
+ continue;
+
/*
* Skip this supplier if there is no
* available charge.
@@ -761,7 +792,7 @@ static void charge_manager_refresh(void)
if (updated_old_port != CHARGE_PORT_NONE)
save_log[updated_old_port] = 1;
- for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; ++i)
+ for (i = 0; i < board_get_usb_pd_port_count(); ++i)
if (save_log[i])
charge_manager_save_log(i);
#endif
@@ -814,6 +845,11 @@ static void charge_manager_make_change(enum charge_manager_change_type change,
int i;
int clear_override = 0;
+ if (!is_valid_port(port)) {
+ CPRINTS("%s: p%d invalid", __func__, port);
+ return;
+ }
+
/* Determine if this is a change which can affect charge status */
switch (change) {
case CHANGE_CHARGE:
@@ -1008,6 +1044,9 @@ void charge_manager_leave_safe_mode(void)
void charge_manager_set_ceil(int port, enum ceil_requestor requestor, int ceil)
{
+ if (!is_valid_port(port))
+ return;
+
if (charge_ceil[port][requestor] != ceil) {
charge_ceil[port][requestor] = ceil;
if (port == charge_port && charge_manager_is_seeded())
@@ -1138,7 +1177,7 @@ static int can_supply_max_current(int port)
if (!is_active_source(port))
/* Non-active ports don't get 3A */
return 0;
- for (p = 0; p < CONFIG_USB_PD_PORT_MAX_COUNT; p++) {
+ for (p = 0; p < board_get_usb_pd_port_count(); p++) {
if (p == port)
continue;
if (source_port_rp[p] ==
@@ -1166,7 +1205,7 @@ void charge_manager_source_port(int port, int enable)
return;
/* Set port limit according to policy */
- for (p = 0; p < CONFIG_USB_PD_PORT_MAX_COUNT; p++) {
+ for (p = 0; p < board_get_usb_pd_port_count(); p++) {
rp = can_supply_max_current(p) ?
CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT :
CONFIG_USB_PD_PULLUP;
@@ -1206,6 +1245,11 @@ static enum ec_status hc_pd_power_info(struct host_cmd_handler_args *args)
if (port == PD_POWER_CHARGING_PORT)
port = charge_port;
+ /*
+ * Not checking for invalid port here, because it might break existing
+ * contract with ectool users. The invalid ports will have the response
+ * voltage, current and power parameters set to 0.
+ */
if (port >= CHARGE_PORT_COUNT)
return EC_RES_INVALID_PARAM;
@@ -1309,7 +1353,7 @@ static void charge_manager_set_external_power_limit(int current_lim,
if (voltage_lim == EC_POWER_LIMIT_NONE)
voltage_lim = PD_MAX_VOLTAGE_MV;
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port) {
+ for (port = 0; port < board_get_usb_pd_port_count(); ++port) {
charge_manager_set_ceil(port, CEIL_REQUESTOR_HOST, current_lim);
pd_set_external_voltage_limit(port, voltage_lim);
}