lkml.org 
[lkml]   [2012]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] Regmap: Converts group operation into single read write operations
From
Date
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>
---
drivers/base/regmap/internal.h | 3 +++
drivers/base/regmap/regmap.c | 40 ++++++++++++++++++++++++++++++++++++----
include/linux/regmap.h | 5 +++++
3 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d92e9b1..2eb7197 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 8a25006..a9a2c27 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -247,6 +247,8 @@ struct regmap *regmap_init(struct device *dev,
map->reg_stride = config->reg_stride;
else
map->reg_stride = 1;
+ if (config->use_single_rw)
+ map->use_single_rw = config->use_single_rw;
map->dev = dev;
map->bus = bus;
map->bus_context = bus_context;
@@ -686,7 +688,21 @@ 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);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 0258bcd..ae797b1 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -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,



\
 
 \ /
  Last update: 2012-04-30 09:01    [W:0.071 / U:0.656 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site