summaryrefslogtreecommitdiff
path: root/drivers/power/supply/bq27xxx_battery.c
diff options
context:
space:
mode:
authorLiam Breck <kernel@networkimprov.net>2017-08-24 06:36:14 +0300
committerSebastian Reichel <sebastian.reichel@collabora.co.uk>2017-08-29 13:37:35 +0300
commit3a731c6414c94012328f485b4b1bb88ed841f9eb (patch)
treee9302f5f182db2b5ef52ececba44c48370d80894 /drivers/power/supply/bq27xxx_battery.c
parent9aade6d8f9d0fd086068fc390c6f6c0ce98ea07a (diff)
downloadlinux-3a731c6414c94012328f485b4b1bb88ed841f9eb.tar.xz
power: supply: bq27xxx: Add chip IDs for previously shadowed chips
For the existing features, these chips act like others already ID'd, so they had false but functional IDs. We will be adding features which require correct IDs, so the following IDs are added: BQ2752X, 531, 542, 546, 742, 425, 441, 621 Chip-specific features are now tracked by BQ27XXX_O_* flags in di->opts. No functional changes to the driver. Signed-off-by: Liam Breck <kernel@networkimprov.net> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Diffstat (limited to 'drivers/power/supply/bq27xxx_battery.c')
-rw-r--r--drivers/power/supply/bq27xxx_battery.c120
1 files changed, 69 insertions, 51 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)