Merge "power: supply: bq27xxx: update the resistance table"
This commit is contained in:
commit
7c12c5ac25
4 changed files with 146 additions and 4 deletions
|
|
@ -295,6 +295,18 @@ config BATTERY_BQ27XXX_DT_UPDATES_NVM
|
|||
general-purpose kernels, as this can cause misconfiguration of a
|
||||
smart battery with embedded NVM/flash.
|
||||
|
||||
config BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
bool "BQ27xxx resistance table update of NVM/flash data memory"
|
||||
depends on BATTERY_BQ27XXX_DT_UPDATES_NVM
|
||||
help
|
||||
Say Y here to enable devicetree monitored-battery resistance table config
|
||||
and Qmax-cell0 value in the NVM/flash data memory. Only enable this option
|
||||
when calibrated resistance table and Qmax-Cell0 parameters for the battery
|
||||
in-use are updated in DT. If the Battery specific data is not available
|
||||
in DT, then this config should not be set to Y. Not for general-purpose
|
||||
kernels, as this can cause is the configuration of a smart battery with
|
||||
embedded NVM/flash.
|
||||
|
||||
config BATTERY_DA9030
|
||||
tristate "DA9030 battery driver"
|
||||
depends on PMIC_DA903X
|
||||
|
|
|
|||
|
|
@ -866,7 +866,25 @@ enum bq27xxx_dm_reg_id {
|
|||
BQ27XXX_DM_DESIGN_CAPACITY = 0,
|
||||
BQ27XXX_DM_DESIGN_ENERGY,
|
||||
BQ27XXX_DM_TERMINATE_VOLTAGE,
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
BQ27XXX_DM_TAPER_RATE,
|
||||
BQ27XXX_DM_QMAX,
|
||||
BQ27XXX_RAM_R_A0_0,
|
||||
BQ27XXX_RAM_R_A0_1,
|
||||
BQ27XXX_RAM_R_A0_2,
|
||||
BQ27XXX_RAM_R_A0_3,
|
||||
BQ27XXX_RAM_R_A0_4,
|
||||
BQ27XXX_RAM_R_A0_5,
|
||||
BQ27XXX_RAM_R_A0_6,
|
||||
BQ27XXX_RAM_R_A0_7,
|
||||
BQ27XXX_RAM_R_A0_8,
|
||||
BQ27XXX_RAM_R_A0_9,
|
||||
BQ27XXX_RAM_R_A0_10,
|
||||
BQ27XXX_RAM_R_A0_11,
|
||||
BQ27XXX_RAM_R_A0_12,
|
||||
BQ27XXX_RAM_R_A0_13,
|
||||
BQ27XXX_RAM_R_A0_14,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define bq27000_dm_regs NULL
|
||||
|
|
@ -921,7 +939,25 @@ static struct bq27xxx_dm_reg bq27421_dm_regs[] = {
|
|||
[BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 8000 },
|
||||
[BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },
|
||||
[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2500, 3700 },
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
[BQ27XXX_DM_TAPER_RATE] = { 82, 27, 2, 0, 2000 }, /* Taper rate */
|
||||
[BQ27XXX_DM_QMAX] = { 82, 0, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_0] = { 89, 0, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_1] = { 89, 2, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_2] = { 89, 4, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_3] = { 89, 6, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_4] = { 89, 8, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_5] = { 89, 10, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_6] = { 89, 12, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_7] = { 89, 14, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_8] = { 89, 16, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_9] = { 89, 18, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_10] = { 89, 20, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_11] = { 89, 22, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_12] = { 89, 24, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_13] = { 89, 26, 2, 0, 32767 },
|
||||
[BQ27XXX_RAM_R_A0_14] = { 89, 28, 2, 0, 32767 },
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct bq27xxx_dm_reg bq27425_dm_regs[] = {
|
||||
|
|
@ -1060,7 +1096,26 @@ static const char * const bq27xxx_dm_reg_name[] = {
|
|||
[BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
|
||||
[BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
|
||||
[BQ27XXX_DM_TERMINATE_VOLTAGE] = "terminate-voltage",
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
[BQ27XXX_DM_TAPER_RATE] = "Taper-rate",
|
||||
[BQ27XXX_DM_QMAX] = "QMAX-Cell",
|
||||
[BQ27XXX_RAM_R_A0_0] = "R_A0_0",
|
||||
[BQ27XXX_RAM_R_A0_1] = "R_A0_1",
|
||||
[BQ27XXX_RAM_R_A0_2] = "R_A0_2",
|
||||
[BQ27XXX_RAM_R_A0_3] = "R_A0_3",
|
||||
[BQ27XXX_RAM_R_A0_4] = "R_A0_4",
|
||||
[BQ27XXX_RAM_R_A0_5] = "R_A0_5",
|
||||
[BQ27XXX_RAM_R_A0_6] = "R_A0_6",
|
||||
[BQ27XXX_RAM_R_A0_7] = "R_A0_7",
|
||||
[BQ27XXX_RAM_R_A0_8] = "R_A0_8",
|
||||
[BQ27XXX_RAM_R_A0_9] = "R_A0_9",
|
||||
[BQ27XXX_RAM_R_A0_10] = "R_A0_10",
|
||||
[BQ27XXX_RAM_R_A0_11] = "R_A0_11",
|
||||
[BQ27XXX_RAM_R_A0_12] = "R_A0_12",
|
||||
[BQ27XXX_RAM_R_A0_13] = "R_A0_13",
|
||||
[BQ27XXX_RAM_R_A0_14] = "R_A0_14",
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1435,7 +1490,10 @@ static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
|
|||
struct bq27xxx_dm_buf bd = BQ27XXX_DM_BUF(di, BQ27XXX_DM_DESIGN_CAPACITY);
|
||||
struct bq27xxx_dm_buf bt = BQ27XXX_DM_BUF(di, BQ27XXX_DM_TERMINATE_VOLTAGE);
|
||||
bool updated;
|
||||
u32 taper_rate, i;
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
struct bq27xxx_dm_buf rt = BQ27XXX_DM_BUF(di, BQ27XXX_RAM_R_A0_0);
|
||||
u32 i, taper_rate;
|
||||
#endif
|
||||
|
||||
if (bq27xxx_battery_unseal(di) < 0)
|
||||
return;
|
||||
|
|
@ -1443,8 +1501,7 @@ static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
|
|||
if (info->charge_full_design_uah != -EINVAL &&
|
||||
info->energy_full_design_uwh != -EINVAL) {
|
||||
bq27xxx_battery_read_dm_block(di, &bd);
|
||||
taper_rate = (u32)((info->charge_full_design_uah * 10) /
|
||||
info->charge_term_current_ua);
|
||||
|
||||
/* assume design energy, taper_rate & capacity are in same block */
|
||||
bq27xxx_battery_update_dm_block(di, &bd,
|
||||
BQ27XXX_DM_DESIGN_CAPACITY,
|
||||
|
|
@ -1452,9 +1509,22 @@ static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
|
|||
bq27xxx_battery_update_dm_block(di, &bd,
|
||||
BQ27XXX_DM_DESIGN_ENERGY,
|
||||
info->energy_full_design_uwh / 1000);
|
||||
/* update Taper rate based on the capacity and term current*/
|
||||
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
bq27xxx_battery_read_dm_block(di, &rt);
|
||||
/* update Taper rate based on the capacity and term current */
|
||||
taper_rate = (u32)((info->charge_full_design_uah * 10) /
|
||||
info->charge_term_current_ua);
|
||||
bq27xxx_battery_update_dm_block(di, &bd, BQ27XXX_DM_TAPER_RATE,
|
||||
taper_rate);
|
||||
/* update the QMAX-CELL0 and resistance table */
|
||||
bq27xxx_battery_update_dm_block(di, &bd, BQ27XXX_DM_QMAX,
|
||||
di->qmax_cell0);
|
||||
for (i = 0 ; i < 15; i++)
|
||||
bq27xxx_battery_update_dm_block(di, &rt,
|
||||
(i + BQ27XXX_RAM_R_A0_0),
|
||||
di->resist_table[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (info->voltage_min_design_uv != -EINVAL) {
|
||||
|
|
@ -1471,10 +1541,19 @@ static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
|
|||
bq27xxx_battery_write_dm_block(di, &bd);
|
||||
bq27xxx_battery_write_dm_block(di, &bt);
|
||||
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
bq27xxx_battery_write_dm_block(di, &rt);
|
||||
|
||||
bq27xxx_battery_read_dm_block(di, &bd);
|
||||
for (i = 0; i < BQ27XXX_DM_SZ; i++)
|
||||
dev_dbg(di->dev, "BQ27xxx: DM_NVM[%d]: 0x%04x\n", i, bd.data[i]);
|
||||
|
||||
bq27xxx_battery_read_dm_block(di, &rt);
|
||||
for (i = 0; i < BQ27XXX_DM_SZ; i++)
|
||||
dev_dbg(di->dev, "BQ27xxx: Resisiatnce table DM_NVM[%d]:0x%04x\n",
|
||||
i, rt.data[i]);
|
||||
#endif
|
||||
|
||||
bq27xxx_battery_seal(di);
|
||||
|
||||
if (updated && !(di->opts & BQ27XXX_O_CFGUP)) {
|
||||
|
|
|
|||
|
|
@ -136,6 +136,37 @@ static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
static int bq27xx_parse_dt(struct bq27xxx_device_info *di,
|
||||
struct device *dev,
|
||||
struct device_node *battery_np)
|
||||
{
|
||||
int ret;
|
||||
int rc;
|
||||
|
||||
ret = of_property_read_u32(battery_np, "qmax-cell0", &di->qmax_cell0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Undefined Qmax-Cell0\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
rc = of_property_count_elems_of_size(battery_np, "resist-table",
|
||||
sizeof(u32));
|
||||
|
||||
if (rc != BQ27XXX_RESISTANCE_TABLE_LENGTH) {
|
||||
dev_err(dev, "Invalid number of elements in resist-table\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32_array(battery_np, "resist-table",
|
||||
di->resist_table, BQ27XXX_RESISTANCE_TABLE_LENGTH);
|
||||
if (ret)
|
||||
dev_err(dev, "Undefined resistance table\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
|
@ -143,6 +174,9 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
|||
int ret;
|
||||
char *name;
|
||||
int num;
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
struct device_node *battery_np_rt;
|
||||
#endif
|
||||
|
||||
/* Get new ID for the new battery device */
|
||||
mutex_lock(&battery_mutex);
|
||||
|
|
@ -169,6 +203,17 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
|
|||
di->bus.read_bulk = bq27xxx_battery_i2c_bulk_read;
|
||||
di->bus.write_bulk = bq27xxx_battery_i2c_bulk_write;
|
||||
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
battery_np_rt = of_parse_phandle(client->dev.of_node,
|
||||
"bat-resist-table", 0);
|
||||
if (!battery_np_rt)
|
||||
return -ENODEV;
|
||||
ret = bq27xx_parse_dt(di, di->dev, battery_np_rt);
|
||||
of_node_put(battery_np_rt);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
ret = bq27xxx_battery_setup(di);
|
||||
if (ret)
|
||||
goto err_failed;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include <linux/power_supply.h>
|
||||
|
||||
#define BQ27XXX_RESISTANCE_TABLE_LENGTH 15
|
||||
|
||||
enum bq27xxx_chip {
|
||||
BQ27000 = 1, /* bq27000, bq27200 */
|
||||
BQ27010, /* bq27010, bq27210 */
|
||||
|
|
@ -78,6 +80,10 @@ struct bq27xxx_device_info {
|
|||
struct list_head list;
|
||||
struct mutex lock;
|
||||
u8 *regs;
|
||||
#ifdef CONFIG_BATTERY_BQ27XXX_RESIST_TABLE_UPDATES_NVM
|
||||
u32 qmax_cell0;
|
||||
u32 resist_table[BQ27XXX_RESISTANCE_TABLE_LENGTH];
|
||||
#endif
|
||||
};
|
||||
|
||||
void bq27xxx_battery_update(struct bq27xxx_device_info *di);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue