aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Jangam <ashish.jangam@kpitcummins.com>2012-04-30 18:23:40 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-30 18:29:56 -0400
commit2e33caf16f7a1903d226ef7f9f5ec6a234fee18e (patch)
treeb557691a1197a035eee85df52d4eb05bcb9f02fb
parent56806555de5485d6786bf0f8df01b8ed9fc5d006 (diff)
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>
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c40
-rw-r--r--include/linux/regmap.h5
3 files changed, 44 insertions, 4 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d92e9b1cb83c..2eb719704885 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -91,6 +91,9 @@ struct regmap {
91 91
92 struct reg_default *patch; 92 struct reg_default *patch;
93 int patch_regs; 93 int patch_regs;
94
95 /* if set, converts bulk rw to single rw */
96 bool use_single_rw;
94}; 97};
95 98
96struct regcache_ops { 99struct regcache_ops {
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 8a25006b2a4d..0a05a706e141 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -247,6 +247,7 @@ struct regmap *regmap_init(struct device *dev,
247 map->reg_stride = config->reg_stride; 247 map->reg_stride = config->reg_stride;
248 else 248 else
249 map->reg_stride = 1; 249 map->reg_stride = 1;
250 map->use_single_rw = config->use_single_rw;
250 map->dev = dev; 251 map->dev = dev;
251 map->bus = bus; 252 map->bus = bus;
252 map->bus_context = bus_context; 253 map->bus_context = bus_context;
@@ -686,7 +687,22 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
686 for (i = 0; i < val_count * val_bytes; i += val_bytes) 687 for (i = 0; i < val_count * val_bytes; i += val_bytes)
687 map->format.parse_val(wval + i); 688 map->format.parse_val(wval + i);
688 } 689 }
689 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); 690 /*
691 * Some devices does not support bulk write, for
692 * them we have a series of single write operations.
693 */
694 if (map->use_single_rw) {
695 for (i = 0; i < val_count; i++) {
696 ret = regmap_raw_write(map,
697 reg + (i * map->reg_stride),
698 val + (i * val_bytes),
699 val_bytes);
700 if (ret != 0)
701 return ret;
702 }
703 } else {
704 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
705 }
690 706
691 if (val_bytes != 1) 707 if (val_bytes != 1)
692 kfree(wval); 708 kfree(wval);
@@ -855,9 +871,25 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
855 return -EINVAL; 871 return -EINVAL;
856 872
857 if (vol || map->cache_type == REGCACHE_NONE) { 873 if (vol || map->cache_type == REGCACHE_NONE) {
858 ret = regmap_raw_read(map, reg, val, val_bytes * val_count); 874 /*
859 if (ret != 0) 875 * Some devices does not support bulk read, for
860 return ret; 876 * them we have a series of single read operations.
877 */
878 if (map->use_single_rw) {
879 for (i = 0; i < val_count; i++) {
880 ret = regmap_raw_read(map,
881 reg + (i * map->reg_stride),
882 val + (i * val_bytes),
883 val_bytes);
884 if (ret != 0)
885 return ret;
886 }
887 } else {
888 ret = regmap_raw_read(map, reg, val,
889 val_bytes * val_count);
890 if (ret != 0)
891 return ret;
892 }
861 893
862 for (i = 0; i < val_count * val_bytes; i += val_bytes) 894 for (i = 0; i < val_count * val_bytes; i += val_bytes)
863 map->format.parse_val(val + i); 895 map->format.parse_val(val + i);
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 0258bcd6258d..ae797b142aa8 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -76,6 +76,9 @@ struct reg_default {
76 * @write_flag_mask: Mask to be set in the top byte of the register when doing 76 * @write_flag_mask: Mask to be set in the top byte of the register when doing
77 * a write. If both read_flag_mask and write_flag_mask are 77 * a write. If both read_flag_mask and write_flag_mask are
78 * empty the regmap_bus default masks are used. 78 * empty the regmap_bus default masks are used.
79 * @use_single_rw: If set, converts the bulk read and write operations into
80 * a series of single read and write operations. This is useful
81 * for device that does not support bulk read and write.
79 * 82 *
80 * @cache_type: The actual cache type. 83 * @cache_type: The actual cache type.
81 * @reg_defaults_raw: Power on reset values for registers (for use with 84 * @reg_defaults_raw: Power on reset values for registers (for use with
@@ -104,6 +107,8 @@ struct regmap_config {
104 107
105 u8 read_flag_mask; 108 u8 read_flag_mask;
106 u8 write_flag_mask; 109 u8 write_flag_mask;
110
111 bool use_single_rw;
107}; 112};
108 113
109typedef int (*regmap_hw_write)(void *context, const void *data, 114typedef int (*regmap_hw_write)(void *context, const void *data,