regmap: Converts group operation into single read write operations
authorAshish Jangam <ashish.jangam@kpitcummins.com>
Mon, 30 Apr 2012 22:23:40 +0000 (23:23 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 30 Apr 2012 22:29:56 +0000 (23:29 +0100)
Some devices does not support bulk read and write operations, for them
we have series of single write and read operations.

Signed-off-by: Anthony Olech <Anthony.Olech@diasemi.com>
Signed-off-by: Ashish Jangam <ashish.jangam@kpitcummins.com>
[Fixed coding style, don't check use_single_rw before assign --broonie ]
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
drivers/base/regmap/internal.h
drivers/base/regmap/regmap.c
include/linux/regmap.h

index d92e9b1cb83cc2f6c0295819979af3af6bd4e9b7..2eb719704885cbfe9497e0c04de7f5d088d990a6 100644 (file)
@@ -91,6 +91,9 @@ struct regmap {
 
        struct reg_default *patch;
        int patch_regs;
+
+       /* if set, converts bulk rw to single rw */
+       bool use_single_rw;
 };
 
 struct regcache_ops {
index 8a25006b2a4de1885387e3223e29e27f4cd3fcfc..0a05a706e141cc81d115e54b9e90991c2d3ad744 100644 (file)
@@ -247,6 +247,7 @@ struct regmap *regmap_init(struct device *dev,
                map->reg_stride = config->reg_stride;
        else
                map->reg_stride = 1;
+       map->use_single_rw = config->use_single_rw;
        map->dev = dev;
        map->bus = bus;
        map->bus_context = bus_context;
@@ -686,7 +687,22 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
                for (i = 0; i < val_count * val_bytes; i += val_bytes)
                        map->format.parse_val(wval + i);
        }
-       ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
+       /*
+        * Some devices does not support bulk write, for
+        * them we have a series of single write operations.
+        */
+       if (map->use_single_rw) {
+               for (i = 0; i < val_count; i++) {
+                       ret = regmap_raw_write(map,
+                                               reg + (i * map->reg_stride),
+                                               val + (i * val_bytes),
+                                               val_bytes);
+                       if (ret != 0)
+                               return ret;
+               }
+       } else {
+               ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
+       }
 
        if (val_bytes != 1)
                kfree(wval);
@@ -855,9 +871,25 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
                return -EINVAL;
 
        if (vol || map->cache_type == REGCACHE_NONE) {
-               ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
-               if (ret != 0)
-                       return ret;
+               /*
+                * Some devices does not support bulk read, for
+                * them we have a series of single read operations.
+                */
+               if (map->use_single_rw) {
+                       for (i = 0; i < val_count; i++) {
+                               ret = regmap_raw_read(map,
+                                               reg + (i * map->reg_stride),
+                                               val + (i * val_bytes),
+                                               val_bytes);
+                               if (ret != 0)
+                                       return ret;
+                       }
+               } else {
+                       ret = regmap_raw_read(map, reg, val,
+                                             val_bytes * val_count);
+                       if (ret != 0)
+                               return ret;
+               }
 
                for (i = 0; i < val_count * val_bytes; i += val_bytes)
                        map->format.parse_val(val + i);
index 0258bcd6258d524c1254c96670d22fd6ec7dc1b0..ae797b142aa8cb5f5eeb2fda088f6a5ee30426da 100644 (file)
@@ -76,6 +76,9 @@ struct reg_default {
  * @write_flag_mask: Mask to be set in the top byte of the register when doing
  *                   a write. If both read_flag_mask and write_flag_mask are
  *                   empty the regmap_bus default masks are used.
+ * @use_single_rw: If set, converts the bulk read and write operations into
+ *                 a series of single read and write operations. This is useful
+ *                 for device that does not support bulk read and write.
  *
  * @cache_type: The actual cache type.
  * @reg_defaults_raw: Power on reset values for registers (for use with
@@ -104,6 +107,8 @@ struct regmap_config {
 
        u8 read_flag_mask;
        u8 write_flag_mask;
+
+       bool use_single_rw;
 };
 
 typedef int (*regmap_hw_write)(void *context, const void *data,
This page took 0.031581 seconds and 5 git commands to generate.