|
@@ -17,6 +17,7 @@
|
|
|
#include <linux/rbtree.h>
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/bug.h>
|
|
|
+#include <linux/lockdep.h>
|
|
|
|
|
|
struct module;
|
|
|
struct device;
|
|
@@ -51,14 +52,17 @@ struct reg_default {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * Register/value pairs for sequences of writes
|
|
|
+ * Register/value pairs for sequences of writes with an optional delay in
|
|
|
+ * microseconds to be applied after each write.
|
|
|
*
|
|
|
* @reg: Register address.
|
|
|
* @def: Register value.
|
|
|
+ * @delay_us: Delay to be applied after the register write in microseconds
|
|
|
*/
|
|
|
struct reg_sequence {
|
|
|
unsigned int reg;
|
|
|
unsigned int def;
|
|
|
+ unsigned int delay_us;
|
|
|
};
|
|
|
|
|
|
#ifdef CONFIG_REGMAP
|
|
@@ -307,8 +311,12 @@ typedef void (*regmap_hw_free_context)(void *context);
|
|
|
* if not implemented on a given device.
|
|
|
* @async_write: Write operation which completes asynchronously, optional and
|
|
|
* must serialise with respect to non-async I/O.
|
|
|
+ * @reg_write: Write a single register value to the given register address. This
|
|
|
+ * write operation has to complete when returning from the function.
|
|
|
* @read: Read operation. Data is returned in the buffer used to transmit
|
|
|
* data.
|
|
|
+ * @reg_read: Read a single register value from a given register address.
|
|
|
+ * @free_context: Free context.
|
|
|
* @async_alloc: Allocate a regmap_async() structure.
|
|
|
* @read_flag_mask: Mask to be set in the top byte of the register when doing
|
|
|
* a read.
|
|
@@ -318,7 +326,8 @@ typedef void (*regmap_hw_free_context)(void *context);
|
|
|
* @val_format_endian_default: Default endianness for formatted register
|
|
|
* values. Used when the regmap_config specifies DEFAULT. If this is
|
|
|
* DEFAULT, BIG is assumed.
|
|
|
- * @async_size: Size of struct used for async work.
|
|
|
+ * @max_raw_read: Max raw read size that can be used on the bus.
|
|
|
+ * @max_raw_write: Max raw write size that can be used on the bus.
|
|
|
*/
|
|
|
struct regmap_bus {
|
|
|
bool fast_io;
|
|
@@ -333,47 +342,186 @@ struct regmap_bus {
|
|
|
u8 read_flag_mask;
|
|
|
enum regmap_endian reg_format_endian_default;
|
|
|
enum regmap_endian val_format_endian_default;
|
|
|
+ size_t max_raw_read;
|
|
|
+ size_t max_raw_write;
|
|
|
};
|
|
|
|
|
|
-struct regmap *regmap_init(struct device *dev,
|
|
|
- const struct regmap_bus *bus,
|
|
|
- void *bus_context,
|
|
|
- const struct regmap_config *config);
|
|
|
+/*
|
|
|
+ * __regmap_init functions.
|
|
|
+ *
|
|
|
+ * These functions take a lock key and name parameter, and should not be called
|
|
|
+ * directly. Instead, use the regmap_init macros that generate a key and name
|
|
|
+ * for each call.
|
|
|
+ */
|
|
|
+struct regmap *__regmap_init(struct device *dev,
|
|
|
+ const struct regmap_bus *bus,
|
|
|
+ void *bus_context,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_spi(struct spi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_spmi_base(struct spmi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_spmi_ext(struct spmi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_mmio_clk(struct device *dev, const char *clk_id,
|
|
|
+ void __iomem *regs,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+
|
|
|
+struct regmap *__devm_regmap_init(struct device *dev,
|
|
|
+ const struct regmap_bus *bus,
|
|
|
+ void *bus_context,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_spi(struct spi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_spmi_base(struct spmi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_spmi_ext(struct spmi_device *dev,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_mmio_clk(struct device *dev,
|
|
|
+ const char *clk_id,
|
|
|
+ void __iomem *regs,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97,
|
|
|
+ const struct regmap_config *config,
|
|
|
+ struct lock_class_key *lock_key,
|
|
|
+ const char *lock_name);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Wrapper for regmap_init macros to include a unique lockdep key and name
|
|
|
+ * for each call. No-op if CONFIG_LOCKDEP is not set.
|
|
|
+ *
|
|
|
+ * @fn: Real function to call (in the form __[*_]regmap_init[_*])
|
|
|
+ * @name: Config variable name (#config in the calling macro)
|
|
|
+ **/
|
|
|
+#ifdef CONFIG_LOCKDEP
|
|
|
+#define __regmap_lockdep_wrapper(fn, name, ...) \
|
|
|
+( \
|
|
|
+ ({ \
|
|
|
+ static struct lock_class_key _key; \
|
|
|
+ fn(__VA_ARGS__, &_key, \
|
|
|
+ KBUILD_BASENAME ":" \
|
|
|
+ __stringify(__LINE__) ":" \
|
|
|
+ "(" name ")->lock"); \
|
|
|
+ }) \
|
|
|
+)
|
|
|
+#else
|
|
|
+#define __regmap_lockdep_wrapper(fn, name, ...) fn(__VA_ARGS__, NULL, NULL)
|
|
|
+#endif
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init(): Initialise register map
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @bus: Bus-specific callbacks to use with device
|
|
|
+ * @bus_context: Data passed to bus-specific callbacks
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap. This function should generally not be called
|
|
|
+ * directly, it should be called by bus-specific init functions.
|
|
|
+ */
|
|
|
+#define regmap_init(dev, bus, bus_context, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init, #config, \
|
|
|
+ dev, bus, bus_context, config)
|
|
|
int regmap_attach_dev(struct device *dev, struct regmap *map,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_spi(struct spi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_spmi_base(struct spmi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_spmi_ext(struct spmi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
|
|
|
- void __iomem *regs,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
|
|
|
- const struct regmap_config *config);
|
|
|
-
|
|
|
-struct regmap *devm_regmap_init(struct device *dev,
|
|
|
- const struct regmap_bus *bus,
|
|
|
- void *bus_context,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_spi(struct spi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_spmi_base(struct spmi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_spmi_ext(struct spmi_device *dev,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
|
|
|
- void __iomem *regs,
|
|
|
- const struct regmap_config *config);
|
|
|
-struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
|
|
|
- const struct regmap_config *config);
|
|
|
+ const struct regmap_config *config);
|
|
|
|
|
|
-bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
|
|
|
+/**
|
|
|
+ * regmap_init_i2c(): Initialise register map
|
|
|
+ *
|
|
|
+ * @i2c: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_i2c(i2c, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_i2c, #config, \
|
|
|
+ i2c, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init_spi(): Initialise register map
|
|
|
+ *
|
|
|
+ * @spi: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_spi(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_spi, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init_spmi_base(): Create regmap for the Base register space
|
|
|
+ * @sdev: SPMI device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_spmi_base(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_spmi_base, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init_spmi_ext(): Create regmap for Ext register space
|
|
|
+ * @sdev: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_spmi_ext(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_spmi_ext, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init_mmio_clk(): Initialise register map with register clock
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @clk_id: register clock consumer ID
|
|
|
+ * @regs: Pointer to memory-mapped IO region
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_mmio_clk(dev, clk_id, regs, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_mmio_clk, #config, \
|
|
|
+ dev, clk_id, regs, config)
|
|
|
|
|
|
/**
|
|
|
* regmap_init_mmio(): Initialise register map
|
|
@@ -385,12 +533,109 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
|
|
|
* The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
* a struct regmap.
|
|
|
*/
|
|
|
-static inline struct regmap *regmap_init_mmio(struct device *dev,
|
|
|
- void __iomem *regs,
|
|
|
- const struct regmap_config *config)
|
|
|
-{
|
|
|
- return regmap_init_mmio_clk(dev, NULL, regs, config);
|
|
|
-}
|
|
|
+#define regmap_init_mmio(dev, regs, config) \
|
|
|
+ regmap_init_mmio_clk(dev, NULL, regs, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * regmap_init_ac97(): Initialise AC'97 register map
|
|
|
+ *
|
|
|
+ * @ac97: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer to
|
|
|
+ * a struct regmap.
|
|
|
+ */
|
|
|
+#define regmap_init_ac97(ac97, config) \
|
|
|
+ __regmap_lockdep_wrapper(__regmap_init_ac97, #config, \
|
|
|
+ ac97, config)
|
|
|
+bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init(): Initialise managed register map
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @bus: Bus-specific callbacks to use with device
|
|
|
+ * @bus_context: Data passed to bus-specific callbacks
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. This function should generally not be called
|
|
|
+ * directly, it should be called by bus-specific init functions. The
|
|
|
+ * map will be automatically freed by the device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init(dev, bus, bus_context, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init, #config, \
|
|
|
+ dev, bus, bus_context, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_i2c(): Initialise managed register map
|
|
|
+ *
|
|
|
+ * @i2c: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The regmap will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_i2c(i2c, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_i2c, #config, \
|
|
|
+ i2c, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_spi(): Initialise register map
|
|
|
+ *
|
|
|
+ * @spi: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The map will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_spi(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_spi, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_spmi_base(): Create managed regmap for Base register space
|
|
|
+ * @sdev: SPMI device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The regmap will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_spmi_base(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_spmi_base, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_spmi_ext(): Create managed regmap for Ext register space
|
|
|
+ * @sdev: SPMI device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The regmap will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_spmi_ext(dev, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_spmi_ext, #config, \
|
|
|
+ dev, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_mmio_clk(): Initialise managed register map with clock
|
|
|
+ *
|
|
|
+ * @dev: Device that will be interacted with
|
|
|
+ * @clk_id: register clock consumer ID
|
|
|
+ * @regs: Pointer to memory-mapped IO region
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The regmap will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_mmio_clk(dev, clk_id, regs, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_mmio_clk, #config, \
|
|
|
+ dev, clk_id, regs, config)
|
|
|
|
|
|
/**
|
|
|
* devm_regmap_init_mmio(): Initialise managed register map
|
|
@@ -403,12 +648,22 @@ static inline struct regmap *regmap_init_mmio(struct device *dev,
|
|
|
* to a struct regmap. The regmap will be automatically freed by the
|
|
|
* device management code.
|
|
|
*/
|
|
|
-static inline struct regmap *devm_regmap_init_mmio(struct device *dev,
|
|
|
- void __iomem *regs,
|
|
|
- const struct regmap_config *config)
|
|
|
-{
|
|
|
- return devm_regmap_init_mmio_clk(dev, NULL, regs, config);
|
|
|
-}
|
|
|
+#define devm_regmap_init_mmio(dev, regs, config) \
|
|
|
+ devm_regmap_init_mmio_clk(dev, NULL, regs, config)
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_regmap_init_ac97(): Initialise AC'97 register map
|
|
|
+ *
|
|
|
+ * @ac97: Device that will be interacted with
|
|
|
+ * @config: Configuration for register map
|
|
|
+ *
|
|
|
+ * The return value will be an ERR_PTR() on error or a valid pointer
|
|
|
+ * to a struct regmap. The regmap will be automatically freed by the
|
|
|
+ * device management code.
|
|
|
+ */
|
|
|
+#define devm_regmap_init_ac97(ac97, config) \
|
|
|
+ __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config, \
|
|
|
+ ac97, config)
|
|
|
|
|
|
void regmap_exit(struct regmap *map);
|
|
|
int regmap_reinit_cache(struct regmap *map,
|
|
@@ -450,6 +705,8 @@ int regmap_get_max_register(struct regmap *map);
|
|
|
int regmap_get_reg_stride(struct regmap *map);
|
|
|
int regmap_async_complete(struct regmap *map);
|
|
|
bool regmap_can_raw_write(struct regmap *map);
|
|
|
+size_t regmap_get_raw_read_max(struct regmap *map);
|
|
|
+size_t regmap_get_raw_write_max(struct regmap *map);
|
|
|
|
|
|
int regcache_sync(struct regmap *map);
|
|
|
int regcache_sync_region(struct regmap *map, unsigned int min,
|