summaryrefslogtreecommitdiff
path: root/include/usb_i2c.h
diff options
context:
space:
mode:
authorChun-Ta Lin <itspeter@google.com>2017-06-21 15:14:37 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-11-24 02:39:04 -0800
commitf326fb05b564b0975a9870b2831f9372539202db (patch)
tree30aae36290a70e21b502f387f2636370259f0176 /include/usb_i2c.h
parentbfa592f1673948469eca8f532da69462c4ecdbe6 (diff)
downloadchrome-ec-f326fb05b564b0975a9870b2831f9372539202db.tar.gz
hammer: enable large block reading on usb i2c passthru.
Originally, i2c passthru is limited to use I2C_XFER_SINGLE flag where it can only read at most 255 bytes at a time. For application that requires larger i2c bus reading, we change the flag setting and the command protocol. TEST=old ./touchpad_updater still works (previous protocol) TEST=new ./touchpad_updater can get more than 500 bytes per transaction TEST=Debug message only print when -d assigned. ./touchpad_updater -d TEST=Manually change #define CONFIG_USB_I2C_MAX_READ_COUNT (1024 - 6) to #define CONFIG_USB_I2C_MAX_READ_COUNT (1024 - 4) and trigger POWER_OF_TWO assertion. BRANCH=none BUG=b:35587174, b:63993891 Change-Id: Id75b11ea49ba89bab8e18af24d47219030c778c5 Signed-off-by: Chun-Ta Lin <itspeter@google.com> Reviewed-on: https://chromium-review.googlesource.com/542716 Commit-Ready: Chun-ta Lin <itspeter@chromium.org> Tested-by: Chun-ta Lin <itspeter@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'include/usb_i2c.h')
-rw-r--r--include/usb_i2c.h92
1 files changed, 67 insertions, 25 deletions
diff --git a/include/usb_i2c.h b/include/usb_i2c.h
index 3e8eb3e7e5..c135066e26 100644
--- a/include/usb_i2c.h
+++ b/include/usb_i2c.h
@@ -14,27 +14,63 @@
#define __CROS_USB_I2C_H
/*
- * Command:
- * +----------+-----------+---------------+---------------+---------------+
- * | port: 1B | addr: 1B | wr count : 1B | rd count : 1B | data : <= 60B |
- * +----------+-----------+---------------+---------------+---------------+
+ * 2 forms of command are supported:
+ * - When write payload + header is larger than 64 bytes, which exceed the
+ * common USB packet (64 bytes), remaining payload should send without
+ * header.
*
- * port address: 1 byte, i2c interface index
+ * - CONFIG_USB_I2C_MAX_WRITE_COUNT / CONFIG_USB_I2C_MAX_READ_COUNT have to
+ * be defined properly based on the use cases.
*
- * slave address: 1 byte, i2c 7-bit bus address
+ * - Read less than 128 (0x80) bytes.
+ * +------+------+----+----+---------------+
+ * | port | addr | wc | rc | write payload |
+ * +------+------+----+----+---------------+
+ * | 1B | 1B | 1B | 1B | < 256 bytes |
+ * +------+------+----+----+---------------+
*
- * write count: 1 byte, zero based count of bytes to write. If write
- * count exceed 60 bytes, following packets are expected
- * to continue the payload without header.
+ * - Read less than 32768 (0x8000) bytes.
+ * +------+------+----+----+-----+----------+---------------+
+ * | port | addr | wc | rc | rc1 | reserved | write payload |
+ * +------+------+----+----+----------------+---------------+
+ * | 1B | 1B | 1B | 1B | 1B | 1B | < 256 bytes |
+ * +------+------+----+----+----------------+---------------+
*
- * read count: 1 byte, zero based count of bytes to read
+ * - Special notes for rc and rc1:
+ * If the most significant bit in rc is set (rc >= 0x80), this indicates
+ * that we want to read back more than 127 bytes, so the first byte of
+ * data contains rc1 (read count continuation), and the final read count
+ * will be (rc1 << 7) | (rc & 0x7F).
*
- * data: payload of data to write.
+ * Fields:
+ * - port: port address, 1 byte, i2c interface index.
+ *
+ * - addr: slave address, 1 byte, i2c 7-bit bus address.
+ *
+ * - wc: write count, 1 byte, zero based count of bytes to write. If the
+ * indicated write count cause the payload + header exceeds 64 bytes,
+ * Following packets are expected to continue the payload without
+ * header.
+ *
+ * - rc: read count, 1 byte, zero based count of bytes to read. To read more
+ * than 127 (0x7F) bytes please see the special notes above.
+ *
+ * - data: payload of data to write. See wc above for more information.
+ *
+ * - rc1: extended read count, 1 byte. An extended version indicates we want
+ * to read more data. While the most significant bits is set in read
+ * count (rc >= 0x80), rc1 will concatenate with rc together. See the
+ * special notes above for concatenating details.
+ *
+ * - reserved: reserved byte, 1 byte.
*
* Response:
- * +-------------+---+---+-----------------------+
- * | status : 2B | 0 | 0 | read payload : <= 60B |
- * +-------------+---+---+-----------------------+
+ * +-------------+---+---+--------------+
+ * | status : 2B | 0 | 0 | read payload |
+ * +-------------+---+---+--------------+
+ *
+ * - read payload might not fit into a single USB packets. Remaining will be
+ * transimitted witout header. Receiving side should concatenate them.
*
* status: 2 byte status
* 0x0000: Success
@@ -43,15 +79,15 @@
* This can happen if someone else has acquired the shared memory
* buffer that the I2C driver uses as /dev/null
* 0x0003: Write count invalid (mismatch with merged payload)
- * 0x0004: Read count invalid (> 60 bytes)
+ * 0x0004: Read count invalid (e.g. larger than available buffer)
* 0x0005: The port specified is invalid.
* 0x0006: The I2C interface is disabled.
* 0x8000: Unknown error mask
* The bottom 15 bits will contain the bottom 15 bits from the EC
* error code.
*
- * read payload: up to 60 bytes of data read from I2C, length will match
- * requested read count
+ * read payload: Depends on the buffer size and implementation. Length will
+ * match requested read count
*/
enum usb_i2c_error {
@@ -66,12 +102,18 @@ enum usb_i2c_error {
};
-#define USB_I2C_MAX_READ_COUNT 60
-#define USB_I2C_CONFIG_BUFFER_SIZE \
- ((CONFIG_USB_I2C_MAX_WRITE_COUNT+4) > USB_MAX_PACKET_SIZE ? \
- (CONFIG_USB_I2C_MAX_WRITE_COUNT+4) : USB_MAX_PACKET_SIZE)
+#define USB_I2C_WRITE_BUFFER (CONFIG_USB_I2C_MAX_WRITE_COUNT + 4)
+/* If read payload is larger or equal to 128 bytes, header contains rc1 */
+#define USB_I2C_READ_BUFFER ((CONFIG_USB_I2C_MAX_READ_COUNT < 128) ? \
+ (CONFIG_USB_I2C_MAX_READ_COUNT + 4) : \
+ (CONFIG_USB_I2C_MAX_READ_COUNT + 6))
+
+#define USB_I2C_BUFFER_SIZE \
+ (USB_I2C_READ_BUFFER > USB_I2C_WRITE_BUFFER ? \
+ USB_I2C_READ_BUFFER : USB_I2C_WRITE_BUFFER)
-BUILD_ASSERT(USB_MAX_PACKET_SIZE == (2 + 1 + 1 + USB_I2C_MAX_READ_COUNT));
+BUILD_ASSERT(POWER_OF_TWO(USB_I2C_READ_BUFFER));
+BUILD_ASSERT(POWER_OF_TWO(USB_I2C_WRITE_BUFFER));
/*
* Compile time Per-USB gpio configuration stored in flash. Instances of this
@@ -110,7 +152,7 @@ extern struct consumer_ops const usb_i2c_consumer_ops;
ENDPOINT) \
static uint16_t \
CONCAT2(NAME, _buffer_) \
- [USB_I2C_CONFIG_BUFFER_SIZE / 2]; \
+ [USB_I2C_BUFFER_SIZE / 2]; \
static void CONCAT2(NAME, _deferred_)(void); \
DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \
static struct queue const CONCAT2(NAME, _to_usb_); \
@@ -136,10 +178,10 @@ extern struct consumer_ops const usb_i2c_consumer_ops;
.tx_queue = &CONCAT2(NAME, _to_usb_), \
}; \
static struct queue const CONCAT2(NAME, _to_usb_) = \
- QUEUE_DIRECT(USB_MAX_PACKET_SIZE, uint8_t, \
+ QUEUE_DIRECT(USB_I2C_READ_BUFFER, uint8_t, \
null_producer, CONCAT2(NAME, _usb_).consumer); \
static struct queue const CONCAT3(usb_to_, NAME, _) = \
- QUEUE_DIRECT(CONFIG_USB_I2C_MAX_WRITE_COUNT+4, uint8_t, \
+ QUEUE_DIRECT(USB_I2C_WRITE_BUFFER, uint8_t, \
CONCAT2(NAME, _usb_).producer, NAME.consumer); \
static void CONCAT2(NAME, _deferred_)(void) \
{ usb_i2c_deferred(&NAME); }