summaryrefslogtreecommitdiff
path: root/board/hoho/usb_pd_policy.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 /board/hoho/usb_pd_policy.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 'board/hoho/usb_pd_policy.c')
-rw-r--r--board/hoho/usb_pd_policy.c119
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);
+}