diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2013-01-12 15:54:12 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-01-13 18:04:01 -0500 |
commit | ad278406b3b8b8e454af23b63df3c3d63f6aee94 (patch) | |
tree | c5e936e0acf0b3ae7b9d88ba1601507a18c6769d /drivers/base/regmap/regmap.c | |
parent | 9931faca02c604c22335f5a935a501bb2ace6e20 (diff) |
regmap: Add provisions to have user-defined read 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 read function.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r-- | drivers/base/regmap/regmap.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 42d5cb0f503f..ceaefcfda8de 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -34,6 +34,9 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, | |||
34 | unsigned int mask, unsigned int val, | 34 | unsigned int mask, unsigned int val, |
35 | bool *change); | 35 | bool *change); |
36 | 36 | ||
37 | static int _regmap_bus_read(void *context, unsigned int reg, | ||
38 | unsigned int *val); | ||
39 | |||
37 | bool regmap_reg_in_ranges(unsigned int reg, | 40 | bool regmap_reg_in_ranges(unsigned int reg, |
38 | const struct regmap_range *ranges, | 41 | const struct regmap_range *ranges, |
39 | unsigned int nranges) | 42 | unsigned int nranges) |
@@ -430,6 +433,8 @@ struct regmap *regmap_init(struct device *dev, | |||
430 | map->read_flag_mask = bus->read_flag_mask; | 433 | map->read_flag_mask = bus->read_flag_mask; |
431 | } | 434 | } |
432 | 435 | ||
436 | map->reg_read = _regmap_bus_read; | ||
437 | |||
433 | reg_endian = config->reg_format_endian; | 438 | reg_endian = config->reg_format_endian; |
434 | if (reg_endian == REGMAP_ENDIAN_DEFAULT) | 439 | if (reg_endian == REGMAP_ENDIAN_DEFAULT) |
435 | reg_endian = bus->reg_format_endian_default; | 440 | reg_endian = bus->reg_format_endian_default; |
@@ -1202,10 +1207,27 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
1202 | return ret; | 1207 | return ret; |
1203 | } | 1208 | } |
1204 | 1209 | ||
1210 | static int _regmap_bus_read(void *context, unsigned int reg, | ||
1211 | unsigned int *val) | ||
1212 | { | ||
1213 | int ret; | ||
1214 | struct regmap *map = context; | ||
1215 | |||
1216 | if (!map->format.parse_val) | ||
1217 | return -EINVAL; | ||
1218 | |||
1219 | ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); | ||
1220 | if (ret == 0) | ||
1221 | *val = map->format.parse_val(map->work_buf); | ||
1222 | |||
1223 | return ret; | ||
1224 | } | ||
1225 | |||
1205 | static int _regmap_read(struct regmap *map, unsigned int reg, | 1226 | static int _regmap_read(struct regmap *map, unsigned int reg, |
1206 | unsigned int *val) | 1227 | unsigned int *val) |
1207 | { | 1228 | { |
1208 | int ret; | 1229 | int ret; |
1230 | BUG_ON(!map->reg_read); | ||
1209 | 1231 | ||
1210 | if (!map->cache_bypass) { | 1232 | if (!map->cache_bypass) { |
1211 | ret = regcache_read(map, reg, val); | 1233 | ret = regcache_read(map, reg, val); |
@@ -1213,26 +1235,21 @@ static int _regmap_read(struct regmap *map, unsigned int reg, | |||
1213 | return 0; | 1235 | return 0; |
1214 | } | 1236 | } |
1215 | 1237 | ||
1216 | if (!map->format.parse_val) | ||
1217 | return -EINVAL; | ||
1218 | |||
1219 | if (map->cache_only) | 1238 | if (map->cache_only) |
1220 | return -EBUSY; | 1239 | return -EBUSY; |
1221 | 1240 | ||
1222 | ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); | 1241 | ret = map->reg_read(map, reg, val); |
1223 | if (ret == 0) { | 1242 | if (ret == 0) { |
1224 | *val = map->format.parse_val(map->work_buf); | ||
1225 | |||
1226 | #ifdef LOG_DEVICE | 1243 | #ifdef LOG_DEVICE |
1227 | if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) | 1244 | if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0) |
1228 | dev_info(map->dev, "%x => %x\n", reg, *val); | 1245 | dev_info(map->dev, "%x => %x\n", reg, *val); |
1229 | #endif | 1246 | #endif |
1230 | 1247 | ||
1231 | trace_regmap_reg_read(map->dev, reg, *val); | 1248 | trace_regmap_reg_read(map->dev, reg, *val); |
1232 | } | ||
1233 | 1249 | ||
1234 | if (ret == 0 && !map->cache_bypass) | 1250 | if (!map->cache_bypass) |
1235 | regcache_write(map, reg, *val); | 1251 | regcache_write(map, reg, *val); |
1252 | } | ||
1236 | 1253 | ||
1237 | return ret; | 1254 | return ret; |
1238 | } | 1255 | } |