summaryrefslogtreecommitdiff
path: root/board/dingdong
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-11-19 18:17:52 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-02 01:57:26 +0000
commit975cb11ca193a8783ad53950dad5a01013d3d770 (patch)
treef3b6beac1f5c2f2f9500518001bd0e7f56328915 /board/dingdong
parent01047f65240a1ba333372f53c28f8281cbb7cf1f (diff)
downloadchrome-ec-975cb11ca193a8783ad53950dad5a01013d3d770.tar.gz
dingdong/hoho: Add GFU alternate mode.
Per USB PD specification even custom VDMs should fall under the alternate mode discovery policy. CL lays ground work for GFU (Google Flash Update) alternate mode. Signed-off-by: Todd Broch <tbroch@chromium.org> BRANCH=samus BUG=chrome-os-partner:31192,chrome-os-partner:31193 TEST=manual, See samus_pd console correctly discover another SVID & subsequent mode. (0) == Discover identity w/ two SVIDs 0xff01 & 0x11d1 (1) == Discover mode for 0xff01 (2) == Discover mode for 0x18d1 console output -------------- SVDM/5 [1] ff008041 2c0018d1 00000000 50110001 1100000b [4070.286120 DONE] (0) SVDM/2 [2] ff008042 ff0118d1 00000000 [4070.289353 DONE] (1) SVDM/2 [3] ff018043 00001085 [4070.292575 DONE] (2) SVDM/2 [3] 18d18043 00000001 [4070.295798 DONE] SVDM/1 [4] ff018144 [4070.298844 DONE] SVDM/2 [16] ff018150 00000002 [4070.302261 DONE] SVDM/1 [17] ff018151 > pe 0 dump IDENT: [ID Header] 2c0018d1 :: AMA, VID:18d1 [Cert Stat] 00000000 [2] 50110001 [3] 1100000b SVID[0]: ff01 MODES: [1] 00001085 SVID[1]: 18d1 MODES: [1] 00000001 MODE[1]: svid:ff01 caps:00001085 Change-Id: Ifab79a6fc6770a6f4bd7690ca8e6723503264137 Reviewed-on: https://chromium-review.googlesource.com/231833 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org> Commit-Queue: Todd Broch <tbroch@chromium.org> Tested-by: Todd Broch <tbroch@chromium.org>
Diffstat (limited to 'board/dingdong')
-rw-r--r--board/dingdong/usb_pd_policy.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c
index 2743eb12fd..b38254a83b 100644
--- a/board/dingdong/usb_pd_policy.c
+++ b/board/dingdong/usb_pd_policy.c
@@ -43,6 +43,8 @@ static unsigned select_mv = 5000;
/* Whether alternate mode has been entered or not */
static int alt_mode;
+/* When set true, we are in GFU mode */
+static int gfu_mode;
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
uint32_t *curr_limit, uint32_t *supply_voltage)
@@ -170,40 +172,45 @@ static int svdm_response_identity(int port, uint32_t *payload)
static int svdm_response_svids(int port, uint32_t *payload)
{
- payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, 0);
- return 2;
+ payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, USB_VID_GOOGLE);
+ payload[2] = 0;
+ return 3;
}
-/*
- * Will only ever be a single mode for this UFP_D device as it has no real USB
- * support making it only PIN_E configureable
- */
-#define MODE_CNT 1
-#define OPOS 1
+#define OPOS_DP 1
+#define OPOS_GFU 1
-const uint32_t vdo_dp_mode[MODE_CNT] = {
- VDO_MODE_DP(0, /* UFP pin cfg supported : none */
+const uint32_t vdo_dp_modes[1] = {
+ VDO_MODE_DP(0, /* UFP pin cfg supported : none */
MODE_DP_PIN_E, /* DFP pin cfg supported */
- 1, /* no usb2.0 signalling in AMode */
- CABLE_PLUG, /* its a plug */
+ 1, /* no usb2.0 signalling in AMode */
+ CABLE_PLUG, /* its a plug */
MODE_DP_V13, /* DPv1.3 Support, no Gen2 */
MODE_DP_SNK) /* Its a sink only */
};
+const uint32_t vdo_goog_modes[1] = {
+ VDO_MODE_GOOGLE(MODE_GOOGLE_FU)
+};
+
static int svdm_response_modes(int port, uint32_t *payload)
{
- if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT)
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
+ memcpy(payload + 1, vdo_dp_modes, sizeof(vdo_dp_modes));
+ return ARRAY_SIZE(vdo_dp_modes) + 1;
+ } else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) {
+ memcpy(payload + 1, vdo_goog_modes, sizeof(vdo_goog_modes));
+ return ARRAY_SIZE(vdo_goog_modes) + 1;
+ } else {
return 0; /* nak */
-
- memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
- return MODE_CNT + 1;
+ }
}
static int dp_status(int port, uint32_t *payload)
{
int opos = PD_VDO_OPOS(payload[0]);
int hpd = gpio_get_level(GPIO_DP_HPD);
- if (opos != OPOS)
+ if (opos != OPOS_DP)
return 0; /* nak */
payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
@@ -227,14 +234,21 @@ static int dp_config(int port, uint32_t *payload)
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]) != OPOS))
- return 0; /* will generate NAK */
+ int rv = 0; /* will generate a NAK */
- /* TODO(tbroch) Enumerate USB BB here with updated mode choice */
- alt_mode = OPOS;
- return 1;
+ /* SID & mode request is valid */
+ if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_DP)) {
+ alt_mode = OPOS_DP;
+ rv = 1;
+ } else if ((PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_GFU)) {
+ alt_mode = OPOS_GFU;
+ gfu_mode = 1;
+ rv = 1;
+ }
+ /* TODO(p/33968): Enumerate USB BB here with updated mode choice */
+ return rv;
}
int pd_alt_mode(int port)
@@ -244,8 +258,14 @@ int pd_alt_mode(int port)
static int svdm_exit_mode(int port, uint32_t *payload)
{
- gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
alt_mode = 0;
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT)
+ gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
+ else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE)
+ gfu_mode = 0;
+ else
+ CPRINTF("Unknown exit mode req:0x%08x\n", payload[0]);
+
return 1; /* Must return ACK */
}