From 34086a6b71a9babd15f73668b12b04433a8165a5 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Tue, 17 Oct 2017 09:07:29 -0700 Subject: cleanup: pd: Make PDO find / extract functions non-static Allow other modules to call pd_find_pdo_index() / pd_extract_pdo_power() in order to get information about current PDOs. BUG=chromium:775542 TEST=Manual on kevin, verify 20V negotiation with zinger still works. BRANCH=servo Change-Id: I1861a0226501bda13e7d576d0971d841da9d2b74 Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/724682 Commit-Ready: Shawn N Tested-by: Shawn N Reviewed-by: Vincent Palatin Reviewed-on: https://chromium-review.googlesource.com/740003 --- common/usb_pd_policy.c | 71 +++++++++++++++++++++++------------------------- common/usb_pd_protocol.c | 21 ++------------ include/usb_pd.h | 27 +++++++++++++++--- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 18d8860773..f7d9eebe7d 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -81,31 +81,27 @@ int pd_board_check_request(uint32_t, int) __attribute__((weak, alias("stub_pd_board_check_request"))); #ifdef CONFIG_USB_PD_DUAL_ROLE +/* Last received source cap */ +static uint32_t pd_src_caps[CONFIG_USB_PD_PORT_COUNT][PDO_MAX_OBJECTS]; +static uint8_t pd_src_cap_cnt[CONFIG_USB_PD_PORT_COUNT]; + /* Cap on the max voltage requested as a sink (in millivolts) */ static unsigned max_request_mv = PD_MAX_VOLTAGE_MV; /* no cap */ -/** - * Find PDO index that offers the most amount of power and stays within - * max_mv voltage. - * - * @param cnt the number of Power Data Objects. - * @param src_caps Power Data Objects representing the source capabilities. - * @param max_mv maximum voltage (or -1 if no limit) - * @return index of PDO within source cap packet - */ -static int pd_find_pdo_index(int cnt, uint32_t *src_caps, int max_mv) +int pd_find_pdo_index(int port, int max_mv, uint32_t *selected_pdo) { int i, uw, mv, ma; - int ret = -1; + int ret = 0; int __attribute__((unused)) cur_mv = 0; int cur_uw = 0; int prefer_cur; + const uint32_t *src_caps = pd_src_caps[port]; /* max voltage is always limited by this boards max request */ max_mv = MIN(max_mv, PD_MAX_VOLTAGE_MV); /* Get max power that is under our max voltage input */ - for (i = 0; i < cnt; i++) { + for (i = 0; i < pd_src_cap_cnt[port]; i++) { /* its an unsupported Augmented PDO (PD3.0) */ if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) continue; @@ -146,19 +142,17 @@ static int pd_find_pdo_index(int cnt, uint32_t *src_caps, int max_mv) cur_mv = mv; } } + + if (selected_pdo) + *selected_pdo = src_caps[ret]; + return ret; } -/** - * Extract power information out of a Power Data Object (PDO) - * - * @pdo Power data object - * @ma Current we can request from that PDO - * @mv Voltage of the PDO - */ -static void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv) +void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv) { int max_ma, uw; + *mv = ((pdo >> 10) & 0x3FF) * 50; if (*mv == 0) { @@ -178,26 +172,25 @@ static void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv) *ma = MIN(max_ma, PD_MAX_CURRENT_MA); } -int pd_build_request(int cnt, uint32_t *src_caps, uint32_t *rdo, - uint32_t *ma, uint32_t *mv, enum pd_request_type req_type) +int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv, + enum pd_request_type req_type) { + uint32_t pdo; int pdo_index, flags = 0; int uw; int max_or_min_ma; int max_or_min_mw; - if (req_type == PD_REQUEST_VSAFE5V) + if (req_type == PD_REQUEST_VSAFE5V) { /* src cap 0 should be vSafe5V */ pdo_index = 0; - else + pdo = pd_src_caps[port][0]; + } else { /* find pdo index for max voltage we can request */ - pdo_index = pd_find_pdo_index(cnt, src_caps, max_request_mv); - - /* If could not find desired pdo_index, then return error */ - if (pdo_index == -1) - return -EC_ERROR_UNKNOWN; + pdo_index = pd_find_pdo_index(port, max_request_mv, &pdo); + } - pd_extract_pdo_power(src_caps[pdo_index], ma, mv); + pd_extract_pdo_power(pdo, ma, mv); uw = *ma * *mv; /* Mismatch bit set if less power offered than the operating power */ if (uw < (1000 * PD_OPERATING_POWER_MW)) @@ -227,7 +220,7 @@ int pd_build_request(int cnt, uint32_t *src_caps, uint32_t *rdo, max_or_min_mw = uw / 1000; #endif - if ((src_caps[pdo_index] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { + if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { int mw = uw / 1000; *rdo = RDO_BATT(pdo_index + 1, mw, max_or_min_mw, flags); } else { @@ -239,14 +232,18 @@ int pd_build_request(int cnt, uint32_t *src_caps, uint32_t *rdo, void pd_process_source_cap(int port, int cnt, uint32_t *src_caps) { #ifdef CONFIG_CHARGE_MANAGER - uint32_t ma, mv; - int pdo_index; + uint32_t ma, mv, pdo; +#endif + int i; + + pd_src_cap_cnt[port] = cnt; + for (i = 0; i < cnt; i++) + pd_src_caps[port][i] = *src_caps++; +#ifdef CONFIG_CHARGE_MANAGER /* Get max power info that we could request */ - pdo_index = pd_find_pdo_index(cnt, src_caps, PD_MAX_VOLTAGE_MV); - if (pdo_index < 0) - pdo_index = 0; - pd_extract_pdo_power(src_caps[pdo_index], &ma, &mv); + pd_find_pdo_index(port, PD_MAX_VOLTAGE_MV, &pdo); + pd_extract_pdo_power(pdo, &ma, &mv); /* Set max. limit, but apply 500mA ceiling */ charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, PD_MIN_MA); diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 0485f6316e..f550492108 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -99,10 +99,6 @@ enum vdm_states { /* Port dual-role state */ enum pd_dual_role_states drp_state = CONFIG_USB_PD_INITIAL_DRP_STATE; -/* Last received source cap */ -static uint32_t pd_src_caps[CONFIG_USB_PD_PORT_COUNT][PDO_MAX_OBJECTS]; -static int pd_src_cap_cnt[CONFIG_USB_PD_PORT_COUNT]; - /* Enable variable for Try.SRC states */ static uint8_t pd_try_src_enable; #endif @@ -575,15 +571,6 @@ void pd_soft_reset(void) } #ifdef CONFIG_USB_PD_DUAL_ROLE -static void pd_store_src_cap(int port, int cnt, uint32_t *src_caps) -{ - int i; - - pd_src_cap_cnt[port] = cnt; - for (i = 0; i < cnt; i++) - pd_src_caps[port][i] = *src_caps++; -} - /* * Request desired charge voltage from source. * Returns EC_SUCCESS on success or non-zero on failure. @@ -613,8 +600,7 @@ static int pd_send_request_msg(int port, int always_send_request) * If this port is not actively charging or we are not allowed to * request the max voltage, then select vSafe5V */ - res = pd_build_request(pd_src_cap_cnt[port], pd_src_caps[port], - &rdo, &curr_limit, &supply_voltage, + res = pd_build_request(port, &rdo, &curr_limit, &supply_voltage, charging && max_request_allowed ? PD_REQUEST_MAX : PD_REQUEST_VSAFE5V); @@ -727,12 +713,11 @@ static void handle_data_request(int port, uint16_t head, /* Port partner is now known to be PD capable */ pd[port].flags |= PD_FLAGS_PREVIOUS_PD_CONN; - pd_store_src_cap(port, cnt, payload); /* src cap 0 should be fixed PDO */ pd_update_pdo_flags(port, payload[0]); - pd_process_source_cap(port, pd_src_cap_cnt[port], - pd_src_caps[port]); + pd_process_source_cap(port, cnt, payload); + /* Source will resend source cap on failure */ pd_send_request_msg(port, 1); } diff --git a/include/usb_pd.h b/include/usb_pd.h index 5aa517e679..c1161dcaee 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -885,16 +885,15 @@ enum pd_request_type { /** * Decide which PDO to choose from the source capabilities. * - * @param cnt the number of Power Data Objects. - * @param src_caps Power Data Objects representing the source capabilities. + * @param port USB-C port number * @param rdo requested Request Data Object. * @param ma selected current limit (stored on success) * @param mv selected supply voltage (stored on success) * @param req_type request type * @return <0 if invalid, else EC_SUCCESS */ -int pd_build_request(int cnt, uint32_t *src_caps, uint32_t *rdo, - uint32_t *ma, uint32_t *mv, enum pd_request_type req_type); +int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv, + enum pd_request_type req_type); /** * Check if max voltage request is allowed (only used if @@ -913,6 +912,26 @@ int pd_is_max_request_allowed(void); */ void pd_process_source_cap(int port, int cnt, uint32_t *src_caps); +/** + * Find PDO index that offers the most amount of power and stays within + * max_mv voltage. + * + * @param port USB-C port number + * @param max_mv maximum voltage (or -1 if no limit) + * @param pdo raw pdo corresponding to index, or index 0 on error (output) + * @return index of PDO within source cap packet + */ +int pd_find_pdo_index(int port, int max_mv, uint32_t *pdo); + +/** + * Extract power information out of a Power Data Object (PDO) + * + * @param pdo raw pdo to extract + * @param ma current of the PDO (output) + * @param mv voltage of the PDO (output) + */ +void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv); + /** * Reduce the sink power consumption to a minimum value. * -- cgit v1.2.1