diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2016-10-25 14:53:49 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-10-26 01:45:17 -0700 |
commit | fffea303b4a0892a51d6dad5e903d7869deff13c (patch) | |
tree | 0470ea2c2b725e45bd466262164141fdaaf5253c /common | |
parent | 6e82ee47298583dd1ac3e37e5f73f93ee17a45d9 (diff) | |
download | chrome-ec-fffea303b4a0892a51d6dad5e903d7869deff13c.tar.gz |
pd: fix contract negotiation with dynamic PDOs
When the board is using dynamic source PDOs, we need to ensure that we
are checking the incoming sink power request against the right set of
PDOs else we might reject a valid request (e.g. with high-power source,
we need to check against the 3.0A limit if we only have one port
connected).
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=gru
BUG=chrome-os-partner:56110
TEST=Connect Kevin to Caroline, ask Caroline to charge from the other
side and see it negotiating successfully a 5V/3A contract.
Change-Id: Ie1aa5746776be5946422bf07c08ae0f22faddd8c
Reviewed-on: https://chromium-review.googlesource.com/403088
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')
-rw-r--r-- | common/usb_pd_policy.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index b1c4e17c92..87f6fbe3d1 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -40,13 +40,21 @@ int pd_check_requested_voltage(uint32_t rdo) int idx = RDO_POS(rdo); uint32_t pdo; uint32_t pdo_ma; +#if defined(CONFIG_USB_PD_DYNAMIC_SRC_CAP) || \ + defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) + const uint32_t *src_pdo; + const int pdo_cnt = charge_manager_get_source_pdo(&src_pdo); +#else + const uint32_t *src_pdo = pd_src_pdo; + const int pdo_cnt = pd_src_pdo_cnt; +#endif /* Board specific check for this request */ - if (pd_board_check_request(rdo)) + if (pd_board_check_request(rdo, pdo_cnt)) return EC_ERROR_INVAL; /* check current ... */ - pdo = pd_src_pdo[idx - 1]; + pdo = src_pdo[idx - 1]; pdo_ma = (pdo & 0x3ff); if (op_ma > pdo_ma) return EC_ERROR_INVAL; /* too much op current */ @@ -61,15 +69,15 @@ int pd_check_requested_voltage(uint32_t rdo) return EC_SUCCESS; } -static int stub_pd_board_check_request(uint32_t rdo) +static int stub_pd_board_check_request(uint32_t rdo, int pdo_cnt) { int idx = RDO_POS(rdo); /* Check for invalid index */ - return (!idx || idx > pd_src_pdo_cnt) ? + return (!idx || idx > pdo_cnt) ? EC_ERROR_INVAL : EC_SUCCESS; } -int pd_board_check_request(uint32_t) +int pd_board_check_request(uint32_t, int) __attribute__((weak, alias("stub_pd_board_check_request"))); #ifdef CONFIG_USB_PD_DUAL_ROLE |