diff options
-rw-r--r-- | common/i2c.c | 12 | ||||
-rw-r--r-- | include/config.h | 10 | ||||
-rw-r--r-- | include/i2c.h | 38 |
3 files changed, 50 insertions, 10 deletions
diff --git a/common/i2c.c b/common/i2c.c index 05d7f1a703..800922adea 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -26,10 +26,20 @@ #define CPUTS(outstr) cputs(CC_I2C, outstr) #define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) -static struct mutex port_mutex[I2C_PORT_COUNT]; +/* Only chips with multi-port controllers will define I2C_CONTROLER_COUNT */ +#ifndef I2C_CONTROLLER_COUNT +#define I2C_CONTROLLER_COUNT I2C_PORT_COUNT +#endif + +static struct mutex port_mutex[I2C_CONTROLLER_COUNT]; void i2c_lock(int port, int lock) { +#ifdef CONFIG_I2C_MULTI_PORT_CONTROLLER + /* Lock the controller, not the port */ + port = i2c_port_to_controller(port); + ASSERT(port != -1); +#endif if (lock) { /* Don't allow deep sleep when I2C port is locked */ disable_sleep(SLEEP_MASK_I2C); diff --git a/include/config.h b/include/config.h index d112e88dd7..97460a88ac 100644 --- a/include/config.h +++ b/include/config.h @@ -778,6 +778,16 @@ #undef CONFIG_I2C_SCL_GATE_ADDR #undef CONFIG_I2C_SCL_GATE_GPIO +/* + * I2C multi-port controller. + * + * If CONFIG_I2C_MULTI_PORT_CONTROLLER is defined, a single on-chip I2C + * controller may have multiple I2C ports attached. Therefore, I2c operations + * must lock the controller (not just the port) to prevent hardware access + * conflicts. + */ +#undef CONFIG_I2C_MULTI_PORT_CONTROLLER + /*****************************************************************************/ /* Current/Power monitor */ diff --git a/include/i2c.h b/include/i2c.h index a4e105ddac..753efa0aec 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -134,20 +134,28 @@ void i2c_lock(int port, int lock); */ void i2c_set_timeout(int port, uint32_t timeout); -/* Read a 16-bit register from the slave at 8-bit slave address <slaveaddr>, at - * the specified 8-bit <offset> in the slave's address space. */ +/** + * Read a 16-bit register from the slave at 8-bit slave address <slaveaddr>, at + * the specified 8-bit <offset> in the slave's address space. + */ int i2c_read16(int port, int slave_addr, int offset, int *data); -/* Write a 16-bit register to the slave at 8-bit slave address <slaveaddr>, at - * the specified 8-bit <offset> in the slave's address space. */ +/** + * Write a 16-bit register to the slave at 8-bit slave address <slaveaddr>, at + * the specified 8-bit <offset> in the slave's address space. + */ int i2c_write16(int port, int slave_addr, int offset, int data); -/* Read an 8-bit register from the slave at 8-bit slave address <slaveaddr>, at - * the specified 8-bit <offset> in the slave's address space. */ +/** + * Read an 8-bit register from the slave at 8-bit slave address <slaveaddr>, at + * the specified 8-bit <offset> in the slave's address space. + */ int i2c_read8(int port, int slave_addr, int offset, int *data); -/* Write an 8-bit register to the slave at 8-bit slave address <slaveaddr>, at - * the specified 8-bit <offset> in the slave's address space. */ +/** + * Write an 8-bit register to the slave at 8-bit slave address <slaveaddr>, at + * the specified 8-bit <offset> in the slave's address space. + */ int i2c_write8(int port, int slave_addr, int offset, int data); /** @@ -164,7 +172,8 @@ int i2c_is_busy(int port); */ int i2c_unwedge(int port); -/* Read ascii string using smbus read block protocol. +/** + * Read ascii string using smbus read block protocol. * Read bytestream from <slaveaddr>:<offset> with format: * [length_N] [byte_0] [byte_1] ... [byte_N-1] * @@ -176,4 +185,15 @@ int i2c_unwedge(int port); int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data, int len); +/** + * Convert port number to controller number, for multi-port controllers. + * This function will only be called if CONFIG_I2C_MULTI_PORT_CONTROLLER is + * defined. + * + * @parm port I2C port + * + * @return controller number, or -1 on invalid parameter + */ +int i2c_port_to_controller(int port); + #endif /* __CROS_EC_I2C_H */ |