regmap: Changes for v4.19
Several small new features for regmap this time around: - Support for SCCB, an I2C variant used on some media cards. This has also pulled in an I2C commit from Peter Rosin as a dependency. - Addition of an API for reading repeatedly from registers where the address doesn't automatically increment like some ADC outputs or GPIO status registers. - Support for bulk I/O on Slimbus. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAltxUxYTHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0B26B/9A/Q9P+92i0LZ2ecO3QltvPeIP46jR gnS3WEmgMk/yIWR9wusF3Ju4gfTZ4L5DEkl+5iooqlg54e3c8l3OdDIsRXXiLtIK +BOU9xW4u4sdmGjuXqkkGCWgz75r/Em07Z4y3pB5kl/KHGtQPOrrvS8/33ETjhKC tg/SC8bdJ6ZSC2J1lVYA+IolNfVt0rvjY3TdXwm0qel9SmQIqrL8xilj/JV8Hmhg 6PSH9PIoIkSRgvqp1N0IOysVcDcwgjAEyg3eeH+L2S0y/YMPY88ndf7d8mpWdkzQ KGEUxgB+qWBHMjRKTgu4sqal1KZxCPghxO5kRn4UBaZsxFDdnXbtDcRQ =e1ml -----END PGP SIGNATURE----- Merge tag 'regmap-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap Pull regmap updates from Mark Brown: "Several small new features for regmap this time around: - Support for SCCB, an I2C variant used on some media cards. This has also pulled in an I2C commit from Peter Rosin as a dependency. - Addition of an API for reading repeatedly from registers where the address doesn't automatically increment like some ADC outputs or GPIO status registers. - Support for bulk I/O on Slimbus" * tag 'regmap-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: Add regmap_noinc_read API regmap: sccb: fix typo and sort headers alphabetically i2c: smbus: add unlocked __i2c_smbus_xfer variant regmap: add SCCB support regmap: slimbus: add support to multi read/write
This commit is contained in:
Коммит
15bc88cd5f
|
@ -45,3 +45,7 @@ config REGMAP_IRQ
|
|||
config REGMAP_SOUNDWIRE
|
||||
tristate
|
||||
depends on SOUNDWIRE_BUS
|
||||
|
||||
config REGMAP_SCCB
|
||||
tristate
|
||||
depends on I2C
|
||||
|
|
|
@ -15,3 +15,4 @@ obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
|
|||
obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
|
||||
obj-$(CONFIG_REGMAP_W1) += regmap-w1.o
|
||||
obj-$(CONFIG_REGMAP_SOUNDWIRE) += regmap-sdw.o
|
||||
obj-$(CONFIG_REGMAP_SCCB) += regmap-sccb.o
|
||||
|
|
|
@ -94,10 +94,12 @@ struct regmap {
|
|||
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);
|
||||
const struct regmap_access_table *wr_table;
|
||||
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;
|
||||
|
||||
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
|
||||
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
|
||||
|
@ -181,6 +183,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg);
|
|||
bool regmap_readable(struct regmap *map, unsigned int reg);
|
||||
bool regmap_volatile(struct regmap *map, unsigned int reg);
|
||||
bool regmap_precious(struct regmap *map, unsigned int reg);
|
||||
bool regmap_readable_noinc(struct regmap *map, unsigned int reg);
|
||||
|
||||
int _regmap_write(struct regmap *map, unsigned int reg,
|
||||
unsigned int val);
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Register map access API - SCCB support
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* sccb_is_available - Check if the adapter supports SCCB protocol
|
||||
* @adap: I2C adapter
|
||||
*
|
||||
* Return true if the I2C adapter is capable of using SCCB helper functions,
|
||||
* false otherwise.
|
||||
*/
|
||||
static bool sccb_is_available(struct i2c_adapter *adap)
|
||||
{
|
||||
u32 needed_funcs = I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
|
||||
|
||||
/*
|
||||
* If we ever want support for hardware doing SCCB natively, we will
|
||||
* introduce a sccb_xfer() callback to struct i2c_algorithm and check
|
||||
* for it here.
|
||||
*/
|
||||
|
||||
return (i2c_get_functionality(adap) & needed_funcs) == needed_funcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* regmap_sccb_read - Read data from SCCB slave device
|
||||
* @context: Device that will be interacted with
|
||||
* @reg: Register to be read from
|
||||
* @val: Pointer to store read value
|
||||
*
|
||||
* This executes the 2-phase write transmission cycle that is followed by a
|
||||
* 2-phase read transmission cycle, returning negative errno else zero on
|
||||
* success.
|
||||
*/
|
||||
static int regmap_sccb_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
int ret;
|
||||
union i2c_smbus_data data;
|
||||
|
||||
i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
|
||||
|
||||
ret = __i2c_smbus_xfer(i2c->adapter, i2c->addr, i2c->flags,
|
||||
I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE, NULL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = __i2c_smbus_xfer(i2c->adapter, i2c->addr, i2c->flags,
|
||||
I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
*val = data.byte;
|
||||
out:
|
||||
i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* regmap_sccb_write - Write data to SCCB slave device
|
||||
* @context: Device that will be interacted with
|
||||
* @reg: Register to write to
|
||||
* @val: Value to be written
|
||||
*
|
||||
* This executes the SCCB 3-phase write transmission cycle, returning negative
|
||||
* errno else zero on success.
|
||||
*/
|
||||
static int regmap_sccb_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
|
||||
return i2c_smbus_write_byte_data(i2c, reg, val);
|
||||
}
|
||||
|
||||
static struct regmap_bus regmap_sccb_bus = {
|
||||
.reg_write = regmap_sccb_write,
|
||||
.reg_read = regmap_sccb_read,
|
||||
};
|
||||
|
||||
static const struct regmap_bus *regmap_get_sccb_bus(struct i2c_client *i2c,
|
||||
const struct regmap_config *config)
|
||||
{
|
||||
if (config->val_bits == 8 && config->reg_bits == 8 &&
|
||||
sccb_is_available(i2c->adapter))
|
||||
return ®map_sccb_bus;
|
||||
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
struct regmap *__regmap_init_sccb(struct i2c_client *i2c,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
const struct regmap_bus *bus = regmap_get_sccb_bus(i2c, config);
|
||||
|
||||
if (IS_ERR(bus))
|
||||
return ERR_CAST(bus);
|
||||
|
||||
return __regmap_init(&i2c->dev, bus, &i2c->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_sccb);
|
||||
|
||||
struct regmap *__devm_regmap_init_sccb(struct i2c_client *i2c,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
const struct regmap_bus *bus = regmap_get_sccb_bus(i2c, config);
|
||||
|
||||
if (IS_ERR(bus))
|
||||
return ERR_CAST(bus);
|
||||
|
||||
return __devm_regmap_init(&i2c->dev, bus, &i2c->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_sccb);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -7,33 +7,24 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
|
||||
unsigned int *val)
|
||||
static int regmap_slimbus_write(void *context, const void *data, size_t count)
|
||||
{
|
||||
struct slim_device *sdev = context;
|
||||
int v;
|
||||
|
||||
v = slim_readb(sdev, reg);
|
||||
|
||||
if (v < 0)
|
||||
return v;
|
||||
|
||||
*val = v;
|
||||
|
||||
return 0;
|
||||
return slim_write(sdev, *(u16 *)data, count - 2, (u8 *)data + 2);
|
||||
}
|
||||
|
||||
static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
|
||||
unsigned int val)
|
||||
static int regmap_slimbus_read(void *context, const void *reg, size_t reg_size,
|
||||
void *val, size_t val_size)
|
||||
{
|
||||
struct slim_device *sdev = context;
|
||||
|
||||
return slim_writeb(sdev, reg, val);
|
||||
return slim_read(sdev, *(u16 *)reg, val_size, val);
|
||||
}
|
||||
|
||||
static struct regmap_bus regmap_slimbus_bus = {
|
||||
.reg_write = regmap_slimbus_byte_reg_write,
|
||||
.reg_read = regmap_slimbus_byte_reg_read,
|
||||
.write = regmap_slimbus_write,
|
||||
.read = regmap_slimbus_read,
|
||||
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
|
||||
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
|
|
@ -168,6 +168,17 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool regmap_readable_noinc(struct regmap *map, unsigned int reg)
|
||||
{
|
||||
if (map->readable_noinc_reg)
|
||||
return map->readable_noinc_reg(map->dev, reg);
|
||||
|
||||
if (map->rd_noinc_table)
|
||||
return regmap_check_range_table(map, reg, map->rd_noinc_table);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
|
||||
size_t num)
|
||||
{
|
||||
|
@ -766,10 +777,12 @@ struct regmap *__regmap_init(struct device *dev,
|
|||
map->rd_table = config->rd_table;
|
||||
map->volatile_table = config->volatile_table;
|
||||
map->precious_table = config->precious_table;
|
||||
map->rd_noinc_table = config->rd_noinc_table;
|
||||
map->writeable_reg = config->writeable_reg;
|
||||
map->readable_reg = config->readable_reg;
|
||||
map->volatile_reg = config->volatile_reg;
|
||||
map->precious_reg = config->precious_reg;
|
||||
map->readable_noinc_reg = config->readable_noinc_reg;
|
||||
map->cache_type = config->cache_type;
|
||||
|
||||
spin_lock_init(&map->async_lock);
|
||||
|
@ -1285,6 +1298,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
|
|||
map->readable_reg = config->readable_reg;
|
||||
map->volatile_reg = config->volatile_reg;
|
||||
map->precious_reg = config->precious_reg;
|
||||
map->readable_noinc_reg = config->readable_noinc_reg;
|
||||
map->cache_type = config->cache_type;
|
||||
|
||||
regmap_debugfs_init(map, config->name);
|
||||
|
@ -2564,7 +2578,70 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|||
EXPORT_SYMBOL_GPL(regmap_raw_read);
|
||||
|
||||
/**
|
||||
* regmap_field_read() - Read a value to a single register field
|
||||
* regmap_noinc_read(): Read data from a register without incrementing the
|
||||
* register number
|
||||
*
|
||||
* @map: Register map to read from
|
||||
* @reg: Register to read from
|
||||
* @val: Pointer to data buffer
|
||||
* @val_len: Length of output buffer in bytes.
|
||||
*
|
||||
* The regmap API usually assumes that bulk bus read operations will read a
|
||||
* range of registers. Some devices have certain registers for which a read
|
||||
* operation read will read from an internal FIFO.
|
||||
*
|
||||
* The target register must be volatile but registers after it can be
|
||||
* completely unrelated cacheable registers.
|
||||
*
|
||||
* This will attempt multiple reads as required to read val_len bytes.
|
||||
*
|
||||
* A value of zero will be returned on success, a negative errno will be
|
||||
* returned in error cases.
|
||||
*/
|
||||
int regmap_noinc_read(struct regmap *map, unsigned int reg,
|
||||
void *val, size_t val_len)
|
||||
{
|
||||
size_t read_len;
|
||||
int ret;
|
||||
|
||||
if (!map->bus)
|
||||
return -EINVAL;
|
||||
if (!map->bus->read)
|
||||
return -ENOTSUPP;
|
||||
if (val_len % map->format.val_bytes)
|
||||
return -EINVAL;
|
||||
if (!IS_ALIGNED(reg, map->reg_stride))
|
||||
return -EINVAL;
|
||||
if (val_len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
|
||||
if (!regmap_volatile(map, reg) || !regmap_readable_noinc(map, reg)) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
while (val_len) {
|
||||
if (map->max_raw_read && map->max_raw_read < val_len)
|
||||
read_len = map->max_raw_read;
|
||||
else
|
||||
read_len = val_len;
|
||||
ret = _regmap_raw_read(map, reg, val, read_len);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
val = ((u8 *)val) + read_len;
|
||||
val_len -= read_len;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
map->unlock(map->lock_arg);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_noinc_read);
|
||||
|
||||
/**
|
||||
* regmap_field_read(): Read a value to a single register field
|
||||
*
|
||||
* @field: Register field to read from
|
||||
* @val: Pointer to store read value
|
||||
|
|
|
@ -463,7 +463,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
|
|||
msg[num-1].len++;
|
||||
}
|
||||
|
||||
status = i2c_transfer(adapter, msg, num);
|
||||
status = __i2c_transfer(adapter, msg, num);
|
||||
if (status < 0)
|
||||
goto cleanup;
|
||||
if (status != num) {
|
||||
|
@ -524,9 +524,24 @@ cleanup:
|
|||
* This executes an SMBus protocol operation, and returns a negative
|
||||
* errno code else zero on success.
|
||||
*/
|
||||
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||
char read_write, u8 command, int protocol,
|
||||
union i2c_smbus_data *data)
|
||||
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned short flags, char read_write,
|
||||
u8 command, int protocol, union i2c_smbus_data *data)
|
||||
{
|
||||
s32 res;
|
||||
|
||||
i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||
res = __i2c_smbus_xfer(adapter, addr, flags, read_write,
|
||||
command, protocol, data);
|
||||
i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_smbus_xfer);
|
||||
|
||||
s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned short flags, char read_write,
|
||||
u8 command, int protocol, union i2c_smbus_data *data)
|
||||
{
|
||||
unsigned long orig_jiffies;
|
||||
int try;
|
||||
|
@ -543,8 +558,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
|||
flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
|
||||
|
||||
if (adapter->algo->smbus_xfer) {
|
||||
i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||
|
||||
/* Retry automatically on arbitration loss */
|
||||
orig_jiffies = jiffies;
|
||||
for (res = 0, try = 0; try <= adapter->retries; try++) {
|
||||
|
@ -557,7 +570,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
|||
orig_jiffies + adapter->timeout))
|
||||
break;
|
||||
}
|
||||
i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||
|
||||
if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
|
||||
goto trace;
|
||||
|
@ -579,7 +591,7 @@ trace:
|
|||
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_smbus_xfer);
|
||||
EXPORT_SYMBOL(__i2c_smbus_xfer);
|
||||
|
||||
/**
|
||||
* i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
|
||||
|
|
|
@ -140,9 +140,14 @@ extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
|||
and probably just as fast.
|
||||
Note that we use i2c_adapter here, because you do not need a specific
|
||||
smbus adapter to call this function. */
|
||||
extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned short flags, char read_write, u8 command,
|
||||
int size, union i2c_smbus_data *data);
|
||||
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned short flags, char read_write, u8 command,
|
||||
int protocol, union i2c_smbus_data *data);
|
||||
|
||||
/* Unlocked flavor */
|
||||
s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned short flags, char read_write, u8 command,
|
||||
int protocol, union i2c_smbus_data *data);
|
||||
|
||||
/* Now follow the 'nice' access routines. These also document the calling
|
||||
conventions of i2c_smbus_xfer. */
|
||||
|
|
|
@ -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;
|
||||
|
@ -514,6 +524,10 @@ 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_sccb(struct i2c_client *i2c,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name);
|
||||
struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
|
@ -558,6 +572,10 @@ 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_sccb(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,
|
||||
|
@ -645,6 +663,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
|
|||
__regmap_lockdep_wrapper(__regmap_init_i2c, #config, \
|
||||
i2c, config)
|
||||
|
||||
/**
|
||||
* regmap_init_sccb() - 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_sccb(i2c, config) \
|
||||
__regmap_lockdep_wrapper(__regmap_init_sccb, #config, \
|
||||
i2c, config)
|
||||
|
||||
/**
|
||||
* regmap_init_slimbus() - Initialise register map
|
||||
*
|
||||
|
@ -797,6 +828,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
|
|||
__regmap_lockdep_wrapper(__devm_regmap_init_i2c, #config, \
|
||||
i2c, config)
|
||||
|
||||
/**
|
||||
* devm_regmap_init_sccb() - 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_sccb(i2c, config) \
|
||||
__regmap_lockdep_wrapper(__devm_regmap_init_sccb, #config, \
|
||||
i2c, config)
|
||||
|
||||
/**
|
||||
* devm_regmap_init_spi() - Initialise register map
|
||||
*
|
||||
|
@ -946,6 +991,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 +1243,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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче