aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorIrina Tirdea <irina.tirdea@intel.com>2015-08-12 10:31:33 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-08-24 08:05:19 -0400
commit01eef96e37d77cd89156e5f51aab81a9d5c96539 (patch)
treeb6d1c3a0107448bdf6371fbe5b7d610594045ee9 /drivers/i2c
parent3f9c37a0c9a59db97ca5712eca7838b842949047 (diff)
i2c: core: Add support for best effort block read emulation
There are devices that need to handle block transactions regardless of the capabilities exported by the adapter. For performance reasons, they need to use i2c read blocks if available, otherwise emulate the block transaction with word or byte transactions. Add support for a helper function that would read a data block using the best transfer available: I2C_FUNC_SMBUS_READ_I2C_BLOCK, I2C_FUNC_SMBUS_READ_WORD_DATA or I2C_FUNC_SMBUS_READ_BYTE_DATA. Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c-core.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a6780289c61d..98f6c75b1d18 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -3007,6 +3007,63 @@ trace:
3007} 3007}
3008EXPORT_SYMBOL(i2c_smbus_xfer); 3008EXPORT_SYMBOL(i2c_smbus_xfer);
3009 3009
3010/**
3011 * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
3012 * @client: Handle to slave device
3013 * @command: Byte interpreted by slave
3014 * @length: Size of data block; SMBus allows at most I2C_SMBUS_BLOCK_MAX bytes
3015 * @values: Byte array into which data will be read; big enough to hold
3016 * the data returned by the slave. SMBus allows at most
3017 * I2C_SMBUS_BLOCK_MAX bytes.
3018 *
3019 * This executes the SMBus "block read" protocol if supported by the adapter.
3020 * If block read is not supported, it emulates it using either word or byte
3021 * read protocols depending on availability.
3022 *
3023 * The addresses of the I2C slave device that are accessed with this function
3024 * must be mapped to a linear region, so that a block read will have the same
3025 * effect as a byte read. Before using this function you must double-check
3026 * if the I2C slave does support exchanging a block transfer with a byte
3027 * transfer.
3028 */
3029s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
3030 u8 command, u8 length, u8 *values)
3031{
3032 u8 i = 0;
3033 int status;
3034
3035 if (length > I2C_SMBUS_BLOCK_MAX)
3036 length = I2C_SMBUS_BLOCK_MAX;
3037
3038 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
3039 return i2c_smbus_read_i2c_block_data(client, command, length, values);
3040
3041 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
3042 return -EOPNOTSUPP;
3043
3044 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) {
3045 while ((i + 2) <= length) {
3046 status = i2c_smbus_read_word_data(client, command + i);
3047 if (status < 0)
3048 return status;
3049 values[i] = status & 0xff;
3050 values[i + 1] = status >> 8;
3051 i += 2;
3052 }
3053 }
3054
3055 while (i < length) {
3056 status = i2c_smbus_read_byte_data(client, command + i);
3057 if (status < 0)
3058 return status;
3059 values[i] = status;
3060 i++;
3061 }
3062
3063 return i;
3064}
3065EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated);
3066
3010#if IS_ENABLED(CONFIG_I2C_SLAVE) 3067#if IS_ENABLED(CONFIG_I2C_SLAVE)
3011int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) 3068int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
3012{ 3069{