From d5c7bd985d759b7aade2700c11890821e6187e4b Mon Sep 17 00:00:00 2001 From: Mario Six Date: Mon, 15 Oct 2018 09:24:11 +0200 Subject: [PATCH] regmap: Support reading from specific range It is useful to be able to treat the different ranges of a regmap separately to be able to use distinct offset for them, but this is currently not implemented in the regmap API. To preserve backwards compatibility, add regmap_read_range and regmap_write_range functions that take an additional parameter 'range_num' that identifies the range to operate on. Reviewed-by: Anatolij Gustschin Reviewed-by: Simon Glass Signed-off-by: Mario Six --- drivers/core/regmap.c | 49 ++++++++++++++++++++++++++++++++++++++----- include/regmap.h | 31 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index 916d9272ea..9b2e02af2e 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -188,11 +188,25 @@ int regmap_uninit(struct regmap *map) return 0; } -int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len) +int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset, + void *valp, size_t val_len) { + struct regmap_range *range; void *ptr; - ptr = map_physmem(map->ranges[0].start + offset, val_len, MAP_NOCACHE); + if (range_num >= map->range_count) { + debug("%s: range index %d larger than range count\n", + __func__, range_num); + return -ERANGE; + } + range = &map->ranges[range_num]; + + ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); + + if (offset + val_len > range->size) { + debug("%s: offset/size combination invalid\n", __func__); + return -ERANGE; + } switch (val_len) { case REGMAP_SIZE_8: @@ -213,20 +227,39 @@ int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len) debug("%s: regmap size %zu unknown\n", __func__, val_len); return -EINVAL; } + return 0; } +int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len) +{ + return regmap_raw_read_range(map, 0, offset, valp, val_len); +} + int regmap_read(struct regmap *map, uint offset, uint *valp) { return regmap_raw_read(map, offset, valp, REGMAP_SIZE_32); } -int regmap_raw_write(struct regmap *map, uint offset, const void *val, - size_t val_len) +int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset, + const void *val, size_t val_len) { + struct regmap_range *range; void *ptr; - ptr = map_physmem(map->ranges[0].start + offset, val_len, MAP_NOCACHE); + if (range_num >= map->range_count) { + debug("%s: range index %d larger than range count\n", + __func__, range_num); + return -ERANGE; + } + range = &map->ranges[range_num]; + + ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); + + if (offset + val_len > range->size) { + debug("%s: offset/size combination invalid\n", __func__); + return -ERANGE; + } switch (val_len) { case REGMAP_SIZE_8: @@ -251,6 +284,12 @@ int regmap_raw_write(struct regmap *map, uint offset, const void *val, return 0; } +int regmap_raw_write(struct regmap *map, uint offset, const void *val, + size_t val_len) +{ + return regmap_raw_write_range(map, 0, offset, val, val_len); +} + int regmap_write(struct regmap *map, uint offset, uint val) { return regmap_raw_write(map, offset, &val, REGMAP_SIZE_32); diff --git a/include/regmap.h b/include/regmap.h index f23664e8ba..eba300da29 100644 --- a/include/regmap.h +++ b/include/regmap.h @@ -115,6 +115,37 @@ int regmap_raw_write(struct regmap *map, uint offset, const void *val, int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len); +/** + * regmap_raw_write_range() - Write a value of specified length to a range of a + * regmap + * + * @map: Regmap to write to + * @range_num: Number of the range in the regmap to write to + * @offset: Offset in the regmap to write to + * @val: Value to write to the regmap at the specified offset + * @val_len: Length of the data to be written to the regmap + * + * Return: 0 if OK, -ve on error + */ +int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset, + const void *val, size_t val_len); + +/** + * regmap_raw_read_range() - Read a value of specified length from a range of a + * regmap + * + * @map: Regmap to read from + * @range_num: Number of the range in the regmap to write to + * @offset: Offset in the regmap to read from + * @valp: Pointer to the buffer to receive the data read from the regmap + * at the specified offset + * @val_len: Length of the data to be read from the regmap + * + * Return: 0 if OK, -ve on error + */ +int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset, + void *valp, size_t val_len); + #define regmap_write32(map, ptr, member, val) \ regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)