Skip to content

Commit 4bc5b6b

Browse files
committed
Merge tag 'regmap-noinc-read' into togreg
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.
2 parents ad6e1fb + 74fe7b5 commit 4bc5b6b

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

drivers/base/regmap/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ struct regmap {
9494
bool (*readable_reg)(struct device *dev, unsigned int reg);
9595
bool (*volatile_reg)(struct device *dev, unsigned int reg);
9696
bool (*precious_reg)(struct device *dev, unsigned int reg);
97+
bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
9798
const struct regmap_access_table *wr_table;
9899
const struct regmap_access_table *rd_table;
99100
const struct regmap_access_table *volatile_table;
100101
const struct regmap_access_table *precious_table;
102+
const struct regmap_access_table *rd_noinc_table;
101103

102104
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
103105
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
@@ -181,6 +183,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg);
181183
bool regmap_readable(struct regmap *map, unsigned int reg);
182184
bool regmap_volatile(struct regmap *map, unsigned int reg);
183185
bool regmap_precious(struct regmap *map, unsigned int reg);
186+
bool regmap_readable_noinc(struct regmap *map, unsigned int reg);
184187

185188
int _regmap_write(struct regmap *map, unsigned int reg,
186189
unsigned int val);

drivers/base/regmap/regmap.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
168168
return false;
169169
}
170170

171+
bool 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+
171182
static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
172183
size_t num)
173184
{
@@ -766,10 +777,12 @@ struct regmap *__regmap_init(struct device *dev,
766777
map->rd_table = config->rd_table;
767778
map->volatile_table = config->volatile_table;
768779
map->precious_table = config->precious_table;
780+
map->rd_noinc_table = config->rd_noinc_table;
769781
map->writeable_reg = config->writeable_reg;
770782
map->readable_reg = config->readable_reg;
771783
map->volatile_reg = config->volatile_reg;
772784
map->precious_reg = config->precious_reg;
785+
map->readable_noinc_reg = config->readable_noinc_reg;
773786
map->cache_type = config->cache_type;
774787

775788
spin_lock_init(&map->async_lock);
@@ -1285,6 +1298,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
12851298
map->readable_reg = config->readable_reg;
12861299
map->volatile_reg = config->volatile_reg;
12871300
map->precious_reg = config->precious_reg;
1301+
map->readable_noinc_reg = config->readable_noinc_reg;
12881302
map->cache_type = config->cache_type;
12891303

12901304
regmap_debugfs_init(map, config->name);
@@ -2564,7 +2578,70 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
25642578
EXPORT_SYMBOL_GPL(regmap_raw_read);
25652579

25662580
/**
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+
*/
2601+
int 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+
2637+
out_unlock:
2638+
map->unlock(map->lock_arg);
2639+
return ret;
2640+
}
2641+
EXPORT_SYMBOL_GPL(regmap_noinc_read);
2642+
2643+
/**
2644+
* regmap_field_read(): Read a value to a single register field
25682645
*
25692646
* @field: Register field to read from
25702647
* @val: Pointer to store read value

include/linux/regmap.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,13 @@ typedef void (*regmap_unlock)(void *);
268268
* field is NULL but precious_table (see below) is not, the
269269
* check is performed on such table (a register is precious if
270270
* it belongs to one of the ranges specified by precious_table).
271+
* @readable_noinc_reg: Optional callback returning true if the register
272+
* supports multiple read operations without incrementing
273+
* the register number. If this field is NULL but
274+
* rd_noinc_table (see below) is not, the check is
275+
* performed on such table (a register is no increment
276+
* readable if it belongs to one of the ranges specified
277+
* by rd_noinc_table).
271278
* @disable_locking: This regmap is either protected by external means or
272279
* is guaranteed not be be accessed from multiple threads.
273280
* Don't use any locking mechanisms.
@@ -295,6 +302,7 @@ typedef void (*regmap_unlock)(void *);
295302
* @rd_table: As above, for read access.
296303
* @volatile_table: As above, for volatile registers.
297304
* @precious_table: As above, for precious registers.
305+
* @rd_noinc_table: As above, for no increment readable registers.
298306
* @reg_defaults: Power on reset values for registers (for use with
299307
* register cache support).
300308
* @num_reg_defaults: Number of elements in reg_defaults.
@@ -344,6 +352,7 @@ struct regmap_config {
344352
bool (*readable_reg)(struct device *dev, unsigned int reg);
345353
bool (*volatile_reg)(struct device *dev, unsigned int reg);
346354
bool (*precious_reg)(struct device *dev, unsigned int reg);
355+
bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
347356

348357
bool disable_locking;
349358
regmap_lock lock;
@@ -360,6 +369,7 @@ struct regmap_config {
360369
const struct regmap_access_table *rd_table;
361370
const struct regmap_access_table *volatile_table;
362371
const struct regmap_access_table *precious_table;
372+
const struct regmap_access_table *rd_noinc_table;
363373
const struct reg_default *reg_defaults;
364374
unsigned int num_reg_defaults;
365375
enum regcache_type cache_type;
@@ -946,6 +956,8 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
946956
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
947957
int regmap_raw_read(struct regmap *map, unsigned int reg,
948958
void *val, size_t val_len);
959+
int regmap_noinc_read(struct regmap *map, unsigned int reg,
960+
void *val, size_t val_len);
949961
int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
950962
size_t val_count);
951963
int regmap_update_bits_base(struct regmap *map, unsigned int reg,
@@ -1196,6 +1208,13 @@ static inline int regmap_raw_read(struct regmap *map, unsigned int reg,
11961208
return -EINVAL;
11971209
}
11981210

1211+
static inline int regmap_noinc_read(struct regmap *map, unsigned int reg,
1212+
void *val, size_t val_len)
1213+
{
1214+
WARN_ONCE(1, "regmap API is disabled");
1215+
return -EINVAL;
1216+
}
1217+
11991218
static inline int regmap_bulk_read(struct regmap *map, unsigned int reg,
12001219
void *val, size_t val_count)
12011220
{

0 commit comments

Comments
 (0)