mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02: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
|
|
@ -794,11 +794,74 @@ MODULE_PARM_DESC(poll_interval,
|
||||||
static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
|
static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
|
||||||
bool single)
|
bool single)
|
||||||
{
|
{
|
||||||
/* Reports EINVAL for invalid/missing registers */
|
int ret;
|
||||||
|
|
||||||
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
|
||||||
return -EINVAL;
|
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_client *client = to_i2c_client(di->dev);
|
||||||
struct i2c_msg msg[2];
|
struct i2c_msg msg[2];
|
||||||
unsigned char data[2];
|
u8 data[2];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!client->adapter)
|
if (!client->adapter)
|
||||||
|
|
@ -68,6 +68,82 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
|
||||||
return ret;
|
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,
|
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
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->dev = &client->dev;
|
||||||
di->chip = id->driver_data;
|
di->chip = id->driver_data;
|
||||||
di->name = name;
|
di->name = name;
|
||||||
|
|
||||||
di->bus.read = bq27xxx_battery_i2c_read;
|
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);
|
ret = bq27xxx_battery_setup(di);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ struct bq27xxx_platform_data {
|
||||||
struct bq27xxx_device_info;
|
struct bq27xxx_device_info;
|
||||||
struct bq27xxx_access_methods {
|
struct bq27xxx_access_methods {
|
||||||
int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
|
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 {
|
struct bq27xxx_reg_cache {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user