Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e33caf1 authored by Ashish Jangam's avatar Ashish Jangam Committed by Mark Brown
Browse files

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: default avatarAnthony Olech <Anthony.Olech@diasemi.com>
Signed-off-by: default avatarAshish Jangam <ashish.jangam@kpitcummins.com>
[Fixed coding style, don't check use_single_rw before assign --broonie ]
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 56806555
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+36 −4
Original line number Diff line number Diff line
@@ -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);
	}
	/*
	 * 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);
		/*
		 * 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);
+5 −0
Original line number Diff line number Diff line
@@ -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,