mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 08:24:47 +01:00
power: supply: bq27xxx: Add bulk transfer bus methods
Declare bus.write/read_bulk/write_bulk(). Add I2C write/read_bulk/write_bulk() to implement the above. Add bq27xxx_write/read_block/write_block() helpers to call the above. Signed-off-by: Matt Ranostay <matt@ranostay.consulting> Signed-off-by: Liam Breck <kernel@networkimprov.net> Acked-by: "Andrew F. Davis" <afd@ti.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
This commit is contained in:
parent
e2517f3bb4
commit
14073f6614
3 changed files with 149 additions and 3 deletions
|
|
@ -794,11 +794,74 @@ MODULE_PARM_DESC(poll_interval,
|
|||
static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
|
||||
bool single)
|
||||
{
|
||||
/* Reports EINVAL for invalid/missing registers */
|
||||
int ret;
|
||||
|
||||
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
return di->bus.read(di, di->regs[reg_index], single);
|
||||
ret = di->bus.read(di, di->regs[reg_index], single);
|
||||
if (ret < 0)
|
||||
dev_dbg(di->dev, "failed to read register 0x%02x (index %d)\n",
|
||||
di->regs[reg_index], reg_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index,
|
||||
u16 value, bool single)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
if (!di->bus.write)
|
||||
return -EPERM;
|
||||
|
||||
ret = di->bus.write(di, di->regs[reg_index], value, single);
|
||||
if (ret < 0)
|
||||
dev_dbg(di->dev, "failed to write register 0x%02x (index %d)\n",
|
||||
di->regs[reg_index], reg_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_index,
|
||||
u8 *data, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
if (!di->bus.read_bulk)
|
||||
return -EPERM;
|
||||
|
||||
ret = di->bus.read_bulk(di, di->regs[reg_index], data, len);
|
||||
if (ret < 0)
|
||||
dev_dbg(di->dev, "failed to read_bulk register 0x%02x (index %d)\n",
|
||||
di->regs[reg_index], reg_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_index,
|
||||
u8 *data, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
if (!di->bus.write_bulk)
|
||||
return -EPERM;
|
||||
|
||||
ret = di->bus.write_bulk(di, di->regs[reg_index], data, len);
|
||||
if (ret < 0)
|
||||
dev_dbg(di->dev, "failed to write_bulk register 0x%02x (index %d)\n",
|
||||
di->regs[reg_index], reg_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
|
|||
{
|
||||
struct i2c_client *client = to_i2c_client(di->dev);
|
||||
struct i2c_msg msg[2];
|
||||
unsigned char data[2];
|
||||
u8 data[2];
|
||||
int ret;
|
||||
|
||||
if (!client->adapter)
|
||||
|
|
@ -68,6 +68,82 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int bq27xxx_battery_i2c_write(struct bq27xxx_device_info *di, u8 reg,
|
||||
int value, bool single)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(di->dev);
|
||||
struct i2c_msg msg;
|
||||
u8 data[4];
|
||||
int ret;
|
||||
|
||||
if (!client->adapter)
|
||||
return -ENODEV;
|
||||
|
||||
data[0] = reg;
|
||||
if (single) {
|
||||
data[1] = (u8) value;
|
||||
msg.len = 2;
|
||||
} else {
|
||||
put_unaligned_le16(value, &data[1]);
|
||||
msg.len = 3;
|
||||
}
|
||||
|
||||
msg.buf = data;
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
|
||||
ret = i2c_transfer(client->adapter, &msg, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq27xxx_battery_i2c_bulk_read(struct bq27xxx_device_info *di, u8 reg,
|
||||
u8 *data, int len)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(di->dev);
|
||||
int ret;
|
||||
|
||||
if (!client->adapter)
|
||||
return -ENODEV;
|
||||
|
||||
ret = i2c_smbus_read_i2c_block_data(client, reg, len, data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != len)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
|
||||
u8 reg, u8 *data, int len)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(di->dev);
|
||||
struct i2c_msg msg;
|
||||
u8 buf[33];
|
||||
int ret;
|
||||
|
||||
if (!client->adapter)
|
||||
return -ENODEV;
|
||||
|
||||
buf[0] = reg;
|
||||
memcpy(&buf[1], data, len);
|
||||
|
||||
msg.buf = buf;
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
msg.len = len + 1;
|
||||
|
||||
ret = i2c_transfer(client->adapter, &msg, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
|
@ -95,7 +171,11 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
|||
di->dev = &client->dev;
|
||||
di->chip = id->driver_data;
|
||||
di->name = name;
|
||||
|
||||
di->bus.read = bq27xxx_battery_i2c_read;
|
||||
di->bus.write = bq27xxx_battery_i2c_write;
|
||||
di->bus.read_bulk = bq27xxx_battery_i2c_bulk_read;
|
||||
di->bus.write_bulk = bq27xxx_battery_i2c_bulk_write;
|
||||
|
||||
ret = bq27xxx_battery_setup(di);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ struct bq27xxx_platform_data {
|
|||
struct bq27xxx_device_info;
|
||||
struct bq27xxx_access_methods {
|
||||
int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
|
||||
int (*write)(struct bq27xxx_device_info *di, u8 reg, int value, bool single);
|
||||
int (*read_bulk)(struct bq27xxx_device_info *di, u8 reg, u8 *data, int len);
|
||||
int (*write_bulk)(struct bq27xxx_device_info *di, u8 reg, u8 *data, int len);
|
||||
};
|
||||
|
||||
struct bq27xxx_reg_cache {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue