summary refs log tree commit diff
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;