summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-09-05 17:57:54 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-05 15:43:36 -0700
commit4170abd620557cddef031546ba0a249b834f7b38 (patch)
tree40f720b6ab8164fa7fce8d2ead8f440073264474 /common
parent06fa39d8c474757e8f5e8cedfb180f4c56c1c4dc (diff)
downloadchrome-ec-4170abd620557cddef031546ba0a249b834f7b38.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>
Diffstat (limited to 'common')
-rw-r--r--common/usb_i2c.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/common/usb_i2c.c b/common/usb_i2c.c
index a92c411f1b..3f0ac3c44c 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) {
@@ -75,7 +80,7 @@ static uint8_t usb_i2c_executable(struct usb_i2c_config const *config)
return 1;
}
-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. */
uint8_t count = usb_i2c_read_packet(config);
@@ -107,6 +112,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;
@@ -145,3 +162,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;
+}