summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/power/supply/bq27xxx_battery.c120
-rw-r--r--drivers/power/supply/bq27xxx_battery_i2c.c16
-rw-r--r--include/linux/power/bq27xxx_battery.h9
3 files changed, 86 insertions, 59 deletions
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 00322ccf09b5..cf0f19e2a639 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -221,6 +221,7 @@ static u8
[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
BQ27XXX_DM_REG_ROWS,
},
+#define bq2752x_regs bq2751x_regs
bq27500_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
[BQ27XXX_REG_TEMP] = 0x06,
@@ -401,6 +402,7 @@ static u8
[BQ27XXX_REG_AP] = 0x24,
BQ27XXX_DM_REG_ROWS,
},
+#define bq27531_regs bq27530_regs
bq27541_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
[BQ27XXX_REG_TEMP] = 0x06,
@@ -421,6 +423,9 @@ static u8
[BQ27XXX_REG_AP] = 0x24,
BQ27XXX_DM_REG_ROWS,
},
+#define bq27542_regs bq27541_regs
+#define bq27546_regs bq27541_regs
+#define bq27742_regs bq27541_regs
bq27545_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
[BQ27XXX_REG_TEMP] = 0x06,
@@ -461,6 +466,9 @@ static u8
[BQ27XXX_REG_AP] = 0x18,
BQ27XXX_DM_REG_ROWS,
};
+#define bq27425_regs bq27421_regs
+#define bq27441_regs bq27421_regs
+#define bq27621_regs bq27421_regs
static enum power_supply_property bq27000_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -539,6 +547,7 @@ static enum power_supply_property bq2751x_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+#define bq2752x_props bq2751x_props
static enum power_supply_property bq27500_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -716,6 +725,7 @@ static enum power_supply_property bq27530_props[] = {
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+#define bq27531_props bq27530_props
static enum power_supply_property bq27541_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -735,6 +745,9 @@ static enum power_supply_property bq27541_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+#define bq27542_props bq27541_props
+#define bq27546_props bq27541_props
+#define bq27742_props bq27541_props
static enum power_supply_property bq27545_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -768,33 +781,50 @@ static enum power_supply_property bq27421_props[] = {
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+#define bq27425_props bq27421_props
+#define bq27441_props bq27421_props
+#define bq27621_props bq27421_props
-#define BQ27XXX_DATA(ref) { \
+#define BQ27XXX_O_ZERO 0x00000001
+#define BQ27XXX_O_OTDC 0x00000002
+#define BQ27XXX_O_UTOT 0x00000004
+
+#define BQ27XXX_DATA(ref, opt) { \
+ .opts = (opt), \
.regs = ref##_regs, \
.props = ref##_props, \
.props_size = ARRAY_SIZE(ref##_props) }
static struct {
+ u32 opts;
u8 *regs;
enum power_supply_property *props;
size_t props_size;
} bq27xxx_chip_data[] = {
- [BQ27000] = BQ27XXX_DATA(bq27000),
- [BQ27010] = BQ27XXX_DATA(bq27010),
- [BQ2750X] = BQ27XXX_DATA(bq2750x),
- [BQ2751X] = BQ27XXX_DATA(bq2751x),
- [BQ27500] = BQ27XXX_DATA(bq27500),
- [BQ27510G1] = BQ27XXX_DATA(bq27510g1),
- [BQ27510G2] = BQ27XXX_DATA(bq27510g2),
- [BQ27510G3] = BQ27XXX_DATA(bq27510g3),
- [BQ27520G1] = BQ27XXX_DATA(bq27520g1),
- [BQ27520G2] = BQ27XXX_DATA(bq27520g2),
- [BQ27520G3] = BQ27XXX_DATA(bq27520g3),
- [BQ27520G4] = BQ27XXX_DATA(bq27520g4),
- [BQ27530] = BQ27XXX_DATA(bq27530),
- [BQ27541] = BQ27XXX_DATA(bq27541),
- [BQ27545] = BQ27XXX_DATA(bq27545),
- [BQ27421] = BQ27XXX_DATA(bq27421),
+ [BQ27000] = BQ27XXX_DATA(bq27000, BQ27XXX_O_ZERO),
+ [BQ27010] = BQ27XXX_DATA(bq27010, BQ27XXX_O_ZERO),
+ [BQ2750X] = BQ27XXX_DATA(bq2750x, BQ27XXX_O_OTDC),
+ [BQ2751X] = BQ27XXX_DATA(bq2751x, BQ27XXX_O_OTDC),
+ [BQ2752X] = BQ27XXX_DATA(bq2752x, BQ27XXX_O_OTDC),
+ [BQ27500] = BQ27XXX_DATA(bq27500, BQ27XXX_O_OTDC),
+ [BQ27510G1] = BQ27XXX_DATA(bq27510g1, BQ27XXX_O_OTDC),
+ [BQ27510G2] = BQ27XXX_DATA(bq27510g2, BQ27XXX_O_OTDC),
+ [BQ27510G3] = BQ27XXX_DATA(bq27510g3, BQ27XXX_O_OTDC),
+ [BQ27520G1] = BQ27XXX_DATA(bq27520g1, BQ27XXX_O_OTDC),
+ [BQ27520G2] = BQ27XXX_DATA(bq27520g2, BQ27XXX_O_OTDC),
+ [BQ27520G3] = BQ27XXX_DATA(bq27520g3, BQ27XXX_O_OTDC),
+ [BQ27520G4] = BQ27XXX_DATA(bq27520g4, BQ27XXX_O_OTDC),
+ [BQ27530] = BQ27XXX_DATA(bq27530, BQ27XXX_O_UTOT),
+ [BQ27531] = BQ27XXX_DATA(bq27531, BQ27XXX_O_UTOT),
+ [BQ27541] = BQ27XXX_DATA(bq27541, BQ27XXX_O_OTDC),
+ [BQ27542] = BQ27XXX_DATA(bq27542, BQ27XXX_O_OTDC),
+ [BQ27546] = BQ27XXX_DATA(bq27546, BQ27XXX_O_OTDC),
+ [BQ27742] = BQ27XXX_DATA(bq27742, BQ27XXX_O_OTDC),
+ [BQ27545] = BQ27XXX_DATA(bq27545, BQ27XXX_O_OTDC),
+ [BQ27421] = BQ27XXX_DATA(bq27421, BQ27XXX_O_UTOT),
+ [BQ27425] = BQ27XXX_DATA(bq27425, BQ27XXX_O_UTOT),
+ [BQ27441] = BQ27XXX_DATA(bq27441, BQ27XXX_O_UTOT),
+ [BQ27621] = BQ27XXX_DATA(bq27621, BQ27XXX_O_UTOT),
};
static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -1327,7 +1357,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
{
int soc;
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true);
else
soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
@@ -1353,7 +1383,7 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
return charge;
}
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
else
charge *= 1000;
@@ -1369,7 +1399,7 @@ static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
{
int flags;
- if (di->chip == BQ27000 || di->chip == BQ27010) {
+ if (di->opts & BQ27XXX_O_ZERO) {
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
if (flags >= 0 && (flags & BQ27000_FLAG_CI))
return -ENODATA;
@@ -1395,7 +1425,7 @@ static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
{
int dcap;
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, true);
else
dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
@@ -1405,7 +1435,7 @@ static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
return dcap;
}
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
else
dcap *= 1000;
@@ -1427,7 +1457,7 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
return ae;
}
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
else
ae *= 1000;
@@ -1449,7 +1479,7 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
return temp;
}
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
temp = 5 * temp / 2;
return temp;
@@ -1506,7 +1536,7 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
return tval;
}
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
else
return tval;
@@ -1517,26 +1547,12 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
*/
static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
{
- switch (di->chip) {
- case BQ2750X:
- case BQ2751X:
- case BQ27500:
- case BQ27510G1:
- case BQ27510G2:
- case BQ27510G3:
- case BQ27520G1:
- case BQ27520G2:
- case BQ27520G3:
- case BQ27520G4:
- case BQ27541:
- case BQ27545:
+ if (di->opts & BQ27XXX_O_OTDC)
return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
- case BQ27530:
- case BQ27421:
+ if (di->opts & BQ27XXX_O_UTOT)
return flags & BQ27XXX_FLAG_OT;
- default:
- return false;
- }
+
+ return false;
}
/*
@@ -1544,7 +1560,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
*/
static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
{
- if (di->chip == BQ27530 || di->chip == BQ27421)
+ if (di->opts & BQ27XXX_O_UTOT)
return flags & BQ27XXX_FLAG_UT;
return false;
@@ -1555,7 +1571,7 @@ static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
*/
static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
{
- if (di->chip == BQ27000 || di->chip == BQ27010)
+ if (di->opts & BQ27XXX_O_ZERO)
return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
else
return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
@@ -1568,7 +1584,7 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
{
int flags;
- bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
+ bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
if (flags < 0) {
@@ -1590,8 +1606,8 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
{
struct bq27xxx_reg_cache cache = {0, };
- bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
- bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
+ bool has_ci_flag = di->opts & BQ27XXX_O_ZERO;
+ bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
if ((cache.flags & 0xff) == 0xff)
@@ -1669,7 +1685,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
return curr;
}
- if (di->chip == BQ27000 || di->chip == BQ27010) {
+ if (di->opts & BQ27XXX_O_ZERO) {
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
if (flags & BQ27000_FLAG_CHGS) {
dev_dbg(di->dev, "negative current!\n");
@@ -1690,7 +1706,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
{
int status;
- if (di->chip == BQ27000 || di->chip == BQ27010) {
+ if (di->opts & BQ27XXX_O_ZERO) {
if (di->cache.flags & BQ27000_FLAG_FC)
status = POWER_SUPPLY_STATUS_FULL;
else if (di->cache.flags & BQ27000_FLAG_CHGS)
@@ -1718,7 +1734,7 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
{
int level;
- if (di->chip == BQ27000 || di->chip == BQ27010) {
+ if (di->opts & BQ27XXX_O_ZERO) {
if (di->cache.flags & BQ27000_FLAG_FC)
level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
else if (di->cache.flags & BQ27000_FLAG_EDV1)
@@ -1883,7 +1899,9 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
mutex_init(&di->lock);
+
di->regs = bq27xxx_chip_data[di->chip].regs;
+ di->opts = bq27xxx_chip_data[di->chip].opts;
psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
if (!psy_desc)
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index a5972214f074..0b11ed472f33 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -230,7 +230,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27210", BQ27010 },
{ "bq27500", BQ2750X },
{ "bq27510", BQ2751X },
- { "bq27520", BQ2751X },
+ { "bq27520", BQ2752X },
{ "bq27500-1", BQ27500 },
{ "bq27510g1", BQ27510G1 },
{ "bq27510g2", BQ27510G2 },
@@ -240,16 +240,16 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27520g3", BQ27520G3 },
{ "bq27520g4", BQ27520G4 },
{ "bq27530", BQ27530 },
- { "bq27531", BQ27530 },
+ { "bq27531", BQ27531 },
{ "bq27541", BQ27541 },
- { "bq27542", BQ27541 },
- { "bq27546", BQ27541 },
- { "bq27742", BQ27541 },
+ { "bq27542", BQ27542 },
+ { "bq27546", BQ27546 },
+ { "bq27742", BQ27742 },
{ "bq27545", BQ27545 },
{ "bq27421", BQ27421 },
- { "bq27425", BQ27421 },
- { "bq27441", BQ27421 },
- { "bq27621", BQ27421 },
+ { "bq27425", BQ27425 },
+ { "bq27441", BQ27441 },
+ { "bq27621", BQ27621 },
{},
};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index 89890437f9ab..e48e7a4e9cd6 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -6,6 +6,7 @@ enum bq27xxx_chip {
BQ27010, /* bq27010, bq27210 */
BQ2750X, /* bq27500 deprecated alias */
BQ2751X, /* bq27510, bq27520 deprecated alias */
+ BQ2752X,
BQ27500, /* bq27500/1 */
BQ27510G1, /* bq27510G1 */
BQ27510G2, /* bq27510G2 */
@@ -15,9 +16,16 @@ enum bq27xxx_chip {
BQ27520G3, /* bq27520G3 */
BQ27520G4, /* bq27520G4 */
BQ27530, /* bq27530, bq27531 */
+ BQ27531,
BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
+ BQ27542,
+ BQ27546,
+ BQ27742,
BQ27545, /* bq27545 */
BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+ BQ27425,
+ BQ27441,
+ BQ27621,
};
struct bq27xxx_device_info;
@@ -47,6 +55,7 @@ struct bq27xxx_device_info {
int id;
enum bq27xxx_chip chip;
bool ram_chip;
+ u32 opts;
const char *name;
struct bq27xxx_dm_reg *dm_regs;
u32 unseal_key;