|
@@ -36,6 +36,10 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
|
|
|
|
|
|
static int _regmap_bus_read(void *context, unsigned int reg,
|
|
|
unsigned int *val);
|
|
|
+static int _regmap_bus_formatted_write(void *context, unsigned int reg,
|
|
|
+ unsigned int val);
|
|
|
+static int _regmap_bus_raw_write(void *context, unsigned int reg,
|
|
|
+ unsigned int val);
|
|
|
|
|
|
bool regmap_reg_in_ranges(unsigned int reg,
|
|
|
const struct regmap_range *ranges,
|
|
@@ -580,6 +584,11 @@ struct regmap *regmap_init(struct device *dev,
|
|
|
goto err_map;
|
|
|
}
|
|
|
|
|
|
+ if (map->format.format_write)
|
|
|
+ map->reg_write = _regmap_bus_formatted_write;
|
|
|
+ else if (map->format.format_val)
|
|
|
+ map->reg_write = _regmap_bus_raw_write;
|
|
|
+
|
|
|
map->range_tree = RB_ROOT;
|
|
|
for (i = 0; i < config->num_ranges; i++) {
|
|
|
const struct regmap_range_cfg *range_cfg = &config->ranges[i];
|
|
@@ -986,12 +995,54 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int _regmap_bus_formatted_write(void *context, unsigned int reg,
|
|
|
+ unsigned int val)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ struct regmap_range_node *range;
|
|
|
+ struct regmap *map = context;
|
|
|
+
|
|
|
+ BUG_ON(!map->format.format_write);
|
|
|
+
|
|
|
+ range = _regmap_range_lookup(map, reg);
|
|
|
+ if (range) {
|
|
|
+ ret = _regmap_select_page(map, ®, range, 1);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ map->format.format_write(map, reg, val);
|
|
|
+
|
|
|
+ trace_regmap_hw_write_start(map->dev, reg, 1);
|
|
|
+
|
|
|
+ ret = map->bus->write(map->bus_context, map->work_buf,
|
|
|
+ map->format.buf_size);
|
|
|
+
|
|
|
+ trace_regmap_hw_write_done(map->dev, reg, 1);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int _regmap_bus_raw_write(void *context, unsigned int reg,
|
|
|
+ unsigned int val)
|
|
|
+{
|
|
|
+ struct regmap *map = context;
|
|
|
+
|
|
|
+ BUG_ON(!map->format.format_val);
|
|
|
+
|
|
|
+ map->format.format_val(map->work_buf + map->format.reg_bytes
|
|
|
+ + map->format.pad_bytes, val, 0);
|
|
|
+ return _regmap_raw_write(map, reg,
|
|
|
+ map->work_buf +
|
|
|
+ map->format.reg_bytes +
|
|
|
+ map->format.pad_bytes,
|
|
|
+ map->format.val_bytes);
|
|
|
+}
|
|
|
+
|
|
|
int _regmap_write(struct regmap *map, unsigned int reg,
|
|
|
unsigned int val)
|
|
|
{
|
|
|
- struct regmap_range_node *range;
|
|
|
int ret;
|
|
|
- BUG_ON(!map->format.format_write && !map->format.format_val);
|
|
|
|
|
|
if (!map->cache_bypass && map->format.format_write) {
|
|
|
ret = regcache_write(map, reg, val);
|
|
@@ -1010,33 +1061,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
|
|
|
|
|
|
trace_regmap_reg_write(map->dev, reg, val);
|
|
|
|
|
|
- if (map->format.format_write) {
|
|
|
- range = _regmap_range_lookup(map, reg);
|
|
|
- if (range) {
|
|
|
- ret = _regmap_select_page(map, ®, range, 1);
|
|
|
- if (ret != 0)
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- map->format.format_write(map, reg, val);
|
|
|
-
|
|
|
- trace_regmap_hw_write_start(map->dev, reg, 1);
|
|
|
-
|
|
|
- ret = map->bus->write(map->bus_context, map->work_buf,
|
|
|
- map->format.buf_size);
|
|
|
-
|
|
|
- trace_regmap_hw_write_done(map->dev, reg, 1);
|
|
|
-
|
|
|
- return ret;
|
|
|
- } else {
|
|
|
- map->format.format_val(map->work_buf + map->format.reg_bytes
|
|
|
- + map->format.pad_bytes, val, 0);
|
|
|
- return _regmap_raw_write(map, reg,
|
|
|
- map->work_buf +
|
|
|
- map->format.reg_bytes +
|
|
|
- map->format.pad_bytes,
|
|
|
- map->format.val_bytes);
|
|
|
- }
|
|
|
+ return map->reg_write(map, reg, val);
|
|
|
}
|
|
|
|
|
|
/**
|