aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-09-15 16:56:10 -0400
committerMark Brown <broonie@kernel.org>2016-09-16 07:06:24 -0400
commitf50e38c9966076465bc8d9dd0bc582c268a0031e (patch)
tree094910c3f36be602c126d4fe6fd5edb4e631c68e
parent29b4817d4018df78086157ea3a55c1d9424a7cfc (diff)
regmap: Allow longer flag masks for read and write
We currently only support masking the top bit for read and write flags. Let's make the mask unsigned long and mask the bytes based on the configured register length to make things more generic. This allows using regmap for more exotic combinations like SPI devices that need little endian addressing. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/base/regmap/internal.h4
-rw-r--r--drivers/base/regmap/regmap.c32
-rw-r--r--include/linux/regmap.h8
3 files changed, 25 insertions, 19 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index a0380338946a..6636f03ac2da 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -105,8 +105,8 @@ struct regmap {
105 105
106 bool defer_caching; 106 bool defer_caching;
107 107
108 u8 read_flag_mask; 108 unsigned long read_flag_mask;
109 u8 write_flag_mask; 109 unsigned long write_flag_mask;
110 110
111 /* number of bits to (left) shift the reg value when formatting*/ 111 /* number of bits to (left) shift the reg value when formatting*/
112 int reg_shift; 112 int reg_shift;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 51fa7d66a393..a6a5236b6c8d 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1296,12 +1296,26 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
1296 return 0; 1296 return 0;
1297} 1297}
1298 1298
1299static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes,
1300 unsigned long mask)
1301{
1302 u8 *buf;
1303 int i;
1304
1305 if (!mask || !map->work_buf)
1306 return;
1307
1308 buf = map->work_buf;
1309
1310 for (i = 0; i < max_bytes; i++)
1311 buf[i] |= (mask >> (8 * i)) & 0xff;
1312}
1313
1299int _regmap_raw_write(struct regmap *map, unsigned int reg, 1314int _regmap_raw_write(struct regmap *map, unsigned int reg,
1300 const void *val, size_t val_len) 1315 const void *val, size_t val_len)
1301{ 1316{
1302 struct regmap_range_node *range; 1317 struct regmap_range_node *range;
1303 unsigned long flags; 1318 unsigned long flags;
1304 u8 *u8 = map->work_buf;
1305 void *work_val = map->work_buf + map->format.reg_bytes + 1319 void *work_val = map->work_buf + map->format.reg_bytes +
1306 map->format.pad_bytes; 1320 map->format.pad_bytes;
1307 void *buf; 1321 void *buf;
@@ -1370,8 +1384,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
1370 } 1384 }
1371 1385
1372 map->format.format_reg(map->work_buf, reg, map->reg_shift); 1386 map->format.format_reg(map->work_buf, reg, map->reg_shift);
1373 1387 regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
1374 u8[0] |= map->write_flag_mask; 1388 map->write_flag_mask);
1375 1389
1376 /* 1390 /*
1377 * Essentially all I/O mechanisms will be faster with a single 1391 * Essentially all I/O mechanisms will be faster with a single
@@ -2245,7 +2259,6 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2245 unsigned int val_len) 2259 unsigned int val_len)
2246{ 2260{
2247 struct regmap_range_node *range; 2261 struct regmap_range_node *range;
2248 u8 *u8 = map->work_buf;
2249 int ret; 2262 int ret;
2250 2263
2251 WARN_ON(!map->bus); 2264 WARN_ON(!map->bus);
@@ -2262,15 +2275,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2262 } 2275 }
2263 2276
2264 map->format.format_reg(map->work_buf, reg, map->reg_shift); 2277 map->format.format_reg(map->work_buf, reg, map->reg_shift);
2265 2278 regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
2266 /* 2279 map->read_flag_mask);
2267 * Some buses or devices flag reads by setting the high bits in the
2268 * register address; since it's always the high bits for all
2269 * current formats we can do this here rather than in
2270 * formatting. This may break if we get interesting formats.
2271 */
2272 u8[0] |= map->read_flag_mask;
2273
2274 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); 2280 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
2275 2281
2276 ret = map->bus->read(map->bus_context, map->work_buf, 2282 ret = map->bus->read(map->bus_context, map->work_buf,
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 2c12cc5af744..9adc7b21903d 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -241,9 +241,9 @@ typedef void (*regmap_unlock)(void *);
241 * register cache support). 241 * register cache support).
242 * @num_reg_defaults: Number of elements in reg_defaults. 242 * @num_reg_defaults: Number of elements in reg_defaults.
243 * 243 *
244 * @read_flag_mask: Mask to be set in the top byte of the register when doing 244 * @read_flag_mask: Mask to be set in the top bytes of the register when doing
245 * a read. 245 * a read.
246 * @write_flag_mask: Mask to be set in the top byte of the register when doing 246 * @write_flag_mask: Mask to be set in the top bytes of the register when doing
247 * a write. If both read_flag_mask and write_flag_mask are 247 * a write. If both read_flag_mask and write_flag_mask are
248 * empty the regmap_bus default masks are used. 248 * empty the regmap_bus default masks are used.
249 * @use_single_rw: If set, converts the bulk read and write operations into 249 * @use_single_rw: If set, converts the bulk read and write operations into
@@ -299,8 +299,8 @@ struct regmap_config {
299 const void *reg_defaults_raw; 299 const void *reg_defaults_raw;
300 unsigned int num_reg_defaults_raw; 300 unsigned int num_reg_defaults_raw;
301 301
302 u8 read_flag_mask; 302 unsigned long read_flag_mask;
303 u8 write_flag_mask; 303 unsigned long write_flag_mask;
304 304
305 bool use_single_rw; 305 bool use_single_rw;
306 bool can_multi_write; 306 bool can_multi_write;