summaryrefslogtreecommitdiff
path: root/common/i2c_master.c
diff options
context:
space:
mode:
authorJonathan Brandmeyer <jbrandmeyer@chromium.org>2018-08-07 16:02:57 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-08-09 11:40:02 -0700
commit21e235dbe468bfa80bab86900ab4baeb48533a94 (patch)
tree29abed0575657333d8402ab663587988f548263c /common/i2c_master.c
parentab6090e0c013519968a85661353c4d635cb78386 (diff)
downloadchrome-ec-21e235dbe468bfa80bab86900ab4baeb48533a94.tar.gz
i2c master: Add block read/write commands.
These commands are used by several modules that manage their own block read/write protocols today. This is the first of a series that refactors several modules to use the I2C driver functions instead of their own. BUG=chromium:871851 BRANCH=none TEST=make -j buildall; USB-PD and motionsense testing on Grunt convertible, which exercises several users of the new interface. Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Change-Id: I08475a72031e5fbf49dc344d5b4858622f0d5e93 Reviewed-on: https://chromium-review.googlesource.com/1167957 Commit-Ready: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Tested-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common/i2c_master.c')
-rw-r--r--common/i2c_master.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/common/i2c_master.c b/common/i2c_master.c
index 7915451b32..aa6340610c 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -322,6 +322,42 @@ exit:
return rv;
}
+int i2c_read_block(int port, int slave_addr, int offset, uint8_t *data,
+ int len)
+{
+ int rv;
+ uint8_t reg_address = offset;
+
+ i2c_lock(port, 1);
+ rv = i2c_xfer(port, slave_addr, &reg_address, 1, data, len,
+ I2C_XFER_SINGLE);
+ i2c_lock(port, 0);
+ return rv;
+}
+
+int i2c_write_block(int port, int slave_addr, int offset, const uint8_t *data,
+ int len)
+{
+ int rv0, rv1;
+ uint8_t reg_address = offset;
+
+ /*
+ * Split into two transactions to avoid the stack space consumption of
+ * appending the destination address with the data array. Even if the
+ * first transaction fails, unconditionally perform the second one in
+ * order to have a better chance at sending out the stop bit.
+ */
+ i2c_lock(port, 1);
+ rv0 = i2c_xfer(port, slave_addr, &reg_address, 1, NULL, 0,
+ I2C_XFER_START);
+ rv1 = i2c_xfer(port, slave_addr, data, len, NULL, 0,
+ I2C_XFER_STOP);
+ i2c_lock(port, 0);
+
+ /* Guess that the first error seen is more helpful. */
+ return (rv0 != EC_SUCCESS) ? rv0 : rv1;
+}
+
int get_sda_from_i2c_port(int port, enum gpio_signal *sda)
{
const struct i2c_port_t *i2c_port = get_i2c_port(port);