diff options
| -rw-r--r-- | drivers/base/regmap/internal.h | 4 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap-ac97.c | 4 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 46 | ||||
| -rw-r--r-- | drivers/base/regmap/regmap.c | 7 | ||||
| -rw-r--r-- | include/linux/regmap.h | 2 |
5 files changed, 56 insertions, 7 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 8e94584b0d26..beb8b27d4621 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
| @@ -235,6 +235,10 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
| 235 | 235 | ||
| 236 | void regmap_async_complete_cb(struct regmap_async *async, int ret); | 236 | void regmap_async_complete_cb(struct regmap_async *async, int ret); |
| 237 | 237 | ||
| 238 | enum regmap_endian regmap_get_val_endian(struct device *dev, | ||
| 239 | const struct regmap_bus *bus, | ||
| 240 | const struct regmap_config *config); | ||
| 241 | |||
| 238 | extern struct regcache_ops regcache_rbtree_ops; | 242 | extern struct regcache_ops regcache_rbtree_ops; |
| 239 | extern struct regcache_ops regcache_lzo_ops; | 243 | extern struct regcache_ops regcache_lzo_ops; |
| 240 | extern struct regcache_ops regcache_flat_ops; | 244 | extern struct regcache_ops regcache_flat_ops; |
diff --git a/drivers/base/regmap/regmap-ac97.c b/drivers/base/regmap/regmap-ac97.c index e4c45d2299c1..8d304e2a943d 100644 --- a/drivers/base/regmap/regmap-ac97.c +++ b/drivers/base/regmap/regmap-ac97.c | |||
| @@ -74,8 +74,8 @@ static int regmap_ac97_reg_write(void *context, unsigned int reg, | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static const struct regmap_bus ac97_regmap_bus = { | 76 | static const struct regmap_bus ac97_regmap_bus = { |
| 77 | .reg_write = regmap_ac97_reg_write, | 77 | .reg_write = regmap_ac97_reg_write, |
| 78 | .reg_read = regmap_ac97_reg_read, | 78 | .reg_read = regmap_ac97_reg_read, |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | /** | 81 | /** |
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)) |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index d2f8a818d200..f99b098ddabf 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
| @@ -473,9 +473,9 @@ static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus, | |||
| 473 | return REGMAP_ENDIAN_BIG; | 473 | return REGMAP_ENDIAN_BIG; |
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | static enum regmap_endian regmap_get_val_endian(struct device *dev, | 476 | enum regmap_endian regmap_get_val_endian(struct device *dev, |
| 477 | const struct regmap_bus *bus, | 477 | const struct regmap_bus *bus, |
| 478 | const struct regmap_config *config) | 478 | const struct regmap_config *config) |
| 479 | { | 479 | { |
| 480 | struct device_node *np; | 480 | struct device_node *np; |
| 481 | enum regmap_endian endian; | 481 | enum regmap_endian endian; |
| @@ -513,6 +513,7 @@ static enum regmap_endian regmap_get_val_endian(struct device *dev, | |||
| 513 | /* Use this if no other value was found */ | 513 | /* Use this if no other value was found */ |
| 514 | return REGMAP_ENDIAN_BIG; | 514 | return REGMAP_ENDIAN_BIG; |
| 515 | } | 515 | } |
| 516 | EXPORT_SYMBOL_GPL(regmap_get_val_endian); | ||
| 516 | 517 | ||
| 517 | /** | 518 | /** |
| 518 | * regmap_init(): Initialise register map | 519 | * regmap_init(): Initialise register map |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 4419b99d8d6e..116655d92269 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
| @@ -468,7 +468,7 @@ bool regmap_reg_in_ranges(unsigned int reg, | |||
| 468 | * | 468 | * |
| 469 | * @reg: Offset of the register within the regmap bank | 469 | * @reg: Offset of the register within the regmap bank |
| 470 | * @lsb: lsb of the register field. | 470 | * @lsb: lsb of the register field. |
| 471 | * @reg: msb of the register field. | 471 | * @msb: msb of the register field. |
| 472 | * @id_size: port size if it has some ports | 472 | * @id_size: port size if it has some ports |
| 473 | * @id_offset: address offset for each ports | 473 | * @id_offset: address offset for each ports |
| 474 | */ | 474 | */ |
