summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/fruitpie/usb_pd_policy.c18
-rw-r--r--board/ryu/board.h1
-rw-r--r--board/samus_pd/board.h1
-rw-r--r--board/samus_pd/usb_pd_policy.c18
-rw-r--r--board/zinger/board.h4
-rw-r--r--board/zinger/usb_pd_policy.c10
-rw-r--r--common/usb_pd_protocol.c28
-rw-r--r--include/config.h9
-rw-r--r--include/usb_pd.h22
9 files changed, 87 insertions, 24 deletions
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index 3292a80a77..0a4b1be7ee 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -139,7 +139,6 @@ int pd_board_checks(void)
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
{
int cmd = PD_VDO_CMD(payload[0]);
- int i;
ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]);
/* make sure we have some payload */
@@ -152,12 +151,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
*(payload + cnt - 1) = 0;
ccprintf("version: %s\n", (char *)(payload+1));
break;
- case VDO_CMD_RW_HASH:
- ccprintf("RW Hash: ");
- payload++; /* skip cmd */
- for (i = 0; i < cnt - 1; i++)
- ccprintf("%08x ", *payload++);
- ccprintf("\n");
+ case VDO_CMD_READ_INFO:
+ /* copy hash */
+ if (cnt >= 6)
+ pd_dev_store_rw_hash(port, payload + 1);
+
+ /* if last word is present, it contains lots of info */
+ if (cnt == 7)
+ ccprintf("Dev:%d SW:%d RW:%d\n",
+ VDO_INFO_HW_DEV_ID(payload[6]),
+ VDO_INFO_SW_DBG_VER(payload[6]),
+ VDO_INFO_IS_RW(payload[6]));
break;
}
diff --git a/board/ryu/board.h b/board/ryu/board.h
index 768f71fb1e..7d3b9f5fc3 100644
--- a/board/ryu/board.h
+++ b/board/ryu/board.h
@@ -24,6 +24,7 @@
#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_FLASH_ERASE_CHECK
#define CONFIG_USB_PD_INTERNAL_COMP
+#define CONFIG_USB_PD_READ_INFO_ON_CONNECT
#define CONFIG_USBC_SS_MUX
#define CONFIG_ADC
#define CONFIG_HW_CRC
diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h
index 87cef022b9..4cc58a56e4 100644
--- a/board/samus_pd/board.h
+++ b/board/samus_pd/board.h
@@ -25,6 +25,7 @@
#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_FLASH_ERASE_CHECK
#define CONFIG_USB_PD_INTERNAL_COMP
+#define CONFIG_USB_PD_READ_INFO_ON_CONNECT
#define CONFIG_USBC_SS_MUX
#define CONFIG_ADC
#define CONFIG_HW_CRC
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index 7b56d12435..bf24b2eb07 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -154,7 +154,6 @@ int pd_board_checks(void)
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
{
int cmd = PD_VDO_CMD(payload[0]);
- int i;
ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]);
/* make sure we have some payload */
@@ -167,12 +166,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
*(payload + cnt - 1) = 0;
ccprintf("version: %s\n", (char *)(payload+1));
break;
- case VDO_CMD_RW_HASH:
- ccprintf("RW Hash: ");
- payload++; /* skip cmd */
- for (i = 0; i < cnt - 1; i++)
- ccprintf("%08x ", *payload++);
- ccprintf("\n");
+ case VDO_CMD_READ_INFO:
+ /* copy hash */
+ if (cnt >= 6)
+ pd_dev_store_rw_hash(port, payload + 1);
+
+ /* if last word is present, it contains lots of info */
+ if (cnt == 7)
+ ccprintf("Dev:%d SW:%d RW:%d\n",
+ VDO_INFO_HW_DEV_ID(payload[6]),
+ VDO_INFO_SW_DBG_VER(payload[6]),
+ VDO_INFO_IS_RW(payload[6]));
break;
case VDO_CMD_CURRENT:
ccprintf("Current: %dmA\n", payload[1]);
diff --git a/board/zinger/board.h b/board/zinger/board.h
index ead71fb711..f3a0d3dc5f 100644
--- a/board/zinger/board.h
+++ b/board/zinger/board.h
@@ -42,6 +42,10 @@
#define UARTN CONFIG_UART_CONSOLE
#define UARTN_BASE STM32_USART_BASE(CONFIG_UART_CONSOLE)
+/* USB PD ChromeOS VDM information */
+#define USB_PD_HARDWARE_DEVICE_ID 1
+#define USB_PD_DBG_SW_VERSION 255
+
#ifndef __ASSEMBLER__
#include "common.h"
diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c
index a4fcc38fe1..591021bb56 100644
--- a/board/zinger/usb_pd_policy.c
+++ b/board/zinger/usb_pd_policy.c
@@ -369,10 +369,16 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
pd_power_supply_reset(0);
cpu_reset();
break;
- case VDO_CMD_RW_HASH:
+ case VDO_CMD_READ_INFO:
hash = flash_hash_rw();
+ /* copy hash into response */
memcpy(payload + 1, hash, SHA1_DIGEST_SIZE);
- rsize = 6;
+ /* copy other info into response */
+ payload[SHA1_DIGEST_SIZE/4 + 1] = VDO_INFO(
+ USB_PD_HARDWARE_DEVICE_ID,
+ USB_PD_DBG_SW_VERSION,
+ !is_ro_mode());
+ rsize = 7;
break;
case VDO_CMD_FLASH_ERASE:
/* do not kill the code under our feet */
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 263c9b63e0..387ea20e82 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -13,6 +13,7 @@
#include "hooks.h"
#include "host_command.h"
#include "registers.h"
+#include "sha1.h"
#include "task.h"
#include "timer.h"
#include "util.h"
@@ -220,6 +221,9 @@ static struct pd_protocol {
/* next Vendor Defined Message to send */
uint32_t vdo_data[VDO_MAX_SIZE];
uint8_t vdo_count;
+
+ /* Attached ChromeOS device RW hash */
+ uint32_t dev_rw_hash[SHA1_DIGEST_SIZE/4];
} pd[PD_PORT_COUNT];
/*
@@ -1019,6 +1023,11 @@ static void pd_vdm_send_state_machine(int port)
}
}
+void pd_dev_store_rw_hash(int port, uint32_t *rw_hash)
+{
+ memcpy(pd[port].dev_rw_hash, rw_hash, SHA1_DIGEST_SIZE);
+}
+
#ifdef CONFIG_USB_PD_DUAL_ROLE
void pd_set_dual_role(enum pd_dual_role_states state)
{
@@ -1276,6 +1285,11 @@ void pd_task(void)
!(cc1_volt >= PD_SNK_VA);
pd_select_polarity(port,
pd[port].polarity);
+#ifdef CONFIG_USB_PD_READ_INFO_ON_CONNECT
+ /* Send google VDM to read info */
+ pd_send_vdm(port, USB_VID_GOOGLE,
+ VDO_CMD_READ_INFO, NULL, 0);
+#endif
set_state(port, PD_STATE_SNK_DISCOVERY);
timeout = 10*MSEC;
}
@@ -1493,9 +1507,9 @@ static int remote_flashing(int argc, char **argv)
cmd = VDO_CMD_FLASH_HASH;
cnt = argc;
ccprintf("HASH ...");
- } else if (!strcasecmp(argv[3], "rw_hash")) {
- cmd = VDO_CMD_RW_HASH;
- ccprintf("RW HASH...");
+ } else if (!strcasecmp(argv[3], "info")) {
+ cmd = VDO_CMD_READ_INFO;
+ ccprintf("INFO...");
} else if (!strcasecmp(argv[3], "version")) {
cmd = VDO_CMD_VERSION;
ccprintf("VERSION...");
@@ -1602,6 +1616,11 @@ static int command_pd(int argc, char **argv)
} else if (!strncasecmp(argv[2], "hard", 4)) {
set_state(port, PD_STATE_HARD_RESET);
task_wake(PORT_TO_TASK_ID(port));
+ } else if (!strncasecmp(argv[2], "hash", 4)) {
+ int i;
+ for (i = 0; i < SHA1_DIGEST_SIZE / 4; i++)
+ ccprintf("%08x ", pd[port].dev_rw_hash[i]);
+ ccprintf("\n");
} else if (!strncasecmp(argv[2], "soft", 4)) {
execute_soft_reset(port);
send_control(port, PD_CTRL_SOFT_RESET);
@@ -1690,7 +1709,8 @@ static int command_pd(int argc, char **argv)
DECLARE_CONSOLE_COMMAND(pd, command_pd,
"<port> "
"[tx|bist|charger|dev|dump|dualrole|enable"
- "|soft|hard|clock|ping|state|vdm [ping | curr]]",
+ "|soft|hash|hard|clock|ping|state"
+ "|vdm [ping | curr]]",
"USB PD",
NULL);
diff --git a/include/config.h b/include/config.h
index 1221a6f6bc..609d0943b2 100644
--- a/include/config.h
+++ b/include/config.h
@@ -941,6 +941,9 @@
/* Define if this board can act as a dual-role PD port (source and sink) */
#undef CONFIG_USB_PD_DUAL_ROLE
+/* Dynamic USB PD source capability */
+#undef CONFIG_USB_PD_DYNAMIC_SRC_CAP
+
/* Check whether PD is the sole power source before flash erase operation */
#undef CONFIG_USB_PD_FLASH_ERASE_CHECK
@@ -950,12 +953,12 @@
/* Define if using internal comparator for PD receive */
#undef CONFIG_USB_PD_INTERNAL_COMP
+/* Define to have PD state machine send read info VDM on connection */
+#undef CONFIG_USB_PD_READ_INFO_ON_CONNECT
+
/* USB PD transmit uses SPI master */
#undef CONFIG_USB_PD_TX_USES_SPI_MASTER
-/* Dynamic USB PD source capability */
-#undef CONFIG_USB_PD_DYNAMIC_SRC_CAP
-
/* Support for USB type-c superspeed mux */
#undef CONFIG_USBC_SS_MUX
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 83fee88cf0..4a9376a369 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -122,7 +122,7 @@ enum pd_errors {
/* ChromeOS specific commands */
#define VDO_CMD_VERSION VDO_CMD_VENDOR(0)
-#define VDO_CMD_RW_HASH VDO_CMD_VENDOR(2)
+#define VDO_CMD_READ_INFO VDO_CMD_VENDOR(2)
#define VDO_CMD_REBOOT VDO_CMD_VENDOR(5)
#define VDO_CMD_FLASH_ERASE VDO_CMD_VENDOR(6)
#define VDO_CMD_FLASH_WRITE VDO_CMD_VENDOR(7)
@@ -133,6 +133,18 @@ enum pd_errors {
#define PD_VDO_VID(vdo) ((vdo) >> 16)
#define PD_VDO_CMD(vdo) ((vdo) & 0x1f)
+/*
+ * ChromeOS specific VDO_CMD_READ_INFO responds with device info including:
+ * RW Hash: sha1 of RW hash (20 bytes)
+ * HW Device ID: unique descriptor for each ChromeOS model (2 bytes)
+ * SW Debug Version: Software version useful for debugging (1 byte)
+ * IS RW: True if currently in RW, False otherwise (1 bit)
+ */
+#define VDO_INFO(id, ver, is_rw) ((id) << 16 | (ver) << 8 | (is_rw))
+#define VDO_INFO_HW_DEV_ID(x) ((x) >> 16)
+#define VDO_INFO_SW_DBG_VER(x) (((x) >> 8) & 0xff)
+#define VDO_INFO_IS_RW(x) ((x) & 1)
+
/* USB Vendor ID assigned to Google Inc. */
#define USB_VID_GOOGLE 0x18d1
@@ -293,6 +305,14 @@ int pd_board_checks(void);
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload);
/**
+ * Store RW hash of device
+ *
+ * @param port USB-C port number
+ * @param rw_hash pointer to sha1 rw_hash
+ */
+void pd_dev_store_rw_hash(int port, uint32_t *rw_hash);
+
+/**
* Send Vendor Defined Message
*
* @param port USB-C port number