diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-06-13 19:41:24 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-06-17 13:10:58 +0000 |
commit | cca70a517b21d32e45880d1296997436d026e7b7 (patch) | |
tree | 1c37f28074f4d9050070d7a540780fd592ff9719 /common/i2c.c | |
parent | b33531e262561e297ba1a02fc829a2110c6df515 (diff) | |
download | chrome-ec-cca70a517b21d32e45880d1296997436d026e7b7.tar.gz |
common: Add i2c 32bit read/write
Add functions and associated test to read/write a 32 bit register
BRANCH=smaug
TEST=Test on smaug with bm160 driver
BUG=chromium:39900
Change-Id: Ieff24b65f1eb8610874fe13c4a8fadf583a218cb
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/277535
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common/i2c.c')
-rw-r--r-- | common/i2c.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/common/i2c.c b/common/i2c.c index 4a851da39d..518bca0647 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -77,15 +77,68 @@ void i2c_prepare_sysjump(void) i2c_lock(i2c_ports[i].port, 1); } +int i2c_read32(int port, int slave_addr, int offset, int *data) +{ + int rv; + uint8_t reg, buf[sizeof(uint32_t)]; + + reg = offset & 0xff; + /* I2C read 32-bit word: transmit 8-bit offset, and read 32bits */ + i2c_lock(port, 1); + rv = i2c_xfer(port, slave_addr, ®, 1, buf, sizeof(uint32_t), + I2C_XFER_SINGLE); + i2c_lock(port, 0); + + if (rv) + return rv; + + if (slave_addr & I2C_FLAG_BIG_ENDIAN) + *data = ((int)buf[0] << 24) | ((int)buf[1] << 16) | + ((int)buf[0] << 8) | buf[1]; + else + *data = ((int)buf[3] << 24) | ((int)buf[2] << 16) | + ((int)buf[1] << 8) | buf[0]; + + return EC_SUCCESS; +} + +int i2c_write32(int port, int slave_addr, int offset, int data) +{ + int rv; + uint8_t buf[1 + sizeof(uint32_t)]; + + buf[0] = offset & 0xff; + + if (slave_addr & I2C_FLAG_BIG_ENDIAN) { + buf[1] = (data >> 24) & 0xff; + buf[2] = (data >> 16) & 0xff; + buf[3] = (data >> 8) & 0xff; + buf[4] = data & 0xff; + } else { + buf[1] = data & 0xff; + buf[2] = (data >> 8) & 0xff; + buf[3] = (data >> 16) & 0xff; + buf[4] = (data >> 24) & 0xff; + } + + i2c_lock(port, 1); + rv = i2c_xfer(port, slave_addr, buf, sizeof(uint32_t) + 1, NULL, 0, + I2C_XFER_SINGLE); + i2c_lock(port, 0); + + return rv; +} + int i2c_read16(int port, int slave_addr, int offset, int *data) { int rv; - uint8_t reg, buf[2]; + uint8_t reg, buf[sizeof(uint16_t)]; reg = offset & 0xff; /* I2C read 16-bit word: transmit 8-bit offset, and read 16bits */ i2c_lock(port, 1); - rv = i2c_xfer(port, slave_addr, ®, 1, buf, 2, I2C_XFER_SINGLE); + rv = i2c_xfer(port, slave_addr, ®, 1, buf, sizeof(uint16_t), + I2C_XFER_SINGLE); i2c_lock(port, 0); if (rv) @@ -102,7 +155,7 @@ int i2c_read16(int port, int slave_addr, int offset, int *data) int i2c_write16(int port, int slave_addr, int offset, int data) { int rv; - uint8_t buf[3]; + uint8_t buf[1 + sizeof(uint16_t)]; buf[0] = offset & 0xff; @@ -115,7 +168,8 @@ int i2c_write16(int port, int slave_addr, int offset, int data) } i2c_lock(port, 1); - rv = i2c_xfer(port, slave_addr, buf, 3, NULL, 0, I2C_XFER_SINGLE); + rv = i2c_xfer(port, slave_addr, buf, 1 + sizeof(uint16_t), NULL, 0, + I2C_XFER_SINGLE); i2c_lock(port, 0); return rv; |