mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 00:21:46 +00:00
pd: update source/sink cap PDOs and use to get dual role capable
Update source and sink capacity tables for all PD boards. As per spec, the first entry in both tables must be a fixed power supply PDO. Added dual-role capable bit to fixed PDOs and added new state variable to keep track of that information for each port. This will be used to make decisions in charge manager and to pass up via host commands. BUG=chrome-os-partner:28869 BRANCH=samus TEST=make buildall. use "pd 1 status" to check if part partner is dual-role capable and check zinger is not, C to A receptable adapter is not, and another samus is. Change-Id: I49f034a372bc145cd524577c17ca210eec4c1013 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/227170 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
75ced73838
commit
8bd7ab6203
@@ -18,16 +18,17 @@
|
||||
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
|
||||
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 3000, 0),
|
||||
PDO_FIXED(12000, 3000, 0),
|
||||
PDO_FIXED(20000, 2000, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(12000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(20000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 15000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ const uint32_t pd_src_pdo[] = {
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 15000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
/* Source PDOs */
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(12000, 3000, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(20000, 3000, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(12000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(20000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
static const int pd_src_pdo_cnts[3] = {
|
||||
[SRC_CAP_5V] = 2,
|
||||
@@ -38,9 +38,9 @@ static int pd_src_pdo_idx;
|
||||
|
||||
/* Fake PDOs : we just want our pre-defined voltages */
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_FIXED(5000, 500, 0),
|
||||
PDO_FIXED(12000, 500, 0),
|
||||
PDO_FIXED(20000, 500, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(12000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(20000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
|
||||
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
|
||||
|
||||
/* TODO(crosbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 900, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
/* TODO(crosbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 10000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
|
||||
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
|
||||
|
||||
/* TODO(crosbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 900, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
/* TODO(crosbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 10000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
|
||||
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
|
||||
|
||||
/* TODO(crossbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 900, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 900, PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
/* TODO(crossbug.com/p/28869): update source and sink tables to spec. */
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 15000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
|
||||
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, 3000, 0),
|
||||
PDO_FIXED(12000, 3000, 0),
|
||||
PDO_FIXED(20000, 2000, 0),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(5000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(12000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
PDO_FIXED(20000, 3000, PDO_FIXED_EXTERNAL|PDO_FIXED_DUAL_ROLE),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
const uint32_t pd_snk_pdo[] = {
|
||||
PDO_BATT(4500, 5500, 15000),
|
||||
PDO_BATT(11500, 12500, 36000),
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_DUAL_ROLE),
|
||||
PDO_BATT(5000, 20000, 15000),
|
||||
PDO_VAR(5000, 20000, 3000),
|
||||
};
|
||||
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
|
||||
|
||||
|
||||
@@ -149,9 +149,9 @@ static void discharge_voltage(int target_volt)
|
||||
/* Power Delivery Objects */
|
||||
const uint32_t pd_src_pdo[] = {
|
||||
PDO_FIXED(5000, 500, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(5000, RATED_CURRENT, 0),
|
||||
PDO_FIXED(12000, RATED_CURRENT, 0),
|
||||
PDO_FIXED(20000, RATED_CURRENT, 0),
|
||||
PDO_FIXED(5000, RATED_CURRENT, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(12000, RATED_CURRENT, PDO_FIXED_EXTERNAL),
|
||||
PDO_FIXED(20000, RATED_CURRENT, PDO_FIXED_EXTERNAL),
|
||||
};
|
||||
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
|
||||
|
||||
|
||||
@@ -201,8 +201,8 @@ static int hc_pd_power_info(struct host_cmd_handler_args *args)
|
||||
else
|
||||
r->role = USB_PD_PORT_POWER_DISCONNECTED;
|
||||
|
||||
/* TODO: fill in appropriate dual-role status */
|
||||
r->dualrole = 0;
|
||||
/* Is port partner dual-role capable */
|
||||
r->dualrole = pd_get_partner_dualrole_capable(port);
|
||||
|
||||
if (sup == CHARGE_SUPPLIER_NONE) {
|
||||
r->type = USB_CHG_TYPE_NONE;
|
||||
|
||||
@@ -235,6 +235,8 @@ static struct pd_protocol {
|
||||
uint64_t src_recover;
|
||||
/* Flag for sending pings in SRC_READY */
|
||||
uint8_t ping_enabled;
|
||||
/* Port partner is a dual-role power device */
|
||||
uint8_t drp_partner;
|
||||
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Current limit / voltage based on the last request message */
|
||||
@@ -305,6 +307,7 @@ static inline void set_state(int port, enum pd_states next_state)
|
||||
|
||||
if (next_state == PD_STATE_SRC_DISCONNECTED) {
|
||||
pd[port].dev_id = 0;
|
||||
pd[port].drp_partner = 0;
|
||||
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
|
||||
pd_exit_mode(port, NULL);
|
||||
#else
|
||||
@@ -317,6 +320,11 @@ static inline void set_state(int port, enum pd_states next_state)
|
||||
pd_set_vconn(port, pd[port].polarity, 0);
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
else if (next_state == PD_STATE_SNK_DISCONNECTED) {
|
||||
pd[port].drp_partner = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LOW_POWER_IDLE
|
||||
/* If any PD port is connected, then disable deep sleep */
|
||||
@@ -730,6 +738,10 @@ static void pd_send_request_msg(int port)
|
||||
if (res == EC_SUCCESS) {
|
||||
pd[port].curr_limit = curr_limit;
|
||||
pd[port].supply_voltage = supply_voltage;
|
||||
/* src cap 0 should be fixed PDO, get dualrole power capable */
|
||||
if ((pd_src_caps[port][0] & PDO_TYPE_MASK) == PDO_TYPE_FIXED)
|
||||
pd[port].drp_partner = (pd_src_caps[port][0] &
|
||||
PDO_FIXED_DUAL_ROLE) ? 1 : 0;
|
||||
res = send_request(port, rdo);
|
||||
if (res >= 0)
|
||||
set_state(port, PD_STATE_SNK_REQUESTED);
|
||||
@@ -783,6 +795,10 @@ static void handle_data_request(int port, uint16_t head,
|
||||
|
||||
break;
|
||||
case PD_DATA_SINK_CAP:
|
||||
/* snk cap 0 should be fixed PDO, get dualrole power capable */
|
||||
if ((payload[0] & PDO_TYPE_MASK) == PDO_TYPE_FIXED)
|
||||
pd[port].drp_partner =
|
||||
(payload[0] & PDO_FIXED_DUAL_ROLE) ? 1 : 0;
|
||||
break;
|
||||
case PD_DATA_VENDOR_DEF:
|
||||
handle_vdm_request(port, cnt, payload);
|
||||
@@ -1170,6 +1186,12 @@ int pd_get_polarity(int port)
|
||||
return pd[port].polarity;
|
||||
}
|
||||
|
||||
int pd_get_partner_dualrole_capable(int port)
|
||||
{
|
||||
/* return dualrole status of port partner */
|
||||
return pd[port].drp_partner;
|
||||
}
|
||||
|
||||
void pd_comm_enable(int enable)
|
||||
{
|
||||
pd_comm_enabled = enable;
|
||||
@@ -1236,7 +1258,7 @@ void pd_task(void)
|
||||
#endif /* CONFIG_USB_PD_DUAL_ROLE */
|
||||
enum pd_states this_state;
|
||||
timestamp_t now;
|
||||
int caps_count = 0;
|
||||
int caps_count = 0, src_ready_vdms_sent = 0;
|
||||
|
||||
/* Initialize TX pins and put them in Hi-Z */
|
||||
pd_tx_init();
|
||||
@@ -1383,6 +1405,7 @@ void pd_task(void)
|
||||
res = send_control(port, PD_CTRL_PS_RDY);
|
||||
if (res >= 0) {
|
||||
timeout = PD_T_SEND_SOURCE_CAP;
|
||||
src_ready_vdms_sent = 0;
|
||||
/* it'a time to ping regularly the sink */
|
||||
set_state(port, PD_STATE_SRC_READY);
|
||||
} else {
|
||||
@@ -1392,7 +1415,15 @@ void pd_task(void)
|
||||
}
|
||||
break;
|
||||
case PD_STATE_SRC_READY:
|
||||
timeout = PD_T_SOURCE_ACTIVITY;
|
||||
if (pd[port].last_state != pd[port].task_state) {
|
||||
/* Get sink cap to know if dual-role device */
|
||||
send_control(port, PD_CTRL_GET_SINK_CAP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send VDMs once after get sink cap */
|
||||
if (!src_ready_vdms_sent) {
|
||||
#ifdef CONFIG_USB_PD_SIMPLE_DFP
|
||||
/*
|
||||
* For simple devices that don't support
|
||||
@@ -1408,20 +1439,17 @@ void pd_task(void)
|
||||
pd_send_vdm(port, USB_SID_PD,
|
||||
CMD_DISCOVER_IDENT, NULL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!pd[port].ping_enabled) {
|
||||
timeout = PD_T_SOURCE_ACTIVITY;
|
||||
src_ready_vdms_sent = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pd[port].ping_enabled)
|
||||
break;
|
||||
|
||||
/* Verify that the sink is alive */
|
||||
res = send_control(port, PD_CTRL_PING);
|
||||
if (res >= 0) {
|
||||
/* schedule next keep-alive */
|
||||
timeout = PD_T_SOURCE_ACTIVITY;
|
||||
if (res >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ping dropped. Try soft reset. */
|
||||
set_state(port, PD_STATE_SOFT_RESET);
|
||||
@@ -1955,10 +1983,11 @@ static int command_pd(int argc, char **argv)
|
||||
"SOFT_RESET", "HARD_RESET", "BIST",
|
||||
};
|
||||
BUILD_ASSERT(ARRAY_SIZE(state_names) == PD_STATE_COUNT);
|
||||
ccprintf("Port C%d, %s - Role: %s Polarity: CC%d State: %s\n",
|
||||
ccprintf("Port C%d, %s - Role: %s Polarity: CC%d DRP: %d, "
|
||||
"State: %s\n",
|
||||
port, pd_comm_enabled ? "Enabled" : "Disabled",
|
||||
pd[port].role == PD_ROLE_SOURCE ? "SRC" : "SNK",
|
||||
pd[port].polarity + 1,
|
||||
pd[port].polarity + 1, pd[port].drp_partner,
|
||||
state_names[pd[port].task_state]);
|
||||
} else {
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
@@ -43,6 +43,7 @@ enum pd_errors {
|
||||
#define PDO_FIXED_SUSPEND (1 << 28) /* USB Suspend supported */
|
||||
#define PDO_FIXED_EXTERNAL (1 << 27) /* Externally powered */
|
||||
#define PDO_FIXED_COMM_CAP (1 << 26) /* USB Communications Capable */
|
||||
#define PDO_FIXED_DATA_SWAP (1 << 25) /* Data role swap command supported */
|
||||
#define PDO_FIXED_PEAK_CURR () /* [21..20] Peak current */
|
||||
#define PDO_FIXED_VOLT(mv) (((mv)/50) << 10) /* Voltage in 50mV units */
|
||||
#define PDO_FIXED_CURR(ma) (((ma)/10) << 0) /* Max current in 10mA units */
|
||||
@@ -971,6 +972,13 @@ int pd_is_connected(int port);
|
||||
*/
|
||||
int pd_get_polarity(int port);
|
||||
|
||||
/**
|
||||
* Get port partner dual-role capable status
|
||||
*
|
||||
* @param port USB-C port number
|
||||
*/
|
||||
int pd_get_partner_dualrole_capable(int port);
|
||||
|
||||
/**
|
||||
* Set the PD communication enabled flag. When communication is disabled,
|
||||
* the port can still detect connection and source power but will not
|
||||
|
||||
Reference in New Issue
Block a user