diff options
author | Jeremy Bettis <jbettis@google.com> | 2021-04-06 12:51:02 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-12 20:14:02 +0000 |
commit | d7917d3f795e99c9173c36ebe7af7295eb53571d (patch) | |
tree | b5db5a5333830c20534b412d5e4362cd4c5ca0cc /common/usb_pd_dual_role.c | |
parent | 8ef4ad9400e9ae4e56e832f8bb9cef232bc9a1fe (diff) | |
download | chrome-ec-d7917d3f795e99c9173c36ebe7af7295eb53571d.tar.gz |
ec: Parse battery and augmented PDOs correctly.
Fixes pd_extract_pdo_power() to output the correct voltage and current
for non-fixed PDOs. Add unit test.
BRANCH=none
BUG=b:178484932
TEST=added
Signed-off-by: Jeremy Bettis <jbettis@google.com>
Change-Id: I6de55be3c753e01ef26424896c6fd41b8df8f94b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2805226
Commit-Queue: Jeremy Bettis <jbettis@chromium.org>
Tested-by: Jeremy Bettis <jbettis@chromium.org>
Reviewed-by: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'common/usb_pd_dual_role.c')
-rw-r--r-- | common/usb_pd_dual_role.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/common/usb_pd_dual_role.c b/common/usb_pd_dual_role.c index 61bce77129..2ad0b99125 100644 --- a/common/usb_pd_dual_role.c +++ b/common/usb_pd_dual_role.c @@ -157,32 +157,40 @@ int pd_find_pdo_index(uint32_t src_cap_cnt, const uint32_t * const src_caps, void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *max_mv, uint32_t *min_mv) { - uint32_t max_ma, uw; - - if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) { - max_ma = 50 * (pdo & GENMASK(6, 0)); - *min_mv = 100 * ((pdo & GENMASK(15, 8)) >> 8); - *max_mv = 100 * ((pdo & GENMASK(24, 17)) >> 17); - max_ma = MIN(max_ma, PD_MAX_POWER_MW * 1000 / *min_mv); - *ma = MIN(max_ma, PD_MAX_CURRENT_MA); - return; + int max_ma, mw; + + if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_FIXED) { + *max_mv = PDO_FIXED_VOLTAGE(pdo); + *min_mv = *max_mv; + } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) { + *max_mv = PDO_AUG_MAX_VOLTAGE(pdo); + *min_mv = PDO_AUG_MIN_VOLTAGE(pdo); + } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_VARIABLE) { + *max_mv = PDO_VAR_MAX_VOLTAGE(pdo); + *min_mv = PDO_VAR_MIN_VOLTAGE(pdo); + } else { + *max_mv = PDO_BATT_MAX_VOLTAGE(pdo); + *min_mv = PDO_BATT_MIN_VOLTAGE(pdo); } - *max_mv = ((pdo >> 10) & 0x3FF) * 50; if (*max_mv == 0) { *ma = 0; *min_mv = 0; return; } - if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { - uw = 250000 * (pdo & 0x3FF); - max_ma = 1000 * MIN(1000 * uw, PD_MAX_POWER_MW) / *max_mv; + + if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_FIXED) { + max_ma = PDO_FIXED_CURRENT(pdo); + } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) { + max_ma = PDO_AUG_MAX_CURRENT(pdo); + } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_VARIABLE) { + max_ma = PDO_VAR_MAX_CURRENT(pdo); } else { - max_ma = 10 * (pdo & 0x3FF); - max_ma = MIN(max_ma, PD_MAX_POWER_MW * 1000 / *max_mv); + mw = PDO_BATT_MAX_POWER(pdo); + max_ma = 1000 * mw / *min_mv; } + max_ma = MIN(max_ma, PD_MAX_POWER_MW * 1000 / *min_mv); *ma = MIN(max_ma, PD_MAX_CURRENT_MA); - *min_mv = *max_mv; } void pd_build_request(int32_t vpd_vdo, uint32_t *rdo, uint32_t *ma, |