diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2018-09-05 17:57:54 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-05 15:43:36 -0700 |
commit | 4170abd620557cddef031546ba0a249b834f7b38 (patch) | |
tree | 40f720b6ab8164fa7fce8d2ead8f440073264474 /common/usb_i2c.c | |
parent | 06fa39d8c474757e8f5e8cedfb180f4c56c1c4dc (diff) | |
download | chrome-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/usb_i2c.c')
-rw-r--r-- | common/usb_i2c.c | 31 |
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; +} |