regmap: Add regmap_noinc_read API
The regmap API usually assumes that bulk read operations will read a range of registers but some I2C/SPI devices have certain registers for which a such a read operation will return data from an internal FIFO instead. Add an explicit API to support bulk read without range semantics. Some linux drivers use regmap_bulk_read or regmap_raw_read for such registers, for example mpu6050 or bmi150 from IIO. This only happens to work because when caching is disabled a single regmap read op will map to a single bus read op (as desired). This breaks if caching is enabled and reg+1 happens to be a cacheable register. Without regmap support refactoring a driver to enable regmap caching requires separate I2C and SPI paths. This is exactly what regmap is supposed to help avoid. Suggested-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> Signed-off-by: Stefan Popa <stefan.popa@analog.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:

committed by
Mark Brown

parent
ce397d215c
commit
74fe7b551f
@@ -268,6 +268,13 @@ typedef void (*regmap_unlock)(void *);
|
||||
* field is NULL but precious_table (see below) is not, the
|
||||
* check is performed on such table (a register is precious if
|
||||
* it belongs to one of the ranges specified by precious_table).
|
||||
* @readable_noinc_reg: Optional callback returning true if the register
|
||||
* supports multiple read operations without incrementing
|
||||
* the register number. If this field is NULL but
|
||||
* rd_noinc_table (see below) is not, the check is
|
||||
* performed on such table (a register is no increment
|
||||
* readable if it belongs to one of the ranges specified
|
||||
* by rd_noinc_table).
|
||||
* @disable_locking: This regmap is either protected by external means or
|
||||
* is guaranteed not be be accessed from multiple threads.
|
||||
* Don't use any locking mechanisms.
|
||||
@@ -295,6 +302,7 @@ typedef void (*regmap_unlock)(void *);
|
||||
* @rd_table: As above, for read access.
|
||||
* @volatile_table: As above, for volatile registers.
|
||||
* @precious_table: As above, for precious registers.
|
||||
* @rd_noinc_table: As above, for no increment readable registers.
|
||||
* @reg_defaults: Power on reset values for registers (for use with
|
||||
* register cache support).
|
||||
* @num_reg_defaults: Number of elements in reg_defaults.
|
||||
@@ -344,6 +352,7 @@ struct regmap_config {
|
||||
bool (*readable_reg)(struct device *dev, unsigned int reg);
|
||||
bool (*volatile_reg)(struct device *dev, unsigned int reg);
|
||||
bool (*precious_reg)(struct device *dev, unsigned int reg);
|
||||
bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
|
||||
|
||||
bool disable_locking;
|
||||
regmap_lock lock;
|
||||
@@ -360,6 +369,7 @@ struct regmap_config {
|
||||
const struct regmap_access_table *rd_table;
|
||||
const struct regmap_access_table *volatile_table;
|
||||
const struct regmap_access_table *precious_table;
|
||||
const struct regmap_access_table *rd_noinc_table;
|
||||
const struct reg_default *reg_defaults;
|
||||
unsigned int num_reg_defaults;
|
||||
enum regcache_type cache_type;
|
||||
@@ -946,6 +956,8 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
|
||||
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
|
||||
int regmap_raw_read(struct regmap *map, unsigned int reg,
|
||||
void *val, size_t val_len);
|
||||
int regmap_noinc_read(struct regmap *map, unsigned int reg,
|
||||
void *val, size_t val_len);
|
||||
int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
|
||||
size_t val_count);
|
||||
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,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int regmap_noinc_read(struct regmap *map, unsigned int reg,
|
||||
void *val, size_t val_len)
|
||||
{
|
||||
WARN_ONCE(1, "regmap API is disabled");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int regmap_bulk_read(struct regmap *map, unsigned int reg,
|
||||
void *val, size_t val_count)
|
||||
{
|
||||
|
Reference in New Issue
Block a user