From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thierry Reding Date: Tue, 26 Aug 2014 17:34:01 +0200 Subject: [U-Boot] [PATCH v2 13/40] i2c: Add high-level API In-Reply-To: <1409067268-956-1-git-send-email-thierry.reding@gmail.com> References: <1409067268-956-1-git-send-email-thierry.reding@gmail.com> Message-ID: <1409067268-956-14-git-send-email-thierry.reding@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Thierry Reding This API operates on I2C adapters or I2C clients (a new type of object that refers to a particular slave connected to an adapter). This is useful to avoid having to call i2c_set_bus_num() whenever a device is being accessed. Drivers for I2C devices are supposed to embed a struct i2c_client within a driver-specific data structure and call i2c_client_init() on it, passing in a pointer to the parent I2C adapter and the slave address of the device. Signed-off-by: Thierry Reding --- drivers/i2c/i2c_core.c | 53 ++++++++++++++++++++++++++++ include/i2c.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c index f6179a16244b..88c7af546b0b 100644 --- a/drivers/i2c/i2c_core.c +++ b/drivers/i2c/i2c_core.c @@ -410,3 +410,56 @@ void __i2c_init(int speed, int slaveaddr) } void i2c_init(int speed, int slaveaddr) __attribute__((weak, alias("__i2c_init"))); + +struct i2c_adapter *i2c_adapter_get(unsigned int index) +{ + struct i2c_adapter *adapter = ll_entry_start(struct i2c_adapter, i2c); + unsigned int num = ll_entry_count(struct i2c_adapter, i2c); + unsigned int i; + + if (index >= num) + return NULL; + + for (i = 0; i < index; i++) + adapter++; + + i2c_adapter_init(adapter, adapter->speed, adapter->slaveaddr); + return adapter; +} + +int i2c_adapter_read(struct i2c_adapter *adapter, uint8_t chip, + unsigned int address, size_t alen, void *buffer, + size_t size) +{ + return adapter->read(adapter, chip, address, alen, buffer, size); +} + +int i2c_adapter_write(struct i2c_adapter *adapter, uint8_t chip, + unsigned int address, size_t alen, void *buffer, + size_t size) +{ + return adapter->write(adapter, chip, address, alen, buffer, size); +} + +int i2c_client_init(struct i2c_client *client, struct i2c_adapter *adapter, + uint8_t address) +{ + client->adapter = adapter; + client->address = address; + + return 0; +} + +int i2c_client_read(struct i2c_client *client, unsigned int address, + size_t alen, void *buffer, size_t size) +{ + return i2c_adapter_read(client->adapter, client->address, address, + alen, buffer, size); +} + +int i2c_client_write(struct i2c_client *client, unsigned int address, + size_t alen, void *buffer, size_t size) +{ + return i2c_adapter_write(client->adapter, client->address, address, + alen, buffer, size); +} diff --git a/include/i2c.h b/include/i2c.h index 1b4078ed62fe..8f73ba93c614 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -55,6 +55,20 @@ #define CONFIG_SYS_SPD_BUS_NUM 0 #endif +/** + * struct i2c_adapter - I2C adapter + * @init: initialize I2C adapter + * @probe: probe for a device on the I2C bus + * @read: read data from a device on the I2C bus + * @write: write data to a device on the I2C bus + * @set_bus_speed: configure the I2C bus speed + * @speed: current I2C bus speed + * @waitdelay: + * @slaveaddr: own address (when used as a slave) + * @init_done: flag to indicate whether or not the adapter has been initialized + * @hwadapnr: the hardware number of this adapter + * @name: name of this adapter + */ struct i2c_adapter { void (*init)(struct i2c_adapter *adap, int speed, int slaveaddr); @@ -75,6 +89,16 @@ struct i2c_adapter { char *name; }; +/** + * struct i2c_client - I2C slave + * @adapter: I2C adapter providing the slave's parent bus + * address: address of the I2C slave on the parent bus + */ +struct i2c_client { + struct i2c_adapter *adapter; + unsigned int address; +}; + #define U_BOOT_I2C_MKENT_COMPLETE(_init, _probe, _read, _write, \ _set_speed, _speed, _slaveaddr, _hwadapnr, _name) \ { \ @@ -271,6 +295,78 @@ unsigned int i2c_get_bus_speed(void); * Adjusts I2C pointers after U-Boot is relocated to DRAM */ void i2c_reloc_fixup(void); + +/* + * i2c_adapter_get() - get the I2C adapter associated with a given index + * @index: index of the I2C adapter + */ +struct i2c_adapter *i2c_adapter_get(unsigned int index); + +/* + * i2c_adapter_read() - read data from an I2C slave at a given address + * @adapter: I2C adapter + * @chip: address of the I2C slave to read from + * @address: address within the I2C slave to read from + * @alen: length of address + * @buffer: buffer to receive data from I2C slave + * @size: number of bytes to read + */ +int i2c_adapter_read(struct i2c_adapter *adapter, uint8_t chip, + unsigned int address, size_t alen, void *buffer, + size_t size); + +/* + * i2c_adapter_write() - write data to an I2C slave at a given address + * @adapter: I2C adapter + * @chip: address of the I2C slave to write to + * @address: address within the I2C slave to write to + * @alen: length of address + * @buffer: buffer containing the data to write + * @size: number of bytes to write + * + * Ideally the function would take a const void * buffer, but the underlying + * infrastructure doesn't properly propagate const and adding it here would + * cause a lot of build warnings. + */ +int i2c_adapter_write(struct i2c_adapter *adapter, uint8_t chip, + unsigned int address, size_t alen, void *buffer, + size_t size); + +/* + * i2c_client_init() - initialize an I2C slave + * @client: I2C slave + * @adapter: parent I2C adapter + * @address: address of I2C slave + */ +int i2c_client_init(struct i2c_client *client, struct i2c_adapter *adapter, + uint8_t address); + +/* + * i2c_client_read() - read data from an I2C slave + * @client: I2C slave + * @address: address within the I2C slave to read from + * @alen: length of address + * @buffer: buffer to receive data from I2C slave + * @size: number of bytes to read + */ +int i2c_client_read(struct i2c_client *client, unsigned int address, + size_t alen, void *buffer, size_t size); + +/* + * i2c_client_write() - write data to an I2C slave + * @client: I2C slave + * @address: address within the I2C slave to write to + * @alen: length of address + * @buffer: buffer containing the data to write + * @size: number of bytes to write + * + * Ideally the function would take a const void * buffer, but the underlying + * infrastructure doesn't properly propagate const and adding it here would + * cause a lot of build warnings. + */ +int i2c_client_write(struct i2c_client *client, unsigned int address, + size_t alen, void *buffer, size_t size); + #if defined(CONFIG_SYS_I2C_SOFT) void i2c_soft_init(void); void i2c_soft_active(void); -- 2.0.4