summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorAshish Jangam <ashish.jangam@kpitcummins.com>2012-04-30 23:23:40 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-30 23:29:56 +0100
commit2e33caf16f7a1903d226ef7f9f5ec6a234fee18e (patch)
treeb557691a1197a035eee85df52d4eb05bcb9f02fb /drivers/base
parent56806555de5485d6786bf0f8df01b8ed9fc5d006 (diff)
downloadlinux-3.10-2e33caf16f7a1903d226ef7f9f5ec6a234fee18e.tar.gz
linux-3.10-2e33caf16f7a1903d226ef7f9f5ec6a234fee18e.tar.bz2
linux-3.10-2e33caf16f7a1903d226ef7f9f5ec6a234fee18e.zip
regmap: Converts group operation into single read write operations
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>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c40
2 files changed, 39 insertions, 4 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d92e9b1cb83..2eb71970488 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -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 {
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 8a25006b2a4..0a05a706e14 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -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);