Commit 6f306441e97f8f9d27c43a536360fe221f675a71

Authored by Lars-Peter Clausen
Committed by Mark Brown
1 parent d813ae9a10

regmap: Add support for device specific write and read flag masks.

Some buses like SPI have no standard notation of read or write operations.
The general scheme here is to set or clear specific bits in the register
address to indicate whether the operation is a read or write. We already
support having a read flag mask per bus, but as there is no standard
the bits which need to be set or cleared differ between devices and vendors,
thus we need a mechanism to specify them per device.

This patch adds two new entries to the regmap_config struct, read_flag_mask and
write_flag_mask. These will be or'ed onto the top byte when doing a read or
write operation. If both masks are empty the device will fallback to the
regmap_bus masks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Showing 3 changed files with 24 additions and 3 deletions Side-by-side Diff

drivers/base/regmap/internal.h
... ... @@ -46,6 +46,9 @@
46 46 bool (*readable_reg)(struct device *dev, unsigned int reg);
47 47 bool (*volatile_reg)(struct device *dev, unsigned int reg);
48 48 bool (*precious_reg)(struct device *dev, unsigned int reg);
  49 +
  50 + u8 read_flag_mask;
  51 + u8 write_flag_mask;
49 52 };
50 53  
51 54 bool regmap_writeable(struct regmap *map, unsigned int reg);
drivers/base/regmap/regmap.c
... ... @@ -147,6 +147,13 @@
147 147 map->volatile_reg = config->volatile_reg;
148 148 map->precious_reg = config->precious_reg;
149 149  
  150 + if (config->read_flag_mask || config->write_flag_mask) {
  151 + map->read_flag_mask = config->read_flag_mask;
  152 + map->write_flag_mask = config->write_flag_mask;
  153 + } else {
  154 + map->read_flag_mask = bus->read_flag_mask;
  155 + }
  156 +
150 157 switch (config->reg_bits) {
151 158 case 4:
152 159 switch (config->val_bits) {
... ... @@ -226,6 +233,7 @@
226 233 static int _regmap_raw_write(struct regmap *map, unsigned int reg,
227 234 const void *val, size_t val_len)
228 235 {
  236 + u8 *u8 = map->work_buf;
229 237 void *buf;
230 238 int ret = -ENOTSUPP;
231 239 size_t len;
... ... @@ -239,6 +247,8 @@
239 247  
240 248 map->format.format_reg(map->work_buf, reg);
241 249  
  250 + u8[0] |= map->write_flag_mask;
  251 +
242 252 trace_regmap_hw_write_start(map->dev, reg,
243 253 val_len / map->format.val_bytes);
244 254  
245 255  
... ... @@ -366,13 +376,12 @@
366 376 map->format.format_reg(map->work_buf, reg);
367 377  
368 378 /*
369   - * Some buses flag reads by setting the high bits in the
  379 + * Some buses or devices flag reads by setting the high bits in the
370 380 * register addresss; since it's always the high bits for all
371 381 * current formats we can do this here rather than in
372 382 * formatting. This may break if we get interesting formats.
373 383 */
374   - if (map->bus->read_flag_mask)
375   - u8[0] |= map->bus->read_flag_mask;
  384 + u8[0] |= map->read_flag_mask;
376 385  
377 386 trace_regmap_hw_read_start(map->dev, reg,
378 387 val_len / map->format.val_bytes);
include/linux/regmap.h
... ... @@ -53,6 +53,12 @@
53 53 * @reg_defaults: Power on reset values for registers (for use with
54 54 * register cache support).
55 55 * @num_reg_defaults: Number of elements in reg_defaults.
  56 + *
  57 + * @read_flag_mask: Mask to be set in the top byte of the register when doing
  58 + * a read.
  59 + * @write_flag_mask: Mask to be set in the top byte of the register when doing
  60 + * a write. If both read_flag_mask and write_flag_mask are
  61 + * empty the regmap_bus default masks are used.
56 62 */
57 63 struct regmap_config {
58 64 int reg_bits;
... ... @@ -66,6 +72,9 @@
66 72 unsigned int max_register;
67 73 struct reg_default *reg_defaults;
68 74 int num_reg_defaults;
  75 +
  76 + u8 read_flag_mask;
  77 + u8 write_flag_mask;
69 78 };
70 79  
71 80 typedef int (*regmap_hw_write)(struct device *dev, const void *data,