Commit 63e67c57 authored by Ladislav Michl's avatar Ladislav Michl Committed by Sebastian Reichel

power: supply: ltc2941-battery-gauge: Prepare for LTC2942 and LTC2944

In order to support LTC2942 which has temperature registers
at different offsets than LTC2943 use following register naming
scheme (prefixes):
- LTC294X_ common registers
- LTC2942_ chips specific registers
- LTC2943_ specific registers

LTC2944 is compatible with LTC2943 but uses different constants
to compute voltage and current, so replace num_regs misused
for device indentification with real device id to discriminate
between those two.

There are no functional changes.
Signed-off-by: default avatarLadislav Michl <ladis@linux-mips.org>
Acked-by: default avatarDragos Bogdan <dragos.bogdan@analog.com>
Tested-by: default avatarDragos Bogdan <dragos.bogdan@analog.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
parent adcf04c9
...@@ -34,16 +34,19 @@ enum ltc294x_reg { ...@@ -34,16 +34,19 @@ enum ltc294x_reg {
LTC294X_REG_CONTROL = 0x01, LTC294X_REG_CONTROL = 0x01,
LTC294X_REG_ACC_CHARGE_MSB = 0x02, LTC294X_REG_ACC_CHARGE_MSB = 0x02,
LTC294X_REG_ACC_CHARGE_LSB = 0x03, LTC294X_REG_ACC_CHARGE_LSB = 0x03,
LTC294X_REG_THRESH_HIGH_MSB = 0x04,
LTC294X_REG_THRESH_HIGH_LSB = 0x05,
LTC294X_REG_THRESH_LOW_MSB = 0x06,
LTC294X_REG_THRESH_LOW_LSB = 0x07,
LTC294X_REG_VOLTAGE_MSB = 0x08, LTC294X_REG_VOLTAGE_MSB = 0x08,
LTC294X_REG_VOLTAGE_LSB = 0x09, LTC294X_REG_VOLTAGE_LSB = 0x09,
LTC294X_REG_CURRENT_MSB = 0x0E, LTC2942_REG_TEMPERATURE_MSB = 0x0C,
LTC294X_REG_CURRENT_LSB = 0x0F, LTC2942_REG_TEMPERATURE_LSB = 0x0D,
LTC294X_REG_TEMPERATURE_MSB = 0x14, LTC2943_REG_CURRENT_MSB = 0x0E,
LTC294X_REG_TEMPERATURE_LSB = 0x15, LTC2943_REG_CURRENT_LSB = 0x0F,
LTC2943_REG_TEMPERATURE_MSB = 0x14,
LTC2943_REG_TEMPERATURE_LSB = 0x15,
};
enum ltc294x_id {
LTC2941_ID,
LTC2943_ID,
}; };
#define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6)) #define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
...@@ -54,15 +57,12 @@ enum ltc294x_reg { ...@@ -54,15 +57,12 @@ enum ltc294x_reg {
((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK) ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
#define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0
#define LTC2941_NUM_REGS 0x08
#define LTC2943_NUM_REGS 0x18
struct ltc294x_info { struct ltc294x_info {
struct i2c_client *client; /* I2C Client pointer */ struct i2c_client *client; /* I2C Client pointer */
struct power_supply *supply; /* Supply pointer */ struct power_supply *supply; /* Supply pointer */
struct power_supply_desc supply_desc; /* Supply description */ struct power_supply_desc supply_desc; /* Supply description */
struct delayed_work work; /* Work scheduler */ struct delayed_work work; /* Work scheduler */
unsigned long num_regs; /* Number of registers (chip type) */ enum ltc294x_id id; /* Chip type */
int charge; /* Last charge register content */ int charge; /* Last charge register content */
int r_sense; /* mOhm */ int r_sense; /* mOhm */
int Qlsb; /* nAh */ int Qlsb; /* nAh */
...@@ -146,7 +146,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp) ...@@ -146,7 +146,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) | control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED; LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
/* Put the 2943 into "monitor" mode, so it measures every 10 sec */ /* Put the 2943 into "monitor" mode, so it measures every 10 sec */
if (info->num_regs == LTC2943_NUM_REGS) if (info->id == LTC2941_ID)
control |= LTC2943_REG_CONTROL_MODE_SCAN; control |= LTC2943_REG_CONTROL_MODE_SCAN;
if (value != control) { if (value != control) {
...@@ -263,7 +263,7 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val) ...@@ -263,7 +263,7 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
s32 value; s32 value;
ret = ltc294x_read_regs(info->client, ret = ltc294x_read_regs(info->client,
LTC294X_REG_CURRENT_MSB, &datar[0], 2); LTC2943_REG_CURRENT_MSB, &datar[0], 2);
value = (datar[0] << 8) | datar[1]; value = (datar[0] << 8) | datar[1];
value -= 0x7FFF; value -= 0x7FFF;
/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm, /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
...@@ -280,7 +280,7 @@ static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val) ...@@ -280,7 +280,7 @@ static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
u32 value; u32 value;
ret = ltc294x_read_regs(info->client, ret = ltc294x_read_regs(info->client,
LTC294X_REG_TEMPERATURE_MSB, &datar[0], 2); LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2);
value = (datar[0] << 8) | datar[1]; value = (datar[0] << 8) | datar[1];
/* Full-scale is 510 Kelvin, convert to centidegrees */ /* Full-scale is 510 Kelvin, convert to centidegrees */
*val = (((51000 * value) / 0xFFFF) - 27215); *val = (((51000 * value) / 0xFFFF) - 27215);
...@@ -357,8 +357,8 @@ static enum power_supply_property ltc294x_properties[] = { ...@@ -357,8 +357,8 @@ static enum power_supply_property ltc294x_properties[] = {
POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_CURRENT_NOW,
}; };
static int ltc294x_i2c_remove(struct i2c_client *client) static int ltc294x_i2c_remove(struct i2c_client *client)
...@@ -388,7 +388,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, ...@@ -388,7 +388,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
np = of_node_get(client->dev.of_node); np = of_node_get(client->dev.of_node);
info->num_regs = (unsigned long)of_device_get_match_data(&client->dev); info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
info->supply_desc.name = np->name; info->supply_desc.name = np->name;
/* r_sense can be negative, when sense+ is connected to the battery /* r_sense can be negative, when sense+ is connected to the battery
...@@ -409,7 +409,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, ...@@ -409,7 +409,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
prescaler_exp = LTC2941_MAX_PRESCALER_EXP; prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
} }
if (info->num_regs == LTC2943_NUM_REGS) { if (info->id == LTC2943_ID) {
if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP) if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
prescaler_exp = LTC2943_MAX_PRESCALER_EXP; prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
info->Qlsb = ((340 * 50000) / r_sense) / info->Qlsb = ((340 * 50000) / r_sense) /
...@@ -424,18 +424,17 @@ static int ltc294x_i2c_probe(struct i2c_client *client, ...@@ -424,18 +424,17 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
info->client = client; info->client = client;
info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
info->supply_desc.properties = ltc294x_properties; info->supply_desc.properties = ltc294x_properties;
if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) switch (info->id) {
case LTC2943_ID:
info->supply_desc.num_properties = info->supply_desc.num_properties =
ARRAY_SIZE(ltc294x_properties); ARRAY_SIZE(ltc294x_properties);
else if (info->num_regs >= LTC294X_REG_CURRENT_LSB) break;
info->supply_desc.num_properties = case LTC2941_ID:
ARRAY_SIZE(ltc294x_properties) - 1; default:
else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB)
info->supply_desc.num_properties =
ARRAY_SIZE(ltc294x_properties) - 2;
else
info->supply_desc.num_properties = info->supply_desc.num_properties =
ARRAY_SIZE(ltc294x_properties) - 3; ARRAY_SIZE(ltc294x_properties) - 3;
break;
}
info->supply_desc.get_property = ltc294x_get_property; info->supply_desc.get_property = ltc294x_get_property;
info->supply_desc.set_property = ltc294x_set_property; info->supply_desc.set_property = ltc294x_set_property;
info->supply_desc.property_is_writeable = ltc294x_property_is_writeable; info->supply_desc.property_is_writeable = ltc294x_property_is_writeable;
...@@ -492,8 +491,8 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume); ...@@ -492,8 +491,8 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
static const struct i2c_device_id ltc294x_i2c_id[] = { static const struct i2c_device_id ltc294x_i2c_id[] = {
{"ltc2941", LTC2941_NUM_REGS}, { "ltc2941", LTC2941_ID, },
{"ltc2943", LTC2943_NUM_REGS}, { "ltc2943", LTC2943_ID, },
{ }, { },
}; };
MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
...@@ -501,11 +500,11 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id); ...@@ -501,11 +500,11 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
static const struct of_device_id ltc294x_i2c_of_match[] = { static const struct of_device_id ltc294x_i2c_of_match[] = {
{ {
.compatible = "lltc,ltc2941", .compatible = "lltc,ltc2941",
.data = (void *)LTC2941_NUM_REGS .data = (void *)LTC2941_ID,
}, },
{ {
.compatible = "lltc,ltc2943", .compatible = "lltc,ltc2943",
.data = (void *)LTC2943_NUM_REGS .data = (void *)LTC2943_ID,
}, },
{ }, { },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment