aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-08-09 06:15:06 -0400
committerMark Brown <broonie@kernel.org>2018-08-09 06:15:06 -0400
commit1cbddedbed799be9906ab3f2e5f58e618e6eb475 (patch)
tree1d14cf33d6a0f7119114c379ec09a2a55c3c864f /drivers/base
parent75eb3a67a29e9f87c07c8bd184a7ed4274a58ef0 (diff)
parent74fe7b551f3385fa585d92616c85b3a575b2b2cb (diff)
Merge tag 'regmap-noinc-read' into regmap-4.19
regmap: Support non-incrementing registers Some devices have individual registers that don't autoincrement the register address during bulk reads but instead repeatedly read the same value, for example for monitoring GPIOs or ADCs. Add support for these.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c79
2 files changed, 81 insertions, 1 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 53785e0e297a..a6bf34d6394e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -94,10 +94,12 @@ struct regmap {
94 bool (*readable_reg)(struct device *dev, unsigned int reg); 94 bool (*readable_reg)(struct device *dev, unsigned int reg);
95 bool (*volatile_reg)(struct device *dev, unsigned int reg); 95 bool (*volatile_reg)(struct device *dev, unsigned int reg);
96 bool (*precious_reg)(struct device *dev, unsigned int reg); 96 bool (*precious_reg)(struct device *dev, unsigned int reg);
97 bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
97 const struct regmap_access_table *wr_table; 98 const struct regmap_access_table *wr_table;
98 const struct regmap_access_table *rd_table; 99 const struct regmap_access_table *rd_table;
99 const struct regmap_access_table *volatile_table; 100 const struct regmap_access_table *volatile_table;
100 const struct regmap_access_table *precious_table; 101 const struct regmap_access_table *precious_table;
102 const struct regmap_access_table *rd_noinc_table;
101 103
102 int (*reg_read)(void *context, unsigned int reg, unsigned int *val); 104 int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
103 int (*reg_write)(void *context, unsigned int reg, unsigned int val); 105 int (*reg_write)(void *context, unsigned int reg, unsigned int val);
@@ -181,6 +183,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg);
181bool regmap_readable(struct regmap *map, unsigned int reg); 183bool regmap_readable(struct regmap *map, unsigned int reg);
182bool regmap_volatile(struct regmap *map, unsigned int reg); 184bool regmap_volatile(struct regmap *map, unsigned int reg);
183bool regmap_precious(struct regmap *map, unsigned int reg); 185bool regmap_precious(struct regmap *map, unsigned int reg);
186bool regmap_readable_noinc(struct regmap *map, unsigned int reg);
184 187
185int _regmap_write(struct regmap *map, unsigned int reg, 188int _regmap_write(struct regmap *map, unsigned int reg,
186 unsigned int val); 189 unsigned int val);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 3bc84885eb91..0360a90ad6b6 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -168,6 +168,17 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
168 return false; 168 return false;
169} 169}
170 170
171bool regmap_readable_noinc(struct regmap *map, unsigned int reg)
172{
173 if (map->readable_noinc_reg)
174 return map->readable_noinc_reg(map->dev, reg);
175
176 if (map->rd_noinc_table)
177 return regmap_check_range_table(map, reg, map->rd_noinc_table);
178
179 return true;
180}
181
171static bool regmap_volatile_range(struct regmap *map, unsigned int reg, 182static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
172 size_t num) 183 size_t num)
173{ 184{
@@ -766,10 +777,12 @@ struct regmap *__regmap_init(struct device *dev,
766 map->rd_table = config->rd_table; 777 map->rd_table = config->rd_table;
767 map->volatile_table = config->volatile_table; 778 map->volatile_table = config->volatile_table;
768 map->precious_table = config->precious_table; 779 map->precious_table = config->precious_table;
780 map->rd_noinc_table = config->rd_noinc_table;
769 map->writeable_reg = config->writeable_reg; 781 map->writeable_reg = config->writeable_reg;
770 map->readable_reg = config->readable_reg; 782 map->readable_reg = config->readable_reg;
771 map->volatile_reg = config->volatile_reg; 783 map->volatile_reg = config->volatile_reg;
772 map->precious_reg = config->precious_reg; 784 map->precious_reg = config->precious_reg;
785 map->readable_noinc_reg = config->readable_noinc_reg;
773 map->cache_type = config->cache_type; 786 map->cache_type = config->cache_type;
774 787
775 spin_lock_init(&map->async_lock); 788 spin_lock_init(&map->async_lock);
@@ -1285,6 +1298,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
1285 map->readable_reg = config->readable_reg; 1298 map->readable_reg = config->readable_reg;
1286 map->volatile_reg = config->volatile_reg; 1299 map->volatile_reg = config->volatile_reg;
1287 map->precious_reg = config->precious_reg; 1300 map->precious_reg = config->precious_reg;
1301 map->readable_noinc_reg = config->readable_noinc_reg;
1288 map->cache_type = config->cache_type; 1302 map->cache_type = config->cache_type;
1289 1303
1290 regmap_debugfs_init(map, config->name); 1304 regmap_debugfs_init(map, config->name);
@@ -2564,7 +2578,70 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
2564EXPORT_SYMBOL_GPL(regmap_raw_read); 2578EXPORT_SYMBOL_GPL(regmap_raw_read);
2565 2579
2566/** 2580/**
2567 * regmap_field_read() - Read a value to a single register field 2581 * regmap_noinc_read(): Read data from a register without incrementing the
2582 * register number
2583 *
2584 * @map: Register map to read from
2585 * @reg: Register to read from
2586 * @val: Pointer to data buffer
2587 * @val_len: Length of output buffer in bytes.
2588 *
2589 * The regmap API usually assumes that bulk bus read operations will read a
2590 * range of registers. Some devices have certain registers for which a read
2591 * operation read will read from an internal FIFO.
2592 *
2593 * The target register must be volatile but registers after it can be
2594 * completely unrelated cacheable registers.
2595 *
2596 * This will attempt multiple reads as required to read val_len bytes.
2597 *
2598 * A value of zero will be returned on success, a negative errno will be
2599 * returned in error cases.
2600 */
2601int regmap_noinc_read(struct regmap *map, unsigned int reg,
2602 void *val, size_t val_len)
2603{
2604 size_t read_len;
2605 int ret;
2606
2607 if (!map->bus)
2608 return -EINVAL;
2609 if (!map->bus->read)
2610 return -ENOTSUPP;
2611 if (val_len % map->format.val_bytes)
2612 return -EINVAL;
2613 if (!IS_ALIGNED(reg, map->reg_stride))
2614 return -EINVAL;
2615 if (val_len == 0)
2616 return -EINVAL;
2617
2618 map->lock(map->lock_arg);
2619
2620 if (!regmap_volatile(map, reg) || !regmap_readable_noinc(map, reg)) {
2621 ret = -EINVAL;
2622 goto out_unlock;
2623 }
2624
2625 while (val_len) {
2626 if (map->max_raw_read && map->max_raw_read < val_len)
2627 read_len = map->max_raw_read;
2628 else
2629 read_len = val_len;
2630 ret = _regmap_raw_read(map, reg, val, read_len);
2631 if (ret)
2632 goto out_unlock;
2633 val = ((u8 *)val) + read_len;
2634 val_len -= read_len;
2635 }
2636
2637out_unlock:
2638 map->unlock(map->lock_arg);
2639 return ret;
2640}
2641EXPORT_SYMBOL_GPL(regmap_noinc_read);
2642
2643/**
2644 * regmap_field_read(): Read a value to a single register field
2568 * 2645 *
2569 * @field: Register field to read from 2646 * @field: Register field to read from
2570 * @val: Pointer to store read value 2647 * @val: Pointer to store read value