diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2016-08-22 17:11:27 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-01 19:52:35 -0700 |
commit | 02b80c49f473b872360a782f6a95c607c6734717 (patch) | |
tree | 4c4e9b53f264b81d57206a0035a3ce8adbf323a2 /common/charge_manager.c | |
parent | f4863ef03d76fc3923c49bccdfaf28b47ddc80f9 (diff) | |
download | chrome-ec-02b80c49f473b872360a782f6a95c607c6734717.tar.gz |
pd: manage total source current available
Add a policy to handle the case where the device can source the
`CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT` over one of its type-C port if
there is no sink connected on the other ones.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=chrome-os-partner:56110
TEST=manual: on Kevin, plug and unplug various devices on the 2 ports,
while measuring the type-C pull-up with Twinkie.
Change-Id: Id5961f04d0a1b1073f5ab340068efd9079918209
Reviewed-on: https://chromium-review.googlesource.com/373818
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'common/charge_manager.c')
-rw-r--r-- | common/charge_manager.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c index 13f85e38d0..becb6cc91d 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -4,6 +4,7 @@ */ #include "adc.h" +#include "atomic.h" #include "battery.h" #include "charge_manager.h" #include "charge_ramp.h" @@ -13,8 +14,10 @@ #include "hooks.h" #include "host_command.h" #include "system.h" +#include "tcpm.h" #include "timer.h" #include "usb_pd.h" +#include "usb_pd_tcpm.h" #include "util.h" #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) @@ -72,6 +75,10 @@ static int override_port = OVERRIDE_OFF; static int delayed_override_port = OVERRIDE_OFF; static timestamp_t delayed_override_deadline; +/* Bitmap of ports used as power source */ +static volatile uint32_t source_port_bitmap; +BUILD_ASSERT(sizeof(source_port_bitmap)*8 >= CONFIG_USB_PD_PORT_COUNT); + enum charge_manager_change_type { CHANGE_CHARGE, CHANGE_DUALROLE, @@ -885,6 +892,52 @@ int charge_manager_get_power_limit_uw(void) return current_ma * voltage_mv; } +#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT +void charge_manager_source_port(int port, int enable) +{ + uint32_t prev_bitmap = source_port_bitmap; + int p; + + if (enable) + atomic_or(&source_port_bitmap, 1 << port); + else + atomic_clear(&source_port_bitmap, 1 << port); + + /* No change, exit early. */ + if (prev_bitmap == source_port_bitmap) + return; + + /* Set port limit according to policy */ + for (p = 0; p < CONFIG_USB_PD_PORT_COUNT; p++) { + /* + * if we are the only active source port or there is none, + * advertise all the available power. + */ + int rp = (source_port_bitmap & ~(1 << p)) ? CONFIG_USB_PD_PULLUP + : CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT; + + tcpm_select_rp_value(p, rp); + pd_update_contract(p); + } +} + +int charge_manager_get_source_pdo(const uint32_t **src_pdo) +{ + int p; + int count = 0; + + /* count the number of connected sinks */ + for (p = 0; p < CONFIG_USB_PD_PORT_COUNT; p++) + if (source_port_bitmap & (1 << p)) + count++; + + /* send the maximum current if we are sourcing only on one port */ + *src_pdo = count <= 1 ? pd_src_pdo_max : pd_src_pdo; + + return count <= 1 ? pd_src_pdo_cnt : pd_src_pdo_max_cnt; +} +#endif /* CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT */ + #ifndef TEST_BUILD static int hc_pd_power_info(struct host_cmd_handler_args *args) { |