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 /board/hoho/usb_pd_policy.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 'board/hoho/usb_pd_policy.c')
-rw-r--r-- | board/hoho/usb_pd_policy.c | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index 57099a960d..5523b2a95c 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -14,6 +14,7 @@ #include "timer.h" #include "util.h" #include "usb_pd.h" +#include "version.h" #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) @@ -23,7 +24,7 @@ const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); /* Fake PDOs : we just want our pre-defined voltages */ const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, 0), + PDO_FIXED(5000, 500, 0), }; const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); @@ -88,3 +89,119 @@ int pd_board_checks(void) return EC_SUCCESS; } +/* ----------------- Vendor Defined Messages ------------------ */ +const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */ + 0, /* data caps as USB device */ + IDH_PTYPE_AMA, /* Alternate mode */ + 1, /* supports alt modes */ + USB_VID_GOOGLE); + +const uint32_t vdo_ama = VDO_AMA(CONFIG_USB_PD_IDENTITY_HW_VERS, + CONFIG_USB_PD_IDENTITY_SW_VERS, + 0, 0, 0, 0, /* SS[TR][12] */ + 0, /* Vconn power */ + 0, /* Vconn power required */ + 1, /* Vbus power required */ + 0 /* USB SS support */); + +static int svdm_response_identity(int port, uint32_t *payload) +{ + payload[VDO_I(IDH)] = vdo_idh; + /* TODO(tbroch): Do we plan to obtain TID (test ID) for hoho */ + payload[VDO_I(CSTAT)] = VDO_CSTAT(0); + payload[VDO_I(AMA)] = vdo_ama; + return 4; +} + +static int svdm_response_svids(int port, uint32_t *payload) +{ + payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, 0); + return 2; +} + +const uint32_t vdo_dp_mode[1] = { + VDO_MODE_DP(MODE_DP_PIN_E, /* sink pin cfg */ + 0, /* no src pin cfg */ + 1, /* no usb2.0 signalling in AMode */ + CABLE_PLUG, /* its a plug */ + 0, /* no GEN2 usb */ + 0, /* no dp 1.3 support */ + MODE_DP_SNK) /* Its a sink only */ +}; + +static int svdm_response_modes(int port, uint32_t *payload) +{ + if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) { + /* TODO(tbroch) USB billboard enabled here then */ + return 1; /* will generate a NAK */ + } + memset(payload + 1, 0, sizeof(uint32_t) * PDO_MODES); + payload[1] = vdo_dp_mode[0]; + /* TODO(tbroch) does spec have mechanism for identifying valid modes + * returned for svid? */ + return PDO_MAX_OBJECTS; +} + +static int svdm_enter_mode(int port, uint32_t *payload) +{ + /* SID & mode request is valid */ + if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) || + (PD_VDO_OPOS(payload[0]) != 1)) + return 1; /* will generate a NAK */ + + gpio_set_level(GPIO_PD_SBU_ENABLE, 1); + payload[1] = 0; + return 1; +} + +static int svdm_exit_mode(int port, uint32_t *payload) +{ + /* SID & mode request is valid */ + if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) || + (PD_VDO_OPOS(payload[0]) != 1)) + return 1; /* will generate a NAK */ + + gpio_set_level(GPIO_PD_SBU_ENABLE, 0); + payload[1] = 0; + return 1; +} + +const struct svdm_response svdm_rsp = { + .identity = &svdm_response_identity, + .svids = &svdm_response_svids, + .modes = &svdm_response_modes, + .enter_mode = &svdm_enter_mode, + .exit_mode = &svdm_exit_mode, +}; + +static int pd_custom_vdm(int port, int cnt, uint32_t *payload, + uint32_t **rpayload) +{ + int cmd = PD_VDO_CMD(payload[0]); + int rsize = 1; + ccprintf("%T] VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); + + *rpayload = payload; + switch (cmd) { + case VDO_CMD_VERSION: + memcpy(payload + 1, &version_data.version, 24); + rsize = 7; + break; + default: + /* Unknown : do not answer */ + return 0; + } + ccprintf("%T] DONE\n"); + /* respond (positively) to the request */ + payload[0] |= VDO_SRC_RESPONDER; + + return rsize; +} + +int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) +{ + if (PD_VDO_SVDM(payload[0])) + return pd_svdm(port, cnt, payload, rpayload); + else + return pd_custom_vdm(port, cnt, payload, rpayload); +} |