mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
charge_manager: add option to charge from dual-role devices
Add option to charge automatically from dual-role devices. This also changes the charge override behavior such that any new device attached will clear the override because any new source is a potential device we might charge from. BUG=chrome-os-partner:44958 BRANCH=smaug TEST=tested charge_manager unittests with CONFIG_CHARGE_MANAGER_DRP_CHARGING both defined and undefined Change-Id: Iac77ff0c501826d5fb5a9d50f88399ebc3955b87 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/297789 Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
@@ -140,7 +140,7 @@ static int charge_manager_is_seeded(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef TEST_CHARGE_MANAGER
|
||||
#ifndef TEST_BUILD
|
||||
/**
|
||||
* Fills passed power_info structure with current info about the passed port.
|
||||
*/
|
||||
@@ -273,7 +273,7 @@ static void charge_manager_fill_power_info(int port,
|
||||
r->meas.voltage_now = adc_read_channel(ADC_VBUS);
|
||||
}
|
||||
}
|
||||
#endif /* TEST_CHARGE_MANAGER */
|
||||
#endif /* TEST_BUILD */
|
||||
|
||||
#ifdef CONFIG_USB_PD_LOGGING
|
||||
/**
|
||||
@@ -384,6 +384,7 @@ static void charge_manager_get_best_charge_port(int *new_port,
|
||||
override_port != j)
|
||||
continue;
|
||||
|
||||
#ifndef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/*
|
||||
* Don't charge from a dual-role port unless
|
||||
* it is our override port.
|
||||
@@ -391,6 +392,7 @@ static void charge_manager_get_best_charge_port(int *new_port,
|
||||
if (dualrole_capability[j] != CAP_DEDICATED &&
|
||||
override_port != j)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
candidate_port_power =
|
||||
POWER(available_charge[i][j]);
|
||||
@@ -609,7 +611,9 @@ static void charge_manager_make_change(enum charge_manager_change_type change,
|
||||
* Ignore all except for transition to non-dualrole,
|
||||
* which may occur some time after we see a charge
|
||||
*/
|
||||
#ifndef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
if (dualrole_capability[port] != CAP_DEDICATED)
|
||||
#endif
|
||||
return;
|
||||
/* Clear override only if a charge is present on the port */
|
||||
for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i)
|
||||
@@ -626,9 +630,13 @@ static void charge_manager_make_change(enum charge_manager_change_type change,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Remove override when a dedicated charger is plugged */
|
||||
if (clear_override && override_port != port &&
|
||||
dualrole_capability[port] == CAP_DEDICATED) {
|
||||
/* Remove override when a charger is plugged */
|
||||
if (clear_override && override_port != port
|
||||
#ifndef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* only remove override when it's a dedicated charger */
|
||||
&& dualrole_capability[port] == CAP_DEDICATED
|
||||
#endif
|
||||
) {
|
||||
charge_manager_cleanup_override_port(override_port);
|
||||
override_port = OVERRIDE_OFF;
|
||||
if (delayed_override_port != OVERRIDE_OFF) {
|
||||
@@ -797,7 +805,7 @@ int charge_manager_get_active_charge_port(void)
|
||||
return charge_port;
|
||||
}
|
||||
|
||||
#ifndef TEST_CHARGE_MANAGER
|
||||
#ifndef TEST_BUILD
|
||||
static int hc_pd_power_info(struct host_cmd_handler_args *args)
|
||||
{
|
||||
const struct ec_params_usb_pd_power_info *p = args->params;
|
||||
@@ -816,7 +824,7 @@ static int hc_pd_power_info(struct host_cmd_handler_args *args)
|
||||
DECLARE_HOST_COMMAND(EC_CMD_USB_PD_POWER_INFO,
|
||||
hc_pd_power_info,
|
||||
EC_VER_MASK(0));
|
||||
#endif /* TEST_CHARGE_MANAGER */
|
||||
#endif /* TEST_BUILD */
|
||||
|
||||
static int hc_charge_port_override(struct host_cmd_handler_args *args)
|
||||
{
|
||||
|
||||
@@ -262,6 +262,9 @@
|
||||
/* Compile charge manager */
|
||||
#undef CONFIG_CHARGE_MANAGER
|
||||
|
||||
/* Allow charge manager to default to charging from dual-role partners */
|
||||
#undef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
|
||||
/* Handle the external power limit host command in charge manager */
|
||||
#undef CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
|
||||
|
||||
|
||||
@@ -37,13 +37,14 @@ test-list-host+=sbs_charging host_command
|
||||
test-list-host+=bklight_lid bklight_passthru interrupt timer_dos button
|
||||
test-list-host+=math_util sbs_charging_v2 battery_get_params_smart
|
||||
test-list-host+=lightbar inductive_charging usb_pd fan charge_manager
|
||||
test-list-host+=charge_ramp
|
||||
test-list-host+=charge_manager_drp_charging charge_ramp
|
||||
|
||||
battery_get_params_smart-y=battery_get_params_smart.o
|
||||
bklight_lid-y=bklight_lid.o
|
||||
bklight_passthru-y=bklight_passthru.o
|
||||
button-y=button.o
|
||||
charge_manager-y=charge_manager.o
|
||||
charge_manager_drp_charging-y=charge_manager.o
|
||||
charge_ramp-y+=charge_ramp.o
|
||||
console_edit-y=console_edit.o
|
||||
extpwr_gpio-y=extpwr_gpio.o
|
||||
|
||||
@@ -463,17 +463,21 @@ static int test_dual_role(void)
|
||||
/* Initialize table to no charge. */
|
||||
initialize_charge_table(0, 5000, 1000);
|
||||
|
||||
/*
|
||||
* Mark P0 as dual-role and set a charge. Verify that we don't charge
|
||||
* from the port.
|
||||
*/
|
||||
/* Mark P0 as dual-role and set a charge. */
|
||||
charge_manager_update_dualrole(0, CAP_DUALROLE);
|
||||
charge.current = 500;
|
||||
charge.voltage = 5000;
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST2, 0, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify we do charge from dual-role port */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
#else
|
||||
/* Verify we don't charge from dual-role port */
|
||||
TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE);
|
||||
TEST_ASSERT(active_charge_limit == 0);
|
||||
#endif
|
||||
|
||||
/* Mark P0 as the override port, verify that we now charge. */
|
||||
charge_manager_set_override(0);
|
||||
@@ -482,12 +486,17 @@ static int test_dual_role(void)
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
TEST_ASSERT(pd_get_role(0) == PD_ROLE_SINK);
|
||||
|
||||
/* Remove override and verify we go back to not charging */
|
||||
/* Remove override and verify we go back to previous state */
|
||||
charge_manager_set_override(OVERRIDE_OFF);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
#else
|
||||
TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE);
|
||||
TEST_ASSERT(active_charge_limit == 0);
|
||||
TEST_ASSERT(pd_get_role(0) == PD_ROLE_SOURCE);
|
||||
#endif
|
||||
|
||||
/* Mark P0 as the override port, verify that we again charge. */
|
||||
charge_manager_set_override(0);
|
||||
@@ -530,9 +539,14 @@ static int test_dual_role(void)
|
||||
charge.current = 400;
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST6, 1, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 600);
|
||||
#else
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
TEST_ASSERT(active_charge_limit == 400);
|
||||
TEST_ASSERT(pd_get_role(0) == PD_ROLE_SOURCE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Verify the port is handled normally if the dual-role source is
|
||||
@@ -548,8 +562,8 @@ static int test_dual_role(void)
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
|
||||
/*
|
||||
* Verify that we charge from the dedicated port if a dual-role
|
||||
* source is also attached.
|
||||
* Test one port connected to dedicated charger and one connected
|
||||
* to dual-role device.
|
||||
*/
|
||||
charge_manager_update_dualrole(0, CAP_DUALROLE);
|
||||
charge.current = 0;
|
||||
@@ -559,9 +573,19 @@ static int test_dual_role(void)
|
||||
charge.current = 200;
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST6, 1, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify we charge from port with higher priority */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
#else
|
||||
/*
|
||||
* Verify that we charge from the dedicated port if a dual-role
|
||||
* source is also attached.
|
||||
*/
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
TEST_ASSERT(active_charge_limit == 200);
|
||||
TEST_ASSERT(pd_get_role(0) == PD_ROLE_SOURCE);
|
||||
#endif
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
@@ -605,19 +629,23 @@ static int test_unknown_dualrole_capability(void)
|
||||
struct charge_port_info charge;
|
||||
|
||||
/* Initialize table to no charge. */
|
||||
initialize_charge_table(0, 5000, 1000);
|
||||
initialize_charge_table(0, 5000, 2000);
|
||||
TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE);
|
||||
|
||||
/*
|
||||
* Set a charge on P0 with unknown dualrole capability,
|
||||
* verify that we don't charge from the port.
|
||||
*/
|
||||
/* Set a charge on P0 with unknown dualrole capability, */
|
||||
charge.current = 500;
|
||||
charge.voltage = 5000;
|
||||
charge_manager_update_dualrole(0, CAP_UNKNOWN);
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST2, 0, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify we do charge from that port */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 500);
|
||||
#else
|
||||
/* Verify that we don't charge from the port. */
|
||||
TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE);
|
||||
#endif
|
||||
|
||||
/* Toggle to dedicated and verify port becomes active. */
|
||||
charge_manager_update_dualrole(0, CAP_DEDICATED);
|
||||
@@ -629,14 +657,24 @@ static int test_unknown_dualrole_capability(void)
|
||||
charge_manager_update_dualrole(1, CAP_DUALROLE);
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST2, 1, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
TEST_ASSERT(active_charge_limit == 1000);
|
||||
#else
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
#endif
|
||||
|
||||
/* Remove charger on port 0 */
|
||||
charge.current = 0;
|
||||
charge_manager_update_dualrole(0, CAP_UNKNOWN);
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST2, 0, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
TEST_ASSERT(active_charge_limit == 1000);
|
||||
#else
|
||||
TEST_ASSERT(active_charge_port == CHARGE_PORT_NONE);
|
||||
#endif
|
||||
|
||||
/* Set override to charge on port 1 */
|
||||
charge_manager_set_override(1);
|
||||
@@ -651,26 +689,43 @@ static int test_unknown_dualrole_capability(void)
|
||||
wait_for_charge_manager_refresh();
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
|
||||
/*
|
||||
* Insert UNKNOWN capability charger on port 0, verify that override
|
||||
* is still kept.
|
||||
*/
|
||||
/* Insert UNKNOWN capability charger on port 0 */
|
||||
charge_manager_update_dualrole(0, CAP_UNKNOWN);
|
||||
charge.current = 2000;
|
||||
charge_manager_update_charge(CHARGE_SUPPLIER_TEST2, 0, &charge);
|
||||
wait_for_charge_manager_refresh();
|
||||
wait_for_charge_manager_refresh();
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify override is removed */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
TEST_ASSERT(active_charge_limit == 2000);
|
||||
#else
|
||||
/* Verify override is still kept */
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
#endif
|
||||
|
||||
/* Toggle to dualrole, verify that override is still kept. */
|
||||
/* Toggle to dualrole */
|
||||
charge_manager_update_dualrole(0, CAP_DUALROLE);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify no change */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
#else
|
||||
/* Verify override is still kept */
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
#endif
|
||||
|
||||
/* Toggle to dedicated, verify that override is removed. */
|
||||
/* Toggle to dedicated */
|
||||
charge_manager_update_dualrole(0, CAP_UNKNOWN);
|
||||
wait_for_charge_manager_refresh();
|
||||
#ifdef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
/* Verify no change */
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
#else
|
||||
/* Verify override is still kept */
|
||||
TEST_ASSERT(active_charge_port == 1);
|
||||
#endif
|
||||
charge_manager_update_dualrole(0, CAP_DEDICATED);
|
||||
wait_for_charge_manager_refresh();
|
||||
TEST_ASSERT(active_charge_port == 0);
|
||||
|
||||
17
test/charge_manager_drp_charging.tasklist
Normal file
17
test/charge_manager_drp_charging.tasklist
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of enabled tasks in the priority order
|
||||
*
|
||||
* The first one has the lowest priority.
|
||||
*
|
||||
* For each task, use the macro TASK_TEST(n, r, d, s) where :
|
||||
* 'n' in the name of the task
|
||||
* 'r' in the main routine of the task
|
||||
* 'd' in an opaque parameter passed to the routine at startup
|
||||
* 's' is the stack size in bytes; must be a multiple of 8
|
||||
*/
|
||||
#define CONFIG_TEST_TASK_LIST /* No test task */
|
||||
@@ -118,6 +118,14 @@ int bd99992gw_get_temp(uint16_t adc);
|
||||
|
||||
#ifdef TEST_CHARGE_MANAGER
|
||||
#define CONFIG_CHARGE_MANAGER
|
||||
#undef CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
#define CONFIG_USB_PD_DUAL_ROLE
|
||||
#define CONFIG_USB_PD_PORT_COUNT 2
|
||||
#endif
|
||||
|
||||
#ifdef TEST_CHARGE_MANAGER_DRP_CHARGING
|
||||
#define CONFIG_CHARGE_MANAGER
|
||||
#define CONFIG_CHARGE_MANAGER_DRP_CHARGING
|
||||
#define CONFIG_USB_PD_DUAL_ROLE
|
||||
#define CONFIG_USB_PD_PORT_COUNT 2
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user