static int test_request(void) { uint32_t expected_rdo = RDO_FIXED(1, 900, 900, RDO_CAP_MISMATCH); plug_in_source(0, 0); task_wake(PD_PORT_TO_TASK_ID(0)); task_wait_event(2 * PD_T_CC_DEBOUNCE + 100 * MSEC); TEST_ASSERT(pd_port[0].polarity == 0); /* We're in SNK_DISCOVERY now. Let's send the source cap. */ simulate_source_cap(0); task_wait_event(30 * MSEC); TEST_ASSERT(verify_goodcrc(0, PD_ROLE_SINK, pd_port[0].msg_rx_id)); /* Wait for the power request */ task_wake(PD_PORT_TO_TASK_ID(0)); task_wait_event(35 * MSEC); /* tSenderResponse: 24~30 ms */ inc_rx_id(0); /* Process the request */ TEST_ASSERT(pd_test_tx_msg_verify_sop(0)); TEST_ASSERT(pd_test_tx_msg_verify_short(0, PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK, PD_ROLE_UFP, pd_port[0].msg_tx_id, 1))); TEST_ASSERT(pd_test_tx_msg_verify_word(0, expected_rdo)); TEST_ASSERT(pd_test_tx_msg_verify_crc(0)); TEST_ASSERT(pd_test_tx_msg_verify_eop(0)); inc_tx_id(0); /* We're done */ unplug(0); return EC_SUCCESS; }
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo) { int i; int sel_mv; int max_uw = 0; int max_i = -1; /* Get max power */ for (i = 0; i < cnt; i++) { int uw; int mv = ((src_caps[i] >> 10) & 0x3FF) * 50; if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { uw = 250000 * (src_caps[i] & 0x3FF); } else { int ma = (src_caps[i] & 0x3FF) * 10; uw = ma * mv; } if ((uw > max_uw) && (mv <= max_mv)) { max_i = i; max_uw = uw; sel_mv = mv; } } if (max_i < 0) return -EC_ERROR_UNKNOWN; /* request all the power ... */ if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { int uw = 250000 * (src_caps[i] & 0x3FF); *rdo = RDO_BATT(max_i + 1, uw/2, uw, 0); ccprintf("Request [%d] %dV %d/%d mW\n", max_i, sel_mv/1000, uw/1000, uw/1000); } else { int ma = 10 * (src_caps[max_i] & 0x3FF); *rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0); ccprintf("Request [%d] %dV %d/%d mA\n", max_i, sel_mv/1000, max_i, ma/2, ma); } return EC_SUCCESS; }
int pd_choose_voltage_common(int cnt, uint32_t *src_caps, uint32_t *rdo, uint32_t *curr_limit, uint32_t *supply_voltage, int choose_min) { int i; int sel_mv; int max_uw = 0; int max_ma; int max_i = -1; int max; uint32_t flags; /* Get max power */ for (i = 0; i < cnt; i++) { int uw; int mv = ((src_caps[i] >> 10) & 0x3FF) * 50; if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { uw = 250000 * (src_caps[i] & 0x3FF); } else { int ma = (src_caps[i] & 0x3FF) * 10; uw = ma * mv; } if ((uw > max_uw) && (mv <= max_mv)) { max_i = i; max_uw = uw; sel_mv = mv; } /* * Choose the first entry if seaching for minimum, which will * always be vSafe5V. */ if (choose_min) break; } if (max_i < 0) return -EC_ERROR_UNKNOWN; /* build rdo for desired power */ if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { int uw = 250000 * (src_caps[max_i] & 0x3FF); max = MIN(1000 * uw, MAX_POWER_MW); flags = (max < OPERATING_POWER_MW) ? RDO_CAP_MISMATCH : 0; max_ma = 1000 * max / sel_mv; *rdo = RDO_BATT(max_i + 1, max, max, flags); CPRINTF("Request [%d] %dV %dmW", max_i, sel_mv/1000, max); } else { int ma = 10 * (src_caps[max_i] & 0x3FF); /* * If we're choosing the minimum charge mode, limit our current * to what we can set with ilim PWM (500mA) */ max = MIN(ma, choose_min ? CONFIG_CHARGER_INPUT_CURRENT : MAX_CURRENT_MA); flags = (max * sel_mv) < (1000 * OPERATING_POWER_MW) ? RDO_CAP_MISMATCH : 0; max_ma = max; *rdo = RDO_FIXED(max_i + 1, max, max, flags); CPRINTF("Request [%d] %dV %dmA", max_i, sel_mv/1000, max); } /* Mismatch bit set if less power offered than the operating power */ if (flags & RDO_CAP_MISMATCH) CPRINTF(" Mismatch"); CPRINTF("\n"); *curr_limit = max_ma; *supply_voltage = sel_mv; return EC_SUCCESS; }