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

Commit 07c320dc authored by Andrey Smirnov's avatar Andrey Smirnov Committed by Mark Brown
Browse files

regmap: Add provisions to have user-defined write operation



This commit is a preparatory commit to provide "no-bus" configuration
option for regmap API. It adds necessary plumbing needed to have the
ability to provide user define register write function.

Signed-off-by: default avatarAndrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent ad278406
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ struct regmap {
	const struct regmap_access_table *precious_table;

	int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
	int (*reg_write)(void *context, unsigned int reg, unsigned int val);

	u8 read_flag_mask;
	u8 write_flag_mask;
+54 −29
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,

static int _regmap_bus_read(void *context, unsigned int reg,
			    unsigned int *val);
static int _regmap_bus_formatted_write(void *context, unsigned int reg,
				       unsigned int val);
static int _regmap_bus_raw_write(void *context, unsigned int reg,
				 unsigned int val);

bool regmap_reg_in_ranges(unsigned int reg,
			  const struct regmap_range *ranges,
@@ -580,6 +584,11 @@ struct regmap *regmap_init(struct device *dev,
		goto err_map;
	}

	if (map->format.format_write)
		map->reg_write = _regmap_bus_formatted_write;
	else if (map->format.format_val)
		map->reg_write = _regmap_bus_raw_write;

	map->range_tree = RB_ROOT;
	for (i = 0; i < config->num_ranges; i++) {
		const struct regmap_range_cfg *range_cfg = &config->ranges[i];
@@ -986,31 +995,15 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
	return ret;
}

int _regmap_write(struct regmap *map, unsigned int reg,
static int _regmap_bus_formatted_write(void *context, unsigned int reg,
				       unsigned int val)
{
	struct regmap_range_node *range;
	int ret;
	BUG_ON(!map->format.format_write && !map->format.format_val);

	if (!map->cache_bypass && map->format.format_write) {
		ret = regcache_write(map, reg, val);
		if (ret != 0)
			return ret;
		if (map->cache_only) {
			map->cache_dirty = true;
			return 0;
		}
	}
	struct regmap_range_node *range;
	struct regmap *map = context;

#ifdef LOG_DEVICE
	if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
		dev_info(map->dev, "%x <= %x\n", reg, val);
#endif
	BUG_ON(!map->format.format_write);

	trace_regmap_reg_write(map->dev, reg, val);

	if (map->format.format_write) {
	range = _regmap_range_lookup(map, reg);
	if (range) {
		ret = _regmap_select_page(map, &reg, range, 1);
@@ -1028,7 +1021,15 @@ int _regmap_write(struct regmap *map, unsigned int reg,
	trace_regmap_hw_write_done(map->dev, reg, 1);

	return ret;
	} else {
}

static int _regmap_bus_raw_write(void *context, unsigned int reg,
				 unsigned int val)
{
	struct regmap *map = context;

	BUG_ON(!map->format.format_val);

	map->format.format_val(map->work_buf + map->format.reg_bytes
			       + map->format.pad_bytes, val, 0);
	return _regmap_raw_write(map, reg,
@@ -1037,6 +1038,30 @@ int _regmap_write(struct regmap *map, unsigned int reg,
				 map->format.pad_bytes,
				 map->format.val_bytes);
}

int _regmap_write(struct regmap *map, unsigned int reg,
		  unsigned int val)
{
	int ret;

	if (!map->cache_bypass && map->format.format_write) {
		ret = regcache_write(map, reg, val);
		if (ret != 0)
			return ret;
		if (map->cache_only) {
			map->cache_dirty = true;
			return 0;
		}
	}

#ifdef LOG_DEVICE
	if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
		dev_info(map->dev, "%x <= %x\n", reg, val);
#endif

	trace_regmap_reg_write(map->dev, reg, val);

	return map->reg_write(map, reg, val);
}

/**