summaryrefslogtreecommitdiff
path: root/common/usb_pd_protocol.c
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-09-17 21:39:15 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-09 20:44:43 +0000
commita194bede19a91817ab4351911b74af9a5577baef (patch)
treec084e1dc8027e402e3b54e51cc89a34fc924930e /common/usb_pd_protocol.c
parent0938563284a34b9aa5d1b28b895c3d6fd8cbfff0 (diff)
downloadchrome-ec-a194bede19a91817ab4351911b74af9a5577baef.tar.gz
pd: VDM Alternate mode support.
Successfully communicate SVDM for discovery (identity, svids, modes) and enter mode. Still need to: - Add same functionality on when power role is sink too. - determine what connected events would require exit mode. - do proper cleanup on disconnect. - implement real display port 'enter' mode for samus_pd - test & cleanup Additionally the USB Billboard class functionality needs to be added but will likely do that in a separate CL. BRANCH=none BUG=chrome-os-partner:28342 TEST=manual, From fruitpie, [Image: RO, fruitpie_v1.1.2263-d79140d-dirty 2014-09-29 17:44:15 tbroch@brisket.mtv.corp.google.com] [0.000383 Inits done] C0 st2 Console is enabled; type HELP for help. > [0.250551 USB PD initialized] pd dualrole source C0 st8 > [8.366335 PD TMOUT RX 1/1] RX ERR (-1) [8.478308 PD TMOUT RX 1/1] RX ERR (-1) [8.590280 PD TMOUT RX 1/1] RX ERR (-1) C0 st9 Switch to 5000 V 3000 mA (for 3000/3000 mA) C0 st10 C0 st11 C0 st12 8.867593] SVDM/4 [1] ff008081 340018d1 00000000 17000008 8.867906] DONE 8.871006] SVDM/2 [2] ff008082 ff010000 8.871224] DONE 8.875092] SVDM/7 [3] ff018083 00100081 00000000 00000000 00000000 00000000 00000000 Entering mode w/ vdo = 00100081 8.875492] DONE 8.878435] SVDM/1 [4] ff018144 8.878612] DONE > pe 0 dump SVID[0]: ff01 [0] 00100081 [1] 00000000 [2] 00000000 [3] 00000000 [4] 00000000 [5] 00000000 MODE[0]: svid:ff01 mode:1 caps:00100081 From hoho, [Image: RO, hoho_v1.1.2263-d79140d-dirty 2014-09-29 17:54:59 tbroch@brisket.mtv.corp.google.com] [0.000375 Inits done] C0 st2 Console is enabled; type HELP for help. > [0.250542 USB PD initialized] C0 st3 [0.264637 PD TMOUT RX 1/1] RX ERR (-1) Request [1] 5V 3000mA C0 st4 C0 st5 C0 st6 0.487451] SVDM/1 [1] ff008001 0.487628] DONE 0.491190] SVDM/1 [2] ff008002 0.491346] DONE 0.494510] SVDM/1 [3] ff018003 0.494667] DONE 0.498777] SVDM/1 [4] ff018104 0.498934] DONE Change-Id: I5e2b7802c66b8aaad97e5120dca7a02820086bc1 Signed-off-by: Todd Broch <tbroch@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/219513 Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'common/usb_pd_protocol.c')
-rw-r--r--common/usb_pd_protocol.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index a5a272ab2d..1e7641ed56 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -151,6 +151,7 @@ static const uint8_t dec4b5b[] = {
#define CC_RA(cc) (cc < PD_SRC_RD_THRESHOLD)
#define CC_RD(cc) ((cc > PD_SRC_RD_THRESHOLD) && (cc < PD_SRC_VNC))
#define GET_POLARITY(cc1, cc2) (CC_RD(cc2) || CC_RA(cc1))
+#define IS_CABLE(cc1, cc2) (CC_RD(cc1) || CC_RD(cc2))
/* PD counter definitions */
#define PD_MESSAGE_ID_COUNT 7
@@ -619,29 +620,23 @@ static void bist_mode_2_rx(int port)
static void handle_vdm_request(int port, int cnt, uint32_t *payload)
{
- uint16_t vid = PD_VDO_VID(payload[0]);
-#ifdef CONFIG_USB_PD_CUSTOM_VDM
- int rlen;
+ int rlen = 0;
uint32_t *rdata;
-#endif
- if (vid == USB_VID_GOOGLE) {
- if (pd[port].vdm_state == VDM_STATE_BUSY)
- pd[port].vdm_state = VDM_STATE_DONE;
-#ifdef CONFIG_USB_PD_CUSTOM_VDM
- rlen = pd_custom_vdm(port, cnt, payload, &rdata);
- if (rlen > 0) {
- uint16_t header = PD_HEADER(PD_DATA_VENDOR_DEF,
- pd[port].role, pd[port].msg_id,
- rlen);
- send_validate_message(port, header, rlen, rdata);
- }
-#endif
+ if (pd[port].vdm_state == VDM_STATE_BUSY)
+ pd[port].vdm_state = VDM_STATE_DONE;
+
+ rlen = pd_vdm(port, cnt, payload, &rdata);
+ if (rlen > 0) {
+ uint16_t header = PD_HEADER(PD_DATA_VENDOR_DEF,
+ pd[port].role, pd[port].msg_id,
+ rlen);
+ send_validate_message(port, header, rlen, rdata);
return;
}
if (debug_level >= 1)
CPRINTF("Unhandled VDM VID %04x CMD %04x\n",
- vid, payload[0] & 0xFFFF);
+ PD_VDO_VID(payload[0]), payload[0] & 0xFFFF);
}
static void execute_hard_reset(int port)
@@ -1027,7 +1022,7 @@ void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data,
return;
}
- pd[port].vdo_data[0] = VDO(vid, cmd);
+ pd[port].vdo_data[0] = VDO(vid, (vid == USB_SID_PD) ? 1 : 0, cmd);
pd[port].vdo_count = count + 1;
for (i = 1; i < count + 1; i++)
pd[port].vdo_data[i] = data[i-1];
@@ -1319,20 +1314,23 @@ void pd_task(void)
}
break;
case PD_STATE_SRC_READY:
-#ifdef CONFIG_USB_PD_SIMPLE_DFP
- /*
- * For simple devices that don't support alternate
- * mode and are only sources (ie power adapters),
- * send custom VDM with info about this device
- * once power contract has been negotiated.
- */
if (pd[port].last_state != pd[port].task_state) {
- /* Send google VDM to read info */
+#ifdef CONFIG_USB_PD_SIMPLE_DFP
+ /*
+ * For simple devices that don't support
+ * alternate mode and are only sources (ie power
+ * adapters), send custom VDM with info about
+ * this device once power contract has been
+ * negotiated.
+ */
pd_send_vdm(port, USB_VID_GOOGLE,
VDO_CMD_SEND_INFO,
pd_get_info(), 6);
- }
+#else
+ pd_send_vdm(port, USB_SID_PD,
+ CMD_DISCOVER_IDENT, NULL, 0);
#endif
+ }
if (!pd[port].ping_enabled) {
timeout = PD_T_SOURCE_ACTIVITY;
@@ -1443,6 +1441,7 @@ void pd_task(void)
PD_STATE_HARD_RESET);
break;
case PD_STATE_HARD_RESET:
+ pd_exit_modes(port, payload);
send_hard_reset(port);
/* reset our own state machine */
execute_hard_reset(port);
@@ -1797,8 +1796,10 @@ static int command_pd(int argc, char **argv)
} else if (!strncasecmp(argv[2], "state", 5)) {
const char * const state_names[] = {
"DISABLED", "SUSPENDED",
+#ifdef CONFIG_USB_PD_DUAL_ROLE
"SNK_DISCONNECTED", "SNK_DISCOVERY", "SNK_REQUESTED",
"SNK_TRANSITION", "SNK_READY",
+#endif /* CONFIG_USB_PD_DUAL_ROLE */
"SRC_DISCONNECTED", "SRC_DISCOVERY", "SRC_NEGOCIATE",
"SRC_ACCEPTED", "SRC_TRANSITION", "SRC_READY",
"SOFT_RESET", "HARD_RESET", "BIST",