summaryrefslogtreecommitdiff
path: root/common/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usb_pd_policy.c')
-rw-r--r--common/usb_pd_policy.c141
1 files changed, 11 insertions, 130 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 554cf86151..6e29cb34aa 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -22,6 +22,7 @@
#include "timer.h"
#include "util.h"
#include "usb_api.h"
+#include "usb_common.h"
#include "usb_pd.h"
#include "usbc_ppc.h"
#include "version.h"
@@ -104,144 +105,23 @@ 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 */
-int pd_find_pdo_index(int port, int max_mv, uint32_t *selected_pdo)
+const uint32_t * const pd_get_src_caps(int port)
{
- int i, uw, mv;
- 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 < pd_src_cap_cnt[port]; i++) {
- /* its an unsupported Augmented PDO (PD3.0) */
- if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED)
- continue;
-
- mv = ((src_caps[i] >> 10) & 0x3FF) * 50;
- /* Skip invalid voltage */
- if (!mv)
- continue;
- /* Skip any voltage not supported by this board */
- if (!pd_is_valid_input_voltage(mv))
- continue;
-
- if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
- uw = 250000 * (src_caps[i] & 0x3FF);
- } else {
- int ma = (src_caps[i] & 0x3FF) * 10;
- ma = MIN(ma, PD_MAX_CURRENT_MA);
- uw = ma * mv;
- }
+ ASSERT(port < CONFIG_USB_PD_PORT_COUNT);
- if (mv > max_mv)
- continue;
- uw = MIN(uw, PD_MAX_POWER_MW * 1000);
- prefer_cur = 0;
-
- /* Apply special rules in case of 'tie' */
-#ifdef PD_PREFER_LOW_VOLTAGE
- if (uw == cur_uw && mv < cur_mv)
- prefer_cur = 1;
-#elif defined(PD_PREFER_HIGH_VOLTAGE)
- if (uw == cur_uw && mv > cur_mv)
- prefer_cur = 1;
-#endif
- /* Prefer higher power, except for tiebreaker */
- if (uw > cur_uw || prefer_cur) {
- ret = i;
- cur_uw = uw;
- cur_mv = mv;
- }
- }
-
- if (selected_pdo)
- *selected_pdo = src_caps[ret];
-
- return ret;
+ return pd_src_caps[port];
}
-void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv)
+uint8_t pd_get_src_cap_cnt(int port)
{
- int max_ma, uw;
+ ASSERT(port < CONFIG_USB_PD_PORT_COUNT);
- *mv = ((pdo >> 10) & 0x3FF) * 50;
-
- if (*mv == 0) {
- CPRINTF("ERR:PDO mv=0\n");
- *ma = 0;
- return;
- }
-
- if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
- uw = 250000 * (pdo & 0x3FF);
- max_ma = 1000 * MIN(1000 * uw, PD_MAX_POWER_MW) / *mv;
- } else {
- max_ma = 10 * (pdo & 0x3FF);
- max_ma = MIN(max_ma, PD_MAX_POWER_MW * 1000 / *mv);
- }
-
- *ma = MIN(max_ma, PD_MAX_CURRENT_MA);
+ return pd_src_cap_cnt[port];
}
-void pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv,
- enum pd_request_type req_type)
+uint32_t get_max_request_mv(void)
{
- 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) {
- /* src cap 0 should be vSafe5V */
- pdo_index = 0;
- pdo = pd_src_caps[port][0];
- } else {
- /* find pdo index for max voltage we can request */
- pdo_index = pd_find_pdo_index(port, max_request_mv, &pdo);
- }
-
- 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))
- flags |= RDO_CAP_MISMATCH;
-
-#ifdef CONFIG_USB_PD_GIVE_BACK
- /* Tell source we are give back capable. */
- flags |= RDO_GIVE_BACK;
-
- /*
- * BATTERY PDO: Inform the source that the sink will reduce
- * power to this minimum level on receipt of a GotoMin Request.
- */
- max_or_min_mw = PD_MIN_POWER_MW;
-
- /*
- * FIXED or VARIABLE PDO: Inform the source that the sink will reduce
- * current to this minimum level on receipt of a GotoMin Request.
- */
- max_or_min_ma = PD_MIN_CURRENT_MA;
-#else
- /*
- * Can't give back, so set maximum current and power to operating
- * level.
- */
- max_or_min_ma = *ma;
- max_or_min_mw = uw / 1000;
-#endif
-
- 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 {
- *rdo = RDO_FIXED(pdo_index + 1, *ma, max_or_min_ma, flags);
- }
+ return max_request_mv;
}
void pd_process_source_cap(int port, int cnt, uint32_t *src_caps)
@@ -257,7 +137,8 @@ void pd_process_source_cap(int port, int cnt, uint32_t *src_caps)
#ifdef CONFIG_CHARGE_MANAGER
/* Get max power info that we could request */
- pd_find_pdo_index(port, PD_MAX_VOLTAGE_MV, &pdo);
+ pd_find_pdo_index(pd_get_src_cap_cnt(port), pd_get_src_caps(port),
+ PD_MAX_VOLTAGE_MV, &pdo);
pd_extract_pdo_power(pdo, &ma, &mv);
/* Set max. limit, but apply 500mA ceiling */