diff options
Diffstat (limited to 'board/dingdong')
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 70 |
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 */ } |