diff options
Diffstat (limited to 'drivers/base/regmap/regmap-i2c.c')
| -rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 053150a7f9f2..4b76e33110a2 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | 16 | ||
| 17 | #include "internal.h" | ||
| 17 | 18 | ||
| 18 | static int regmap_smbus_byte_reg_read(void *context, unsigned int reg, | 19 | static int regmap_smbus_byte_reg_read(void *context, unsigned int reg, |
| 19 | unsigned int *val) | 20 | unsigned int *val) |
| @@ -87,6 +88,42 @@ static struct regmap_bus regmap_smbus_word = { | |||
| 87 | .reg_read = regmap_smbus_word_reg_read, | 88 | .reg_read = regmap_smbus_word_reg_read, |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 91 | static int regmap_smbus_word_read_swapped(void *context, unsigned int reg, | ||
| 92 | unsigned int *val) | ||
| 93 | { | ||
| 94 | struct device *dev = context; | ||
| 95 | struct i2c_client *i2c = to_i2c_client(dev); | ||
| 96 | int ret; | ||
| 97 | |||
| 98 | if (reg > 0xff) | ||
| 99 | return -EINVAL; | ||
| 100 | |||
| 101 | ret = i2c_smbus_read_word_swapped(i2c, reg); | ||
| 102 | if (ret < 0) | ||
| 103 | return ret; | ||
| 104 | |||
| 105 | *val = ret; | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int regmap_smbus_word_write_swapped(void *context, unsigned int reg, | ||
| 111 | unsigned int val) | ||
| 112 | { | ||
| 113 | struct device *dev = context; | ||
| 114 | struct i2c_client *i2c = to_i2c_client(dev); | ||
| 115 | |||
| 116 | if (val > 0xffff || reg > 0xff) | ||
| 117 | return -EINVAL; | ||
| 118 | |||
| 119 | return i2c_smbus_write_word_swapped(i2c, reg, val); | ||
| 120 | } | ||
| 121 | |||
| 122 | static struct regmap_bus regmap_smbus_word_swapped = { | ||
| 123 | .reg_write = regmap_smbus_word_write_swapped, | ||
| 124 | .reg_read = regmap_smbus_word_read_swapped, | ||
| 125 | }; | ||
| 126 | |||
| 90 | static int regmap_i2c_write(void *context, const void *data, size_t count) | 127 | static int regmap_i2c_write(void *context, const void *data, size_t count) |
| 91 | { | 128 | { |
| 92 | struct device *dev = context; | 129 | struct device *dev = context; |
| @@ -180,7 +217,14 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, | |||
| 180 | else if (config->val_bits == 16 && config->reg_bits == 8 && | 217 | else if (config->val_bits == 16 && config->reg_bits == 8 && |
| 181 | i2c_check_functionality(i2c->adapter, | 218 | i2c_check_functionality(i2c->adapter, |
| 182 | I2C_FUNC_SMBUS_WORD_DATA)) | 219 | I2C_FUNC_SMBUS_WORD_DATA)) |
| 183 | return ®map_smbus_word; | 220 | switch (regmap_get_val_endian(&i2c->dev, NULL, config)) { |
| 221 | case REGMAP_ENDIAN_LITTLE: | ||
| 222 | return ®map_smbus_word; | ||
| 223 | case REGMAP_ENDIAN_BIG: | ||
| 224 | return ®map_smbus_word_swapped; | ||
| 225 | default: /* everything else is not supported */ | ||
| 226 | break; | ||
| 227 | } | ||
| 184 | else if (config->val_bits == 8 && config->reg_bits == 8 && | 228 | else if (config->val_bits == 8 && config->reg_bits == 8 && |
| 185 | i2c_check_functionality(i2c->adapter, | 229 | i2c_check_functionality(i2c->adapter, |
| 186 | I2C_FUNC_SMBUS_BYTE_DATA)) | 230 | I2C_FUNC_SMBUS_BYTE_DATA)) |
