summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-09-05 17:57:54 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-04-02 21:09:18 +0000
commita77af579d5851ac87e42bc4cb6e29647c2cf459a (patch)
tree8b1a8ed042181933326a305dfbeb6c86511dd0e8
parent74f2779c8a1ddc1d09458e01eca59e3527139f97 (diff)
downloadchrome-ec-a77af579d5851ac87e42bc4cb6e29647c2cf459a.tar.gz
usb_i2c: provide a way to communicate non-i2c commands
On some occasions there might be a need to request an action from the DUT which is related to i2c operations but can not be performed through an i2c transaction. For instance when one need to generate the sync sequence on the EC i2c interface before the EC can be programmed. This patch introduces a facility which allows to register a handler for commands sent on this special address which is picked at 0x78, which becomes 0xf0 during write transaction address cycle. BRANCH=cr50, cr50-mp BUG=b:75976718 TEST=tested along with the rest of the patches to trigger generating of the ITE EC debugger sync sequence. Change-Id: I269d4b8073b0d02f96ca526f221c02c38a036f3d Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1214542 Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit 4170abd620557cddef031546ba0a249b834f7b38) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1549605 Commit-Queue: Ruben Rodriguez Buchillon <coconutruben@chromium.org> Tested-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org> Reviewed-by: Nick Sanders <nsanders@chromium.org>
-rw-r--r--common/usb_i2c.c31
-rw-r--r--include/usb_i2c.h18
2 files changed, 48 insertions, 1 deletions
diff --git a/common/usb_i2c.c b/common/usb_i2c.c
index b1a81aa736..241e86b5ce 100644
--- a/common/usb_i2c.c
+++ b/common/usb_i2c.c
@@ -30,6 +30,11 @@ USB_I2C_CONFIG(i2c,
USB_STR_I2C_NAME,
USB_EP_I2C)
+static int (*cros_cmd_handler)(void *data_in,
+ size_t in_size,
+ void *data_out,
+ size_t out_size);
+
static int16_t usb_i2c_map_error(int error)
{
switch (error) {
@@ -97,7 +102,7 @@ static uint8_t usb_i2c_executable(struct usb_i2c_config const *config)
return 0;
}
-void usb_i2c_execute(struct usb_i2c_config const *config)
+static void usb_i2c_execute(struct usb_i2c_config const *config)
{
/* Payload is ready to execute. */
uint32_t count = usb_i2c_read_packet(config);
@@ -131,6 +136,18 @@ void usb_i2c_execute(struct usb_i2c_config const *config)
config->buffer[0] = USB_I2C_READ_COUNT_INVALID;
} else if (portindex >= i2c_ports_used) {
config->buffer[0] = USB_I2C_PORT_INVALID;
+ } else if (slave_addr == USB_I2C_CMD_ADDR) {
+ /*
+ * This is a non-i2c command, invoke the handler if it has
+ * been registered, if not - report the appropriate error.
+ */
+ if (!cros_cmd_handler)
+ config->buffer[0] = USB_I2C_MISSING_HANDLER;
+ else
+ config->buffer[0] = cros_cmd_handler(config->buffer + 2,
+ write_count,
+ config->buffer + 2,
+ read_count);
} else {
int ret;
@@ -169,3 +186,15 @@ static void usb_i2c_written(struct consumer const *consumer, size_t count)
struct consumer_ops const usb_i2c_consumer_ops = {
.written = usb_i2c_written,
};
+
+int usb_i2c_register_cros_cmd_handler(int (*cmd_handler)
+ (void *data_in,
+ size_t in_size,
+ void *data_out,
+ size_t out_size))
+{
+ if (cros_cmd_handler)
+ return -1;
+ cros_cmd_handler = cmd_handler;
+ return 0;
+}
diff --git a/include/usb_i2c.h b/include/usb_i2c.h
index 29b4fb4ef8..b808de9e49 100644
--- a/include/usb_i2c.h
+++ b/include/usb_i2c.h
@@ -106,6 +106,7 @@ enum usb_i2c_error {
USB_I2C_READ_COUNT_INVALID = 0x0004,
USB_I2C_PORT_INVALID = 0x0005,
USB_I2C_DISABLED = 0x0006,
+ USB_I2C_MISSING_HANDLER = 0x0007,
USB_I2C_UNKNOWN_ERROR = 0x8000,
};
@@ -212,4 +213,21 @@ void usb_i2c_deferred(struct usb_i2c_config const *config);
*/
int usb_i2c_board_is_enabled(void);
+/*
+ * Special i2c address to use when the client is required to execute some
+ * command which does not directly involve the i2c master driver.
+ */
+#define USB_I2C_CMD_ADDR 0xf0
+
+/*
+ * Function to call to register a handler for commands sent to the special i2c
+ * address above.
+ */
+int usb_i2c_register_cros_cmd_handler(int (*cmd_handler)
+ (void *data_in,
+ size_t in_size,
+ void *data_out,
+ size_t out_size));
+
+
#endif /* __CROS_USB_I2C_H */