pd: for request message, add operational and max current

For request message, add the operational and max current for each
board. If the requested power is less than the operational power
required, then set mismatch bit.

BUG=none
BRANCH=samus
TEST=make buildall. load onto samus, plug in zinger and see
that request 20V, operational current 3000mA and max
current of 3000mA.

Change-Id: I4df45d88b7e060f66ff5b806f6fe30803f1afcf7
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/227393
Reviewed-by: Todd Broch <tbroch@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Alec Berg
2014-11-04 13:00:22 -08:00
committed by chrome-internal-fetch
parent e35494e4ac
commit 8a9d0cae28
10 changed files with 214 additions and 63 deletions

View File

@@ -25,6 +25,11 @@
const uint32_t pd_src_pdo[] = {};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 1000
#define MAX_POWER_MW 1500
#define MAX_CURRENT_MA 300
/* Fake PDOs : we just want our pre-defined voltages */
const uint32_t pd_snk_pdo[] = {
PDO_FIXED(5000, 500, 0),
@@ -43,6 +48,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
int i;
int ma;
int set_mv = select_mv;
int max;
uint32_t flags;
/* Default to 5V */
if (set_mv <= 0)
@@ -58,11 +65,19 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired power */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
*curr_limit = ma;
max = MIN(ma, MAX_CURRENT_MA);
flags = (max * set_mv) < (1000 * OPERATING_POWER_MW) ?
RDO_CAP_MISMATCH : 0;
*rdo = RDO_FIXED(i + 1, max, max, 0);
CPRINTF("Request [%d] %dV %dmA", i, set_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;
*supply_voltage = set_mv;
return EC_SUCCESS;
}

View File

@@ -21,6 +21,11 @@
/* Acceptable margin between requested VBUS and measured value */
#define MARGIN_MV 400 /* mV */
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 1000
#define MAX_POWER_MW 1500
#define MAX_CURRENT_MA 300
/* we are not acting as a source */
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
@@ -44,6 +49,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
int i;
int ma;
int set_mv = select_mv;
int max;
uint32_t flags;
/* Default to 5V */
if (set_mv <= 0)
@@ -59,11 +66,19 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired power */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
*curr_limit = ma;
max = MIN(ma, MAX_CURRENT_MA);
flags = (max * set_mv) < (1000 * OPERATING_POWER_MW) ?
RDO_CAP_MISMATCH : 0;
*rdo = RDO_FIXED(i + 1, max, max, 0);
CPRINTF("Request [%d] %dV %dmA", i, set_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;
*supply_voltage = set_mv;
return EC_SUCCESS;
}

View File

@@ -25,6 +25,11 @@
const uint32_t pd_src_pdo[] = {};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 1000
#define MAX_POWER_MW 1500
#define MAX_CURRENT_MA 300
/* Fake PDOs : we just want our pre-defined voltages */
const uint32_t pd_snk_pdo[] = {
PDO_FIXED(5000, 500, 0),
@@ -43,6 +48,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
int i;
int ma;
int set_mv = select_mv;
int max;
uint32_t flags;
/* Default to 5V */
if (set_mv <= 0)
@@ -58,11 +65,19 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired power */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
*curr_limit = ma;
max = MIN(ma, MAX_CURRENT_MA);
flags = (max * set_mv) < (1000 * OPERATING_POWER_MW) ?
RDO_CAP_MISMATCH : 0;
*rdo = RDO_FIXED(i + 1, max, max, 0);
CPRINTF("Request [%d] %dV %dmA", i, set_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;
*supply_voltage = set_mv;
return EC_SUCCESS;
}

View File

@@ -11,6 +11,11 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 15000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 900, PDO_FIXED_EXTERNAL),
};
@@ -32,7 +37,10 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
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++) {
@@ -53,20 +61,31 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (max_i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired power */
if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
int uw = 250000 * (src_caps[max_i] & 0x3FF);
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
*curr_limit = uw/sel_mv;
CPRINTF("Request [%d] %dV %dmW\n",
max_i, sel_mv/1000, uw/1000);
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);
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
*curr_limit = ma;
CPRINTF("Request [%d] %dV %dmA\n",
max_i, sel_mv/1000, ma);
max = MIN(ma, 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;
}

View File

@@ -21,6 +21,11 @@
/* Acceptable margin between requested VBUS and measured value */
#define MARGIN_MV 400 /* mV */
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 5000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
/* Source PDOs */
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
@@ -63,6 +68,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
int i;
int ma;
int set_mv = select_mv;
int max;
uint32_t flags;
/* Default to 5V */
if (set_mv <= 0)
@@ -78,11 +85,19 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired power */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
*curr_limit = ma;
max = MIN(ma, MAX_CURRENT_MA);
flags = (max * set_mv) < (1000 * OPERATING_POWER_MW) ?
RDO_CAP_MISMATCH : 0;
*rdo = RDO_FIXED(i + 1, max, max, 0);
CPRINTF("Request [%d] %dV %dmA", i, set_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;
*supply_voltage = set_mv;
return EC_SUCCESS;
}

View File

@@ -18,6 +18,11 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 10000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
};
@@ -41,6 +46,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
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++) {
@@ -61,20 +68,30 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (max_i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* 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_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
CPRINTF("Request [%d] %dV %dmW\n",
max_i, sel_mv/1000, uw/1000);
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);
max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n",
max_i, sel_mv/1000, ma);
max = MIN(ma, 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;

View File

@@ -18,6 +18,11 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 10000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
};
@@ -41,6 +46,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
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++) {
@@ -61,20 +68,30 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (max_i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* 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_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
CPRINTF("Request [%d] %dV %dmW\n",
max_i, sel_mv/1000, uw/1000);
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);
max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n",
max_i, sel_mv/1000, ma);
max = MIN(ma, 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;

View File

@@ -19,6 +19,11 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 15000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
};
@@ -42,6 +47,8 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
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++) {
@@ -62,20 +69,30 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (max_i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* 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_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
CPRINTF("Request [%d] %dV %dmW\n",
max_i, sel_mv/1000, uw/1000);
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);
max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
CPRINTF("Request [%d] %dV %dmA\n",
max_i, sel_mv/1000, ma);
max = MIN(ma, 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;

View File

@@ -17,6 +17,11 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Define typical operating power and max power */
#define OPERATING_POWER_MW 15000
#define MAX_POWER_MW 60000
#define MAX_CURRENT_MA 3000
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
PDO_FIXED(12000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
@@ -40,7 +45,10 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
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++) {
@@ -61,20 +69,31 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
if (max_i < 0)
return -EC_ERROR_UNKNOWN;
/* request all the power ... */
/* build rdo for desired 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);
*curr_limit = uw/sel_mv;
CPRINTF("Request [%d] %dV %dmW\n",
max_i, sel_mv/1000, uw/1000);
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);
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
*curr_limit = ma;
CPRINTF("Request [%d] %dV %dmA\n",
max_i, sel_mv/1000, ma);
max = MIN(ma, 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;
}

View File

@@ -145,6 +145,8 @@ static void unplug(int port)
static int test_request(void)
{
uint32_t expected_rdo = RDO_FIXED(1, 900, 900, RDO_CAP_MISMATCH);
plug_in_source(0, 0);
task_wake(PORT_TO_TASK_ID(0));
task_wait_event(100 * MSEC);
@@ -165,7 +167,7 @@ static int test_request(void)
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, RDO_FIXED(1, 450, 900, 0)));
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);