summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-11-02 17:55:11 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-06 20:06:25 +0000
commit8bd7ab6203b2e6a33a75be83ae178bde52720145 (patch)
tree60e2e70a7219208a54a10074ee2bebc442becad6
parent75ced738383d4b3bdf4e95b31c193cb0366e69cf (diff)
downloadchrome-ec-8bd7ab6203b2e6a33a75be83ae178bde52720145.tar.gz
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>
-rw-r--r--board/fruitpie/usb_pd_policy.c13
-rw-r--r--board/host/usb_pd_policy.c5
-rw-r--r--board/plankton/usb_pd_policy.c14
-rw-r--r--board/ryu/usb_pd_policy.c11
-rw-r--r--board/ryu_p2/usb_pd_policy.c11
-rw-r--r--board/samus_pd/usb_pd_policy.c11
-rw-r--r--board/twinkie/usb_pd_policy.c13
-rw-r--r--board/zinger/usb_pd_policy.c6
-rw-r--r--common/charge_manager.c4
-rw-r--r--common/usb_pd_protocol.c49
-rw-r--r--include/usb_pd.h8
11 files changed, 91 insertions, 54 deletions
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index 06a8a44ba7..1d8cc7523e 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -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);
diff --git a/board/host/usb_pd_policy.c b/board/host/usb_pd_policy.c
index c1630aff0d..5c39558b41 100644
--- a/board/host/usb_pd_policy.c
+++ b/board/host/usb_pd_policy.c
@@ -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);
diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c
index f213fce9ca..c4367a094d 100644
--- a/board/plankton/usb_pd_policy.c
+++ b/board/plankton/usb_pd_policy.c
@@ -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);
diff --git a/board/ryu/usb_pd_policy.c b/board/ryu/usb_pd_policy.c
index 561e6666ab..d092d521f4 100644
--- a/board/ryu/usb_pd_policy.c
+++ b/board/ryu/usb_pd_policy.c
@@ -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);
diff --git a/board/ryu_p2/usb_pd_policy.c b/board/ryu_p2/usb_pd_policy.c
index 73688b218d..550b20d77a 100644
--- a/board/ryu_p2/usb_pd_policy.c
+++ b/board/ryu_p2/usb_pd_policy.c
@@ -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);
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index c25c05e9fc..cecf5a7987 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -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);
diff --git a/board/twinkie/usb_pd_policy.c b/board/twinkie/usb_pd_policy.c
index d71770e4ec..1179318efd 100644
--- a/board/twinkie/usb_pd_policy.c
+++ b/board/twinkie/usb_pd_policy.c
@@ -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);
diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c
index 103450e24a..96713e1d18 100644
--- a/board/zinger/usb_pd_policy.c
+++ b/board/zinger/usb_pd_policy.c
@@ -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);
diff --git a/common/charge_manager.c b/common/charge_manager.c
index 3bea74747f..c884c05500 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -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;
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index c44e070043..804c50787b 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -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
+ src_ready_vdms_sent = 1;
+ break;
}
- if (!pd[port].ping_enabled) {
- timeout = PD_T_SOURCE_ACTIVITY;
+ 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;
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 1eede4fd89..7b00486b5f 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -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 */
@@ -972,6 +973,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
* send or respond to any PD communication.