From e5b17f90474f2946cb29aa5828c2642fbfffdfa8 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Mon, 13 Feb 2012 14:45:29 -0800 Subject: [PATCH] Add 8-bit I2C read/write functions. These provide 8-bit accesses to registers within an I2C device. BUG=chrome-os-partner:7839 TEST=none Testing will come when I start using them. Change-Id: Ib53d3347253bccee93cb9c5da12db92970155d92 Signed-off-by: Bill Richardson --- chip/lm4/i2c.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/i2c.h | 10 +++++++++ 2 files changed, 65 insertions(+) diff --git a/chip/lm4/i2c.c b/chip/lm4/i2c.c index aa30a2f56a..614ef5c3a9 100644 --- a/chip/lm4/i2c.c +++ b/chip/lm4/i2c.c @@ -126,6 +126,61 @@ int i2c_write16(int port, int slave_addr, int offset, int data) return wait_idle(port); } +/* TODO:(crosbug.com/p/8026) combine common functions to save space */ + +int i2c_read8(int port, int slave_addr, int offset, int* data) +{ + int rv; + + *data = 0; + + /* Transmit the offset address to the slave; leave the master in + * transmit state. */ + LM4_I2C_MSA(port) = slave_addr & 0xff; + LM4_I2C_MDR(port) = offset & 0xff; + LM4_I2C_MCS(port) = 0x03; + + rv = wait_idle(port); + if (rv) + return rv; + + /* Send repeated start followed by receive and stop */ + LM4_I2C_MSA(port) = (slave_addr & 0xff) | 0x01; + LM4_I2C_MCS(port) = 0x07; /* NOTE: datasheet suggests 0x0b, but + * 0x07 with the change in direction + * flips it to a RECEIVE and STOP. + * I think. + */ + rv = wait_idle(port); + if (rv) + return rv; + + /* Read the byte */ + *data = LM4_I2C_MDR(port) & 0xff; + + return EC_SUCCESS; +} + +int i2c_write8(int port, int slave_addr, int offset, int data) +{ + int rv; + + /* Transmit the offset address to the slave; leave the master in + * transmit state. */ + LM4_I2C_MDR(port) = offset & 0xff; + LM4_I2C_MSA(port) = slave_addr & 0xff; + LM4_I2C_MCS(port) = 0x03; + + rv = wait_idle(port); + if (rv) + return rv; + + /* Send repeated start followed by transmit and stop */ + LM4_I2C_MDR(port) = data & 0xff; + LM4_I2C_MCS(port) = 0x05; + + return wait_idle(port); +} /*****************************************************************************/ /* Interrupt handlers */ diff --git a/include/i2c.h b/include/i2c.h index 34076b1f34..c3301e530d 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -26,4 +26,14 @@ int i2c_read16(int port, int slave_addr, int offset, int* data); * space. */ int i2c_write16(int port, int slave_addr, int offset, int data); +/* Reads an 8-bit register from the slave at 8-bit slave address + * , at the specified 8-bit in the slave's address + * space. */ +int i2c_read8(int port, int slave_addr, int offset, int* data); + +/* Writes an 8-bit register to the slave at 8-bit slave address + * , at the specified 8-bit in the slave's address + * space. */ +int i2c_write8(int port, int slave_addr, int offset, int data); + #endif /* __CROS_EC_I2C_H */