|
@@ -209,11 +209,60 @@ static struct regmap_bus regmap_i2c = {
|
|
|
.val_format_endian_default = REGMAP_ENDIAN_BIG,
|
|
|
};
|
|
|
|
|
|
+static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
|
|
|
+ size_t count)
|
|
|
+{
|
|
|
+ struct device *dev = context;
|
|
|
+ struct i2c_client *i2c = to_i2c_client(dev);
|
|
|
+
|
|
|
+ if (count < 1)
|
|
|
+ return -EINVAL;
|
|
|
+ if (count >= I2C_SMBUS_BLOCK_MAX)
|
|
|
+ return -E2BIG;
|
|
|
+
|
|
|
+ --count;
|
|
|
+ return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
|
|
|
+ ((u8 *)data + 1));
|
|
|
+}
|
|
|
+
|
|
|
+static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
|
|
|
+ size_t reg_size, void *val,
|
|
|
+ size_t val_size)
|
|
|
+{
|
|
|
+ struct device *dev = context;
|
|
|
+ struct i2c_client *i2c = to_i2c_client(dev);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (reg_size != 1 || val_size < 1)
|
|
|
+ return -EINVAL;
|
|
|
+ if (val_size >= I2C_SMBUS_BLOCK_MAX)
|
|
|
+ return -E2BIG;
|
|
|
+
|
|
|
+ ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
|
|
|
+ if (ret == val_size)
|
|
|
+ return 0;
|
|
|
+ else if (ret < 0)
|
|
|
+ return ret;
|
|
|
+ else
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
+
|
|
|
+static struct regmap_bus regmap_i2c_smbus_i2c_block = {
|
|
|
+ .write = regmap_i2c_smbus_i2c_write,
|
|
|
+ .read = regmap_i2c_smbus_i2c_read,
|
|
|
+ .max_raw_read = I2C_SMBUS_BLOCK_MAX,
|
|
|
+ .max_raw_write = I2C_SMBUS_BLOCK_MAX,
|
|
|
+};
|
|
|
+
|
|
|
static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
|
|
|
const struct regmap_config *config)
|
|
|
{
|
|
|
if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
|
|
|
return ®map_i2c;
|
|
|
+ else if (config->reg_bits == 8 &&
|
|
|
+ i2c_check_functionality(i2c->adapter,
|
|
|
+ I2C_FUNC_SMBUS_I2C_BLOCK))
|
|
|
+ return ®map_i2c_smbus_i2c_block;
|
|
|
else if (config->val_bits == 16 && config->reg_bits == 8 &&
|
|
|
i2c_check_functionality(i2c->adapter,
|
|
|
I2C_FUNC_SMBUS_WORD_DATA))
|