summaryrefslogtreecommitdiff
path: root/board/zinger/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/zinger/usb_pd_policy.c')
-rw-r--r--board/zinger/usb_pd_policy.c104
1 files changed, 84 insertions, 20 deletions
diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c
index d2d0fbcb8a..0f6bcdfccd 100644
--- a/board/zinger/usb_pd_policy.c
+++ b/board/zinger/usb_pd_policy.c
@@ -395,35 +395,99 @@ void pd_adc_interrupt(void)
DECLARE_IRQ(STM32_IRQ_ADC_COMP, pd_adc_interrupt, 1);
/* ----------------- Vendor Defined Messages ------------------ */
-static uint32_t info_data[6];
-uint32_t *pd_get_info(void)
+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_product = VDO_PRODUCT(CONFIG_USB_PID, CONFIG_USB_BCD_DEV);
+
+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 */
+ 0, /* Vbus power required */
+ AMA_USBSS_BBONLY /* USB SS support */);
+
+/* When set true, we are in GFU mode */
+static int gfu_mode;
+
+static int svdm_response_identity(int port, uint32_t *payload)
{
- void *hash;
-
- /* calculate RW hash */
- hash = flash_hash_rw();
- /* copy first 20 bytes of RW hash */
- memcpy(info_data, hash, 5 * sizeof(uint32_t));
- /* copy other info into data msg */
-#ifdef BOARD_ZINGER
- info_data[5] = VDO_INFO(USB_PD_HW_DEV_ID_ZINGER, 1,
- ver_get_numcommits(), !is_ro_mode());
-#elif defined(BOARD_MINIMUFFIN)
- info_data[5] = VDO_INFO(USB_PD_HW_DEV_ID_MINIMUFFIN, 0,
- ver_get_numcommits(), !is_ro_mode());
-#else
-#error "Board does not have a USB-PD HW Device ID"
-#endif
+ payload[VDO_I(IDH)] = vdo_idh;
+ payload[VDO_I(CSTAT)] = VDO_CSTAT(0);
+ payload[VDO_I(PRODUCT)] = vdo_product;
+ payload[VDO_I(AMA)] = vdo_ama;
+ return VDO_I(AMA) + 1;
+}
+
+static int svdm_response_svids(int port, uint32_t *payload)
+{
+ payload[1] = VDO_SVID(USB_VID_GOOGLE, 0);
+ return 2;
+}
+
+/* Will only ever be a single mode for this device */
+#define MODE_CNT 1
+#define OPOS 1
+
+const uint32_t vdo_dp_mode[MODE_CNT] = {
+ VDO_MODE_GOOGLE(MODE_GOOGLE_FU)
+};
+
+static int svdm_response_modes(int port, uint32_t *payload)
+{
+ if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE)
+ return 0; /* nak */
+
+ memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
+ return MODE_CNT + 1;
+}
+
+static int svdm_enter_mode(int port, uint32_t *payload)
+{
+ /* SID & mode request is valid */
+ if ((PD_VDO_VID(payload[0]) != USB_VID_GOOGLE) ||
+ (PD_VDO_OPOS(payload[0]) != OPOS))
+ return 0; /* will generate NAK */
+
+ gfu_mode = 1;
+ debug_printf("GFU\n");
+ return 1;
+}
- return info_data;
+static int svdm_exit_mode(int port, uint32_t *payload)
+{
+ gfu_mode = 0;
+ return 1; /* Must return ACK */
}
+static struct amode_fx dp_fx = {
+ .status = NULL,
+ .config = NULL,
+};
+
+const struct svdm_response svdm_rsp = {
+ .identity = &svdm_response_identity,
+ .svids = &svdm_response_svids,
+ .modes = &svdm_response_modes,
+ .enter_mode = &svdm_enter_mode,
+ .amode = &dp_fx,
+ .exit_mode = &svdm_exit_mode,
+};
+
static int pd_custom_vdm(int port, int cnt, uint32_t *payload,
uint32_t **rpayload)
{
static int flash_offset;
int cmd = PD_VDO_CMD(payload[0]);
int rsize = 1;
+
+ if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE || !gfu_mode)
+ return 0;
+
debug_printf("%T] VDM/%d [%d] %08x\n", cnt, cmd, payload[0]);
*rpayload = payload;
@@ -439,7 +503,7 @@ static int pd_custom_vdm(int port, int cnt, uint32_t *payload,
break;
case VDO_CMD_READ_INFO:
/* copy info into response */
- memcpy(payload + 1, pd_get_info(), 24);
+ memcpy(payload + 1, board_get_info(), 24);
rsize = 7;
break;
case VDO_CMD_FLASH_ERASE: