diff options
author | Todd Broch <tbroch@chromium.org> | 2014-09-17 21:39:15 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-09 20:44:43 +0000 |
commit | a194bede19a91817ab4351911b74af9a5577baef (patch) | |
tree | c084e1dc8027e402e3b54e51cc89a34fc924930e /common/usb_pd_protocol.c | |
parent | 0938563284a34b9aa5d1b28b895c3d6fd8cbfff0 (diff) | |
download | chrome-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.c | 55 |
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", |