I2C: Add 16-bit read/write functions
Some audio codecs (RealTek) have 16-bit data regs. Use these
functions to access them on Ryu, etc.
BUG=none
BRANCH=none
TEST=Enabled RealTek 5677 codec on Ryu and was able to read
and write codec registers, reset the codec, etc.
Change-Id: I48e5adfa9d01a7662e6fe3d7f143c1bd996f538b
Signed-off-by: Tom Warren <twarren@nvidia.com>
Reviewed-on: https://chromium-review.googlesource.com/228200
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/drivers/bus/i2c/i2c.c b/src/drivers/bus/i2c/i2c.c
index bcab590..01ce7a6 100644
--- a/src/drivers/bus/i2c/i2c.c
+++ b/src/drivers/bus/i2c/i2c.c
@@ -46,3 +46,36 @@
return ops->transfer(ops, &seg, 1);
}
+
+int i2c_readw(I2cOps *ops, uint8_t chip, uint8_t reg, uint16_t *data)
+{
+ I2cSeg seg[2];
+ int ret;
+ uint8_t bytes[2];
+
+ seg[0].read = 0;
+ seg[0].chip = chip;
+ seg[0].buf = ®
+ seg[0].len = 1;
+ seg[1].read = 1;
+ seg[1].chip = chip;
+ seg[1].buf = &bytes[0];
+ seg[1].len = 2;
+
+ ret = ops->transfer(ops, seg, ARRAY_SIZE(seg));
+ *data = (uint16_t)(bytes[0] << 8) + bytes[1];
+ return ret;
+}
+
+int i2c_writew(I2cOps *ops, uint8_t chip, uint8_t reg, uint16_t data)
+{
+ I2cSeg seg;
+ uint8_t buf[3] = {reg, data >> 8, data & 0xFF};
+
+ seg.read = 0;
+ seg.chip = chip;
+ seg.buf = buf;
+ seg.len = ARRAY_SIZE(buf);
+
+ return ops->transfer(ops, &seg, 1);
+}
diff --git a/src/drivers/bus/i2c/i2c.h b/src/drivers/bus/i2c/i2c.h
index 37e624c..62415d6 100644
--- a/src/drivers/bus/i2c/i2c.h
+++ b/src/drivers/bus/i2c/i2c.h
@@ -80,4 +80,18 @@
*/
int i2c_writeb(I2cOps *ops, uint8_t chip, uint8_t reg, uint8_t data);
+/**
+ * Read a word by 2 segments in one frame
+ *
+ * [start][slave addr][w][register addr][start][slave addr][r][data byte high][data byte low][stop]
+ */
+int i2c_readw(I2cOps *ops, uint8_t chip, uint8_t reg, uint16_t *data);
+
+/**
+ * Write a word by one segment in one frame.
+ *
+ * [start][slave addr][w][register addr][data byte high][data byte low][stop]
+ */
+int i2c_writew(I2cOps *ops, uint8_t chip, uint8_t reg, uint16_t data);
+
#endif /* __DRIVERS_BUS_I2C_I2C_H__ */