summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
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;
+}