Skip to content

Commit 2e33caf

Browse files
Ashish Jangambroonie
authored andcommitted
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>
1 parent 5680655 commit 2e33caf

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

drivers/base/regmap/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ struct regmap {
9191

9292
struct reg_default *patch;
9393
int patch_regs;
94+
95+
/* if set, converts bulk rw to single rw */
96+
bool use_single_rw;
9497
};
9598

9699
struct regcache_ops {

drivers/base/regmap/regmap.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ struct regmap *regmap_init(struct device *dev,
247247
map->reg_stride = config->reg_stride;
248248
else
249249
map->reg_stride = 1;
250+
map->use_single_rw = config->use_single_rw;
250251
map->dev = dev;
251252
map->bus = bus;
252253
map->bus_context = bus_context;
@@ -686,7 +687,22 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
686687
for (i = 0; i < val_count * val_bytes; i += val_bytes)
687688
map->format.parse_val(wval + i);
688689
}
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+
}
690706

691707
if (val_bytes != 1)
692708
kfree(wval);
@@ -855,9 +871,25 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
855871
return -EINVAL;
856872

857873
if (vol || map->cache_type == REGCACHE_NONE) {
858-
ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
859-
if (ret != 0)
860-
return ret;
874+
/*
875+
* Some devices does not support bulk read, for
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+
}
861893

862894
for (i = 0; i < val_count * val_bytes; i += val_bytes)
863895
map->format.parse_val(val + i);

include/linux/regmap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ struct reg_default {
7676
* @write_flag_mask: Mask to be set in the top byte of the register when doing
7777
* a write. If both read_flag_mask and write_flag_mask are
7878
* 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.
7982
*
8083
* @cache_type: The actual cache type.
8184
* @reg_defaults_raw: Power on reset values for registers (for use with
@@ -104,6 +107,8 @@ struct regmap_config {
104107

105108
u8 read_flag_mask;
106109
u8 write_flag_mask;
110+
111+
bool use_single_rw;
107112
};
108113

109114
typedef int (*regmap_hw_write)(void *context, const void *data,

0 commit comments

Comments
 (0)