|
@@ -119,13 +119,19 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
|
|
|
b[0] = val << shift;
|
|
|
}
|
|
|
|
|
|
-static void regmap_format_16(void *buf, unsigned int val, unsigned int shift)
|
|
|
+static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift)
|
|
|
{
|
|
|
__be16 *b = buf;
|
|
|
|
|
|
b[0] = cpu_to_be16(val << shift);
|
|
|
}
|
|
|
|
|
|
+static void regmap_format_16_native(void *buf, unsigned int val,
|
|
|
+ unsigned int shift)
|
|
|
+{
|
|
|
+ *(u16 *)buf = val << shift;
|
|
|
+}
|
|
|
+
|
|
|
static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
|
|
|
{
|
|
|
u8 *b = buf;
|
|
@@ -137,13 +143,19 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
|
|
|
b[2] = val;
|
|
|
}
|
|
|
|
|
|
-static void regmap_format_32(void *buf, unsigned int val, unsigned int shift)
|
|
|
+static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift)
|
|
|
{
|
|
|
__be32 *b = buf;
|
|
|
|
|
|
b[0] = cpu_to_be32(val << shift);
|
|
|
}
|
|
|
|
|
|
+static void regmap_format_32_native(void *buf, unsigned int val,
|
|
|
+ unsigned int shift)
|
|
|
+{
|
|
|
+ *(u32 *)buf = val << shift;
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int regmap_parse_8(void *buf)
|
|
|
{
|
|
|
u8 *b = buf;
|
|
@@ -151,7 +163,7 @@ static unsigned int regmap_parse_8(void *buf)
|
|
|
return b[0];
|
|
|
}
|
|
|
|
|
|
-static unsigned int regmap_parse_16(void *buf)
|
|
|
+static unsigned int regmap_parse_16_be(void *buf)
|
|
|
{
|
|
|
__be16 *b = buf;
|
|
|
|
|
@@ -160,6 +172,11 @@ static unsigned int regmap_parse_16(void *buf)
|
|
|
return b[0];
|
|
|
}
|
|
|
|
|
|
+static unsigned int regmap_parse_16_native(void *buf)
|
|
|
+{
|
|
|
+ return *(u16 *)buf;
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int regmap_parse_24(void *buf)
|
|
|
{
|
|
|
u8 *b = buf;
|
|
@@ -170,7 +187,7 @@ static unsigned int regmap_parse_24(void *buf)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static unsigned int regmap_parse_32(void *buf)
|
|
|
+static unsigned int regmap_parse_32_be(void *buf)
|
|
|
{
|
|
|
__be32 *b = buf;
|
|
|
|
|
@@ -179,6 +196,11 @@ static unsigned int regmap_parse_32(void *buf)
|
|
|
return b[0];
|
|
|
}
|
|
|
|
|
|
+static unsigned int regmap_parse_32_native(void *buf)
|
|
|
+{
|
|
|
+ return *(u32 *)buf;
|
|
|
+}
|
|
|
+
|
|
|
static void regmap_lock_mutex(struct regmap *map)
|
|
|
{
|
|
|
mutex_lock(&map->mutex);
|
|
@@ -227,6 +249,7 @@ struct regmap *regmap_init(struct device *dev,
|
|
|
{
|
|
|
struct regmap *map, **m;
|
|
|
int ret = -EINVAL;
|
|
|
+ enum regmap_endian reg_endian, val_endian;
|
|
|
|
|
|
if (!bus || !config)
|
|
|
goto err;
|
|
@@ -275,6 +298,18 @@ struct regmap *regmap_init(struct device *dev,
|
|
|
map->read_flag_mask = bus->read_flag_mask;
|
|
|
}
|
|
|
|
|
|
+ reg_endian = config->reg_format_endian;
|
|
|
+ if (reg_endian == REGMAP_ENDIAN_DEFAULT)
|
|
|
+ reg_endian = bus->reg_format_endian_default;
|
|
|
+ if (reg_endian == REGMAP_ENDIAN_DEFAULT)
|
|
|
+ reg_endian = REGMAP_ENDIAN_BIG;
|
|
|
+
|
|
|
+ val_endian = config->val_format_endian;
|
|
|
+ if (val_endian == REGMAP_ENDIAN_DEFAULT)
|
|
|
+ val_endian = bus->val_format_endian_default;
|
|
|
+ if (val_endian == REGMAP_ENDIAN_DEFAULT)
|
|
|
+ val_endian = REGMAP_ENDIAN_BIG;
|
|
|
+
|
|
|
switch (config->reg_bits + map->reg_shift) {
|
|
|
case 2:
|
|
|
switch (config->val_bits) {
|
|
@@ -321,11 +356,29 @@ struct regmap *regmap_init(struct device *dev,
|
|
|
break;
|
|
|
|
|
|
case 16:
|
|
|
- map->format.format_reg = regmap_format_16;
|
|
|
+ switch (reg_endian) {
|
|
|
+ case REGMAP_ENDIAN_BIG:
|
|
|
+ map->format.format_reg = regmap_format_16_be;
|
|
|
+ break;
|
|
|
+ case REGMAP_ENDIAN_NATIVE:
|
|
|
+ map->format.format_reg = regmap_format_16_native;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ goto err_map;
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case 32:
|
|
|
- map->format.format_reg = regmap_format_32;
|
|
|
+ switch (reg_endian) {
|
|
|
+ case REGMAP_ENDIAN_BIG:
|
|
|
+ map->format.format_reg = regmap_format_32_be;
|
|
|
+ break;
|
|
|
+ case REGMAP_ENDIAN_NATIVE:
|
|
|
+ map->format.format_reg = regmap_format_32_native;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ goto err_map;
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -338,21 +391,47 @@ struct regmap *regmap_init(struct device *dev,
|
|
|
map->format.parse_val = regmap_parse_8;
|
|
|
break;
|
|
|
case 16:
|
|
|
- map->format.format_val = regmap_format_16;
|
|
|
- map->format.parse_val = regmap_parse_16;
|
|
|
+ switch (val_endian) {
|
|
|
+ case REGMAP_ENDIAN_BIG:
|
|
|
+ map->format.format_val = regmap_format_16_be;
|
|
|
+ map->format.parse_val = regmap_parse_16_be;
|
|
|
+ break;
|
|
|
+ case REGMAP_ENDIAN_NATIVE:
|
|
|
+ map->format.format_val = regmap_format_16_native;
|
|
|
+ map->format.parse_val = regmap_parse_16_native;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ goto err_map;
|
|
|
+ }
|
|
|
break;
|
|
|
case 24:
|
|
|
+ if (val_endian != REGMAP_ENDIAN_BIG)
|
|
|
+ goto err_map;
|
|
|
map->format.format_val = regmap_format_24;
|
|
|
map->format.parse_val = regmap_parse_24;
|
|
|
break;
|
|
|
case 32:
|
|
|
- map->format.format_val = regmap_format_32;
|
|
|
- map->format.parse_val = regmap_parse_32;
|
|
|
+ switch (val_endian) {
|
|
|
+ case REGMAP_ENDIAN_BIG:
|
|
|
+ map->format.format_val = regmap_format_32_be;
|
|
|
+ map->format.parse_val = regmap_parse_32_be;
|
|
|
+ break;
|
|
|
+ case REGMAP_ENDIAN_NATIVE:
|
|
|
+ map->format.format_val = regmap_format_32_native;
|
|
|
+ map->format.parse_val = regmap_parse_32_native;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ goto err_map;
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (map->format.format_write)
|
|
|
+ if (map->format.format_write) {
|
|
|
+ if ((reg_endian != REGMAP_ENDIAN_BIG) ||
|
|
|
+ (val_endian != REGMAP_ENDIAN_BIG))
|
|
|
+ goto err_map;
|
|
|
map->use_single_rw = true;
|
|
|
+ }
|
|
|
|
|
|
if (!map->format.format_write &&
|
|
|
!(map->format.format_reg && map->format.format_val))
|