diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-rtl9300.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c index af991b28e4f8..9e6232075137 100644 --- a/drivers/i2c/busses/i2c-rtl9300.c +++ b/drivers/i2c/busses/i2c-rtl9300.c @@ -186,22 +186,32 @@ static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write, return -EIO; if (read_write == I2C_SMBUS_READ) { - if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) { + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: ret = regmap_read(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val); if (ret) return ret; data->byte = val & 0xff; - } else if (size == I2C_SMBUS_WORD_DATA) { + break; + case I2C_SMBUS_WORD_DATA: ret = regmap_read(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val); if (ret) return ret; data->word = val & 0xffff; - } else { + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + ret = rtl9300_i2c_read(i2c, &data->block[1], len); + if (ret) + return ret; + break; + default: ret = rtl9300_i2c_read(i2c, &data->block[0], len); if (ret) return ret; + break; } } @@ -290,6 +300,25 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s len = data->block[0] + 1; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); + if (ret) + goto out_unlock; + if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) { + ret = -EINVAL; + goto out_unlock; + } + ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]); + if (ret) + goto out_unlock; + if (read_write == I2C_SMBUS_WRITE) { + ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]); + if (ret) + goto out_unlock; + } + len = data->block[0]; + break; + default: dev_err(&adap->dev, "Unsupported transaction %d\n", size); ret = -EOPNOTSUPP; @@ -307,7 +336,8 @@ out_unlock: static u32 rtl9300_i2c_func(struct i2c_adapter *a) { return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA; + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; } static const struct i2c_algorithm rtl9300_i2c_algo = { |