All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/7] Add support for additional bq27xxx devices
@ 2015-09-14 21:26 ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

This series adds support for several additional bq27xxx devices and
makes a few related fixes. v1 can be found here: [1] v2: [2] v3: [3]

Changes from v3:
 - Added interrupt handling patch to series
 - Rebased on v4.3-rc1

Changes from v2:
 - Fix alignment issue
 - Fix commit message typo
 - Use INVALID_REG_ADDR in register mappings

Changes from v1:
 - Drop first four patches from series as they have been queued
   at git://git.infradead.org/battery-2.6.git
 - Remove MODULE_ALIAS
 - Add comment about State-of-Charge
 - Add additional links to documentation
 - Add device names to id table
 - Add unlikely to if statement
 - Change return types to bool for status check functions

[1] http://www.spinics.net/lists/kernel/msg2039278.html
[2] http://www.spinics.net/lists/kernel/msg2043759.html
[3] http://www.spinics.net/lists/kernel/msg2050196.html

Andrew F. Davis (7):
  power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
  power: bq27x00_battery: Renaming for consistency
  power: bq27xxx_battery: Platform initialization must declare a device
  power: bq27xxx_battery: Fix typos and change naming for state of
    charge functions
  power: bq27xxx_battery: Add support for additional bq27xxx family
    devices
  power: bq27xxx_battery: Cleanup health checking
  power: bq27xxx_battery: Add interrupt handling support

 MAINTAINERS                           |    4 +-
 arch/arm/configs/omap2plus_defconfig  |    2 +-
 arch/unicore32/Kconfig                |    2 +-
 drivers/power/Kconfig                 |   22 +-
 drivers/power/Makefile                |    2 +-
 drivers/power/bq27x00_battery.c       | 1129 ---------------------------
 drivers/power/bq27xxx_battery.c       | 1383 +++++++++++++++++++++++++++++++++
 drivers/w1/slaves/w1_bq27000.c        |    5 +-
 include/linux/power/bq27x00_battery.h |   19 -
 include/linux/power/bq27xxx_battery.h |   31 +
 10 files changed, 1433 insertions(+), 1166 deletions(-)
 delete mode 100644 drivers/power/bq27x00_battery.c
 create mode 100644 drivers/power/bq27xxx_battery.c
 delete mode 100644 include/linux/power/bq27x00_battery.h
 create mode 100644 include/linux/power/bq27xxx_battery.h

-- 
1.9.1


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v4 0/7] Add support for additional bq27xxx devices
@ 2015-09-14 21:26 ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

This series adds support for several additional bq27xxx devices and
makes a few related fixes. v1 can be found here: [1] v2: [2] v3: [3]

Changes from v3:
 - Added interrupt handling patch to series
 - Rebased on v4.3-rc1

Changes from v2:
 - Fix alignment issue
 - Fix commit message typo
 - Use INVALID_REG_ADDR in register mappings

Changes from v1:
 - Drop first four patches from series as they have been queued
   at git://git.infradead.org/battery-2.6.git
 - Remove MODULE_ALIAS
 - Add comment about State-of-Charge
 - Add additional links to documentation
 - Add device names to id table
 - Add unlikely to if statement
 - Change return types to bool for status check functions

[1] http://www.spinics.net/lists/kernel/msg2039278.html
[2] http://www.spinics.net/lists/kernel/msg2043759.html
[3] http://www.spinics.net/lists/kernel/msg2050196.html

Andrew F. Davis (7):
  power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
  power: bq27x00_battery: Renaming for consistency
  power: bq27xxx_battery: Platform initialization must declare a device
  power: bq27xxx_battery: Fix typos and change naming for state of
    charge functions
  power: bq27xxx_battery: Add support for additional bq27xxx family
    devices
  power: bq27xxx_battery: Cleanup health checking
  power: bq27xxx_battery: Add interrupt handling support

 MAINTAINERS                           |    4 +-
 arch/arm/configs/omap2plus_defconfig  |    2 +-
 arch/unicore32/Kconfig                |    2 +-
 drivers/power/Kconfig                 |   22 +-
 drivers/power/Makefile                |    2 +-
 drivers/power/bq27x00_battery.c       | 1129 ---------------------------
 drivers/power/bq27xxx_battery.c       | 1383 +++++++++++++++++++++++++++++++++
 drivers/w1/slaves/w1_bq27000.c        |    5 +-
 include/linux/power/bq27x00_battery.h |   19 -
 include/linux/power/bq27xxx_battery.h |   31 +
 10 files changed, 1433 insertions(+), 1166 deletions(-)
 delete mode 100644 drivers/power/bq27x00_battery.c
 create mode 100644 drivers/power/bq27xxx_battery.c
 delete mode 100644 include/linux/power/bq27x00_battery.h
 create mode 100644 include/linux/power/bq27xxx_battery.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v4 1/7] power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

The MODULE_DEVICE_TABLE macro automatically adds all needed
i2c MODULE_ALIASes so remove the extra MODULE_ALIAS.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27x00_battery.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 8287261f..d0b2f3b 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -1120,10 +1120,6 @@ module_exit(bq27x00_battery_exit);
 MODULE_ALIAS("platform:bq27000-battery");
 #endif
 
-#ifdef CONFIG_BATTERY_BQ27X00_I2C
-MODULE_ALIAS("i2c:bq27000-battery");
-#endif
-
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
 MODULE_LICENSE("GPL");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 1/7] power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

The MODULE_DEVICE_TABLE macro automatically adds all needed
i2c MODULE_ALIASes so remove the extra MODULE_ALIAS.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27x00_battery.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 8287261f..d0b2f3b 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -1120,10 +1120,6 @@ module_exit(bq27x00_battery_exit);
 MODULE_ALIAS("platform:bq27000-battery");
 #endif
 
-#ifdef CONFIG_BATTERY_BQ27X00_I2C
-MODULE_ALIAS("i2c:bq27000-battery");
-#endif
-
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
 MODULE_LICENSE("GPL");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Rename functions that are used by multiple devices. New devices
have been added and the function names and driver name are no longer
general enough for the functionality they provide.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 MAINTAINERS                                        |   4 +-
 arch/arm/configs/omap2plus_defconfig               |   2 +-
 arch/unicore32/Kconfig                             |   2 +-
 drivers/power/Kconfig                              |  22 +-
 drivers/power/Makefile                             |   2 +-
 .../power/{bq27x00_battery.c => bq27xxx_battery.c} | 333 +++++++++++----------
 drivers/w1/slaves/w1_bq27000.c                     |   4 +-
 .../power/{bq27x00_battery.h => bq27xxx_battery.h} |   4 +-
 8 files changed, 187 insertions(+), 186 deletions(-)
 rename drivers/power/{bq27x00_battery.c => bq27xxx_battery.c} (70%)
 rename include/linux/power/{bq27x00_battery.h => bq27xxx_battery.h} (85%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7ba7ab7..afa5910 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7393,10 +7393,10 @@ NOKIA N900 POWER SUPPLY DRIVERS
 M:	Pali Rohár <pali.rohar@gmail.com>
 S:	Maintained
 F:	include/linux/power/bq2415x_charger.h
-F:	include/linux/power/bq27x00_battery.h
+F:	include/linux/power/bq27xxx_battery.h
 F:	include/linux/power/isp1704_charger.h
 F:	drivers/power/bq2415x_charger.c
-F:	drivers/power/bq27x00_battery.c
+F:	drivers/power/bq27xxx_battery.c
 F:	drivers/power/isp1704_charger.c
 F:	drivers/power/rx51_battery.c
 
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 50c84e1..6a9ec3e 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -245,7 +245,7 @@ CONFIG_GPIO_TWL4030=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_W1=m
 CONFIG_HDQ_MASTER_OMAP=m
-CONFIG_BATTERY_BQ27x00=m
+CONFIG_BATTERY_BQ27XXX=m
 CONFIG_CHARGER_ISP1704=m
 CONFIG_CHARGER_TWL4030=m
 CONFIG_CHARGER_BQ2415X=m
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 928237a..c9faddc 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -222,7 +222,7 @@ config I2C_BATTERY_BQ27200
 	tristate "I2C Battery BQ27200 Support"
 	select I2C_PUV3
 	select POWER_SUPPLY
-	select BATTERY_BQ27x00
+	select BATTERY_BQ27XXX
 
 config I2C_EEPROM_AT24
 	tristate "I2C EEPROMs AT24 support"
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index f8758d6..53c7469 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -157,26 +157,26 @@ config BATTERY_SBS
 	  Say Y to include support for SBS battery driver for SBS-compliant
 	  gas gauges.
 
-config BATTERY_BQ27x00
-	tristate "BQ27x00 battery driver"
+config BATTERY_BQ27XXX
+	tristate "BQ27xxx battery driver"
 	depends on I2C || I2C=n
 	help
-	  Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (I2C/HDQ) chips.
 
-config BATTERY_BQ27X00_I2C
-	bool "BQ27200/BQ27500 support"
-	depends on BATTERY_BQ27x00
+config BATTERY_BQ27XXX_I2C
+	bool "BQ27xxx I2C support"
+	depends on BATTERY_BQ27XXX
 	depends on I2C
 	default y
 	help
-	  Say Y here to enable support for batteries with BQ27x00 (I2C) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (I2C) chips.
 
-config BATTERY_BQ27X00_PLATFORM
-	bool "BQ27000 support"
-	depends on BATTERY_BQ27x00
+config BATTERY_BQ27XXX_PLATFORM
+	bool "BQ27xxx HDQ support"
+	depends on BATTERY_BQ27XXX
 	default y
 	help
-	  Say Y here to enable support for batteries with BQ27000 (HDQ) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (HDQ) chips.
 
 config BATTERY_DA9030
 	tristate "DA9030 battery driver"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 5752ce8..7a5bc96 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_BATTERY_COLLIE)	+= collie_battery.o
 obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
 obj-$(CONFIG_BATTERY_WM97XX)	+= wm97xx_battery.o
 obj-$(CONFIG_BATTERY_SBS)	+= sbs-battery.o
-obj-$(CONFIG_BATTERY_BQ27x00)	+= bq27x00_battery.o
+obj-$(CONFIG_BATTERY_BQ27XXX)	+= bq27xxx_battery.o
 obj-$(CONFIG_BATTERY_DA9030)	+= da9030_battery.o
 obj-$(CONFIG_BATTERY_DA9052)	+= da9052-battery.o
 obj-$(CONFIG_CHARGER_DA9150)	+= da9150-charger.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27xxx_battery.c
similarity index 70%
rename from drivers/power/bq27x00_battery.c
rename to drivers/power/bq27xxx_battery.c
index d0b2f3b..e72055c 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -1,5 +1,5 @@
 /*
- * BQ27x00 battery driver
+ * BQ27xxx battery driver
  *
  * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
@@ -37,7 +37,7 @@
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 
-#include <linux/power/bq27x00_battery.h>
+#include <linux/power/bq27xxx_battery.h>
 
 #define DRIVER_VERSION		"1.2.0"
 
@@ -83,17 +83,17 @@
 #define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
 #define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
 
-#define BQ27000_RS			20 /* Resistor sense */
-#define BQ27x00_POWER_CONSTANT		(256 * 29200 / 1000)
+#define BQ27XXX_RS			20 /* Resistor sense */
+#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
 
-struct bq27x00_device_info;
-struct bq27x00_access_methods {
-	int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);
+struct bq27xxx_device_info;
+struct bq27xxx_access_methods {
+	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
-enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
+enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
 
-struct bq27x00_reg_cache {
+struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
 	int time_to_empty_avg;
@@ -107,12 +107,12 @@ struct bq27x00_reg_cache {
 	int health;
 };
 
-struct bq27x00_device_info {
+struct bq27xxx_device_info {
 	struct device		*dev;
 	int			id;
-	enum bq27x00_chip	chip;
+	enum bq27xxx_chip	chip;
 
-	struct bq27x00_reg_cache cache;
+	struct bq27xxx_reg_cache cache;
 	int charge_design_full;
 
 	unsigned long last_update;
@@ -120,7 +120,7 @@ struct bq27x00_device_info {
 
 	struct power_supply	*bat;
 
-	struct bq27x00_access_methods bus;
+	struct bq27xxx_access_methods bus;
 
 	struct mutex lock;
 };
@@ -206,10 +206,10 @@ MODULE_PARM_DESC(poll_interval,
 		 "battery poll interval in seconds - 0 disables polling");
 
 /*
- * Common code for BQ27x00 devices
+ * Common code for BQ27xxx devices
  */
 
-static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
+static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
 			       bool single)
 {
 	if (di->chip == BQ27425)
@@ -222,7 +222,7 @@ static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
  * differ from BQ27000 and BQ27200 in calculation of certain
  * parameters. Hence we need to check for the chip type.
  */
-static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
+static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
 {
 	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
 	    || di->chip == BQ27510)
@@ -234,18 +234,18 @@ static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
  * Return the battery Relative State-of-Charge
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_rsoc(struct bq27xxx_device_info *di)
 {
 	int rsoc;
 
 	if (di->chip == BQ27500 || di->chip == BQ27742)
-		rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27500_REG_SOC, false);
 	else if (di->chip == BQ27510)
-		rsoc = bq27x00_read(di, BQ27510_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27510_REG_SOC, false);
 	else if (di->chip == BQ27425)
-		rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27425_REG_SOC, false);
 	else
-		rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
+		rsoc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
 
 	if (rsoc < 0)
 		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
@@ -257,11 +257,11 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
  * Return a battery charge value in µAh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 {
 	int charge;
 
-	charge = bq27x00_read(di, reg, false);
+	charge = bq27xxx_read(di, reg, false);
 	if (charge < 0) {
 		dev_dbg(di->dev, "error reading charge register %02x: %d\n",
 			reg, charge);
@@ -271,7 +271,7 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
 	if (bq27xxx_is_chip_version_higher(di))
 		charge *= 1000;
 	else
-		charge = charge * 3570 / BQ27000_RS;
+		charge = charge * 3570 / BQ27XXX_RS;
 
 	return charge;
 }
@@ -280,7 +280,7 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
  * Return the battery Nominal available capaciy in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)
+static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
 {
 	int flags;
 	bool is_bq27500 = di->chip == BQ27500;
@@ -288,39 +288,39 @@ static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)
 	bool is_higher = bq27xxx_is_chip_version_higher(di);
 	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	flags = bq27x00_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
 	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
 		return -ENODATA;
 
-	return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC);
+	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
 }
 
 /*
  * Return the battery Last measured discharge in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27x00_battery_read_lmd(struct bq27x00_device_info *di)
+static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
 {
-	return bq27x00_battery_read_charge(di, BQ27x00_REG_LMD);
+	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
 }
 
 /*
  * Return the battery Initial last measured discharge in µAh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
 {
 	int ilmd;
 
 	if (bq27xxx_is_chip_version_higher(di)) {
 		if (di->chip == BQ27425)
-			ilmd = bq27x00_read(di, BQ27425_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
 		else if (di->chip == BQ27510)
-			ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
 		else
-			ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
 	} else {
-		ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
+		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
 	}
 
 	if (ilmd < 0) {
@@ -331,7 +331,7 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
 	if (bq27xxx_is_chip_version_higher(di))
 		ilmd *= 1000;
 	else
-		ilmd = ilmd * 256 * 3570 / BQ27000_RS;
+		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
 
 	return ilmd;
 }
@@ -340,11 +340,11 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
  * Return the battery Available energy in µWh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
 {
 	int ae;
 
-	ae = bq27x00_read(di, BQ27x00_REG_AE, false);
+	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
 	if (ae < 0) {
 		dev_dbg(di->dev, "error reading available energy\n");
 		return ae;
@@ -353,7 +353,7 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
 	if (di->chip == BQ27500)
 		ae *= 1000;
 	else
-		ae = ae * 29200 / BQ27000_RS;
+		ae = ae * 29200 / BQ27XXX_RS;
 
 	return ae;
 }
@@ -362,11 +362,11 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
  * Return the battery temperature in tenths of degree Kelvin
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
 {
 	int temp;
 
-	temp = bq27x00_read(di, BQ27x00_REG_TEMP, false);
+	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
 	if (temp < 0) {
 		dev_err(di->dev, "error reading temperature\n");
 		return temp;
@@ -382,14 +382,14 @@ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
  * Return the battery Cycle count total
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
 {
 	int cyct;
 
 	if (di->chip == BQ27510)
-		cyct = bq27x00_read(di, BQ27510_REG_CYCT, false);
+		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
 	else
-		cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false);
+		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
 	if (cyct < 0)
 		dev_err(di->dev, "error reading cycle count total\n");
 
@@ -400,11 +400,11 @@ static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di)
  * Read a time register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
 {
 	int tval;
 
-	tval = bq27x00_read(di, reg, false);
+	tval = bq27xxx_read(di, reg, false);
 	if (tval < 0) {
 		dev_dbg(di->dev, "error reading time register %02x: %d\n",
 			reg, tval);
@@ -421,11 +421,11 @@ static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)
  * Read a power avg register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
 {
 	int tval;
 
-	tval = bq27x00_read(di, reg, false);
+	tval = bq27xxx_read(di, reg, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
 			reg, tval);
@@ -435,18 +435,18 @@ static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
 	if (di->chip == BQ27500)
 		return tval;
 	else
-		return (tval * BQ27x00_POWER_CONSTANT) / BQ27000_RS;
+		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
 }
 
 /*
  * Read flag register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
 	int tval;
 
-	tval = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
+	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading flag register:%d\n", tval);
 		return tval;
@@ -475,16 +475,16 @@ static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
 	return -1;
 }
 
-static void bq27x00_update(struct bq27x00_device_info *di)
+static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 {
-	struct bq27x00_reg_cache cache = {0, };
+	struct bq27xxx_reg_cache cache = {0, };
 	bool is_bq27500 = di->chip == BQ27500;
 	bool is_bq27510 = di->chip == BQ27510;
 	bool is_bq27425 = di->chip == BQ27425;
 	bool is_bq27742 = di->chip == BQ27742;
 	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
 	if ((cache.flags & 0xff) == 0xff)
 		/* read error */
 		cache.flags = -1;
@@ -500,41 +500,41 @@ static void bq27x00_update(struct bq27x00_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
-			cache.capacity = bq27x00_battery_read_rsoc(di);
+			cache.capacity = bq27xxx_battery_read_rsoc(di);
 			if (is_bq27742 || is_bq27510)
 				cache.time_to_empty =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTE);
 			else if (!is_bq27425) {
-				cache.energy = bq27x00_battery_read_energy(di);
+				cache.energy = bq27xxx_battery_read_energy(di);
 				cache.time_to_empty =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTE);
 				cache.time_to_empty_avg =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTECP);
 				cache.time_to_full =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTF);
 			}
-			cache.charge_full = bq27x00_battery_read_lmd(di);
-			cache.health = bq27x00_battery_read_health(di);
+			cache.charge_full = bq27xxx_battery_read_lmd(di);
+			cache.health = bq27xxx_battery_read_health(di);
 		}
-		cache.temperature = bq27x00_battery_read_temperature(di);
+		cache.temperature = bq27xxx_battery_read_temperature(di);
 		if (!is_bq27425)
-			cache.cycle_count = bq27x00_battery_read_cyct(di);
+			cache.cycle_count = bq27xxx_battery_read_cyct(di);
 		if (is_bq27742)
 			cache.power_avg =
-				bq27x00_battery_read_pwr_avg(di,
+				bq27xxx_battery_read_pwr_avg(di,
 						BQ27742_POWER_AVG);
 		else
 			cache.power_avg =
-				bq27x00_battery_read_pwr_avg(di,
+				bq27xxx_battery_read_pwr_avg(di,
 						BQ27x00_POWER_AVG);
 
 		/* We only have to read charge design full once */
 		if (di->charge_design_full <= 0)
-			di->charge_design_full = bq27x00_battery_read_ilmd(di);
+			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
 	}
 
 	if (di->cache.capacity != cache.capacity)
@@ -546,12 +546,12 @@ static void bq27x00_update(struct bq27x00_device_info *di)
 	di->last_update = jiffies;
 }
 
-static void bq27x00_battery_poll(struct work_struct *work)
+static void bq27xxx_battery_poll(struct work_struct *work)
 {
-	struct bq27x00_device_info *di =
-		container_of(work, struct bq27x00_device_info, work.work);
+	struct bq27xxx_device_info *di =
+		container_of(work, struct bq27xxx_device_info, work.work);
 
-	bq27x00_update(di);
+	bq27xxx_battery_update(di);
 
 	if (poll_interval > 0) {
 		/* The timer does not have to be accurate. */
@@ -565,13 +565,13 @@ static void bq27x00_battery_poll(struct work_struct *work)
  * Note that current can be negative signed as well
  * Or 0 if something fails.
  */
-static int bq27x00_battery_current(struct bq27x00_device_info *di,
+static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
 				   union power_supply_propval *val)
 {
 	int curr;
 	int flags;
 
-	curr = bq27x00_read(di, BQ27x00_REG_AI, false);
+	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
 	if (curr < 0) {
 		dev_err(di->dev, "error reading current\n");
 		return curr;
@@ -581,19 +581,19 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di,
 		/* bq27500 returns signed value */
 		val->intval = (int)((s16)curr) * 1000;
 	} else {
-		flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
+		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
 		if (flags & BQ27000_FLAG_CHGS) {
 			dev_dbg(di->dev, "negative current!\n");
 			curr = -curr;
 		}
 
-		val->intval = curr * 3570 / BQ27000_RS;
+		val->intval = curr * 3570 / BQ27XXX_RS;
 	}
 
 	return 0;
 }
 
-static int bq27x00_battery_status(struct bq27x00_device_info *di,
+static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 				  union power_supply_propval *val)
 {
 	int status;
@@ -621,7 +621,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
 	return 0;
 }
 
-static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
+static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
 					  union power_supply_propval *val)
 {
 	int level;
@@ -655,12 +655,12 @@ static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
  * Return the battery Voltage in millivolts
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
+static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
 				   union power_supply_propval *val)
 {
 	int volt;
 
-	volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
+	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
 	if (volt < 0) {
 		dev_err(di->dev, "error reading voltage\n");
 		return volt;
@@ -671,7 +671,7 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
 	return 0;
 }
 
-static int bq27x00_simple_value(int value,
+static int bq27xxx_simple_value(int value,
 				union power_supply_propval *val)
 {
 	if (value < 0)
@@ -682,17 +682,17 @@ static int bq27x00_simple_value(int value,
 	return 0;
 }
 
-static int bq27x00_battery_get_property(struct power_supply *psy,
+static int bq27xxx_battery_get_property(struct power_supply *psy,
 					enum power_supply_property psp,
 					union power_supply_propval *val)
 {
 	int ret = 0;
-	struct bq27x00_device_info *di = power_supply_get_drvdata(psy);
+	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
 	mutex_lock(&di->lock);
 	if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
 		cancel_delayed_work_sync(&di->work);
-		bq27x00_battery_poll(&di->work.work);
+		bq27xxx_battery_poll(&di->work.work);
 	}
 	mutex_unlock(&di->lock);
 
@@ -701,60 +701,60 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		ret = bq27x00_battery_status(di, val);
+		ret = bq27xxx_battery_status(di, val);
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		ret = bq27x00_battery_voltage(di, val);
+		ret = bq27xxx_battery_voltage(di, val);
 		break;
 	case POWER_SUPPLY_PROP_PRESENT:
 		val->intval = di->cache.flags < 0 ? 0 : 1;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		ret = bq27x00_battery_current(di, val);
+		ret = bq27xxx_battery_current(di, val);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
-		ret = bq27x00_simple_value(di->cache.capacity, val);
+		ret = bq27xxx_simple_value(di->cache.capacity, val);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
-		ret = bq27x00_battery_capacity_level(di, val);
+		ret = bq27xxx_battery_capacity_level(di, val);
 		break;
 	case POWER_SUPPLY_PROP_TEMP:
-		ret = bq27x00_simple_value(di->cache.temperature, val);
+		ret = bq27xxx_simple_value(di->cache.temperature, val);
 		if (ret == 0)
 			val->intval -= 2731;
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
-		ret = bq27x00_simple_value(di->cache.time_to_empty, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
-		ret = bq27x00_simple_value(di->cache.time_to_empty_avg, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_empty_avg, val);
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
-		ret = bq27x00_simple_value(di->cache.time_to_full, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_full, val);
 		break;
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_NOW:
-		ret = bq27x00_simple_value(bq27x00_battery_read_nac(di), val);
+		ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL:
-		ret = bq27x00_simple_value(di->cache.charge_full, val);
+		ret = bq27xxx_simple_value(di->cache.charge_full, val);
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
-		ret = bq27x00_simple_value(di->charge_design_full, val);
+		ret = bq27xxx_simple_value(di->charge_design_full, val);
 		break;
 	case POWER_SUPPLY_PROP_CYCLE_COUNT:
-		ret = bq27x00_simple_value(di->cache.cycle_count, val);
+		ret = bq27xxx_simple_value(di->cache.cycle_count, val);
 		break;
 	case POWER_SUPPLY_PROP_ENERGY_NOW:
-		ret = bq27x00_simple_value(di->cache.energy, val);
+		ret = bq27xxx_simple_value(di->cache.energy, val);
 		break;
 	case POWER_SUPPLY_PROP_POWER_AVG:
-		ret = bq27x00_simple_value(di->cache.power_avg, val);
+		ret = bq27xxx_simple_value(di->cache.power_avg, val);
 		break;
 	case POWER_SUPPLY_PROP_HEALTH:
-		ret = bq27x00_simple_value(di->cache.health, val);
+		ret = bq27xxx_simple_value(di->cache.health, val);
 		break;
 	case POWER_SUPPLY_PROP_MANUFACTURER:
 		val->strval = BQ27XXX_MANUFACTURER;
@@ -766,15 +766,15 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
 	return ret;
 }
 
-static void bq27x00_external_power_changed(struct power_supply *psy)
+static void bq27xxx_external_power_changed(struct power_supply *psy)
 {
-	struct bq27x00_device_info *di = power_supply_get_drvdata(psy);
+	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
 	cancel_delayed_work_sync(&di->work);
 	schedule_delayed_work(&di->work, 0);
 }
 
-static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
+static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
 				    const char *name)
 {
 	int ret;
@@ -800,10 +800,10 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
 		psy_desc->properties = bq27x00_battery_props;
 		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
 	}
-	psy_desc->get_property = bq27x00_battery_get_property;
-	psy_desc->external_power_changed = bq27x00_external_power_changed;
+	psy_desc->get_property = bq27xxx_battery_get_property;
+	psy_desc->external_power_changed = bq27xxx_external_power_changed;
 
-	INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll);
+	INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
 	mutex_init(&di->lock);
 
 	di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
@@ -815,17 +815,17 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
 
 	dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
 
-	bq27x00_update(di);
+	bq27xxx_battery_update(di);
 
 	return 0;
 }
 
-static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
+static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di)
 {
 	/*
-	 * power_supply_unregister call bq27x00_battery_get_property which
-	 * call bq27x00_battery_poll.
-	 * Make sure that bq27x00_battery_poll will not call
+	 * power_supply_unregister call bq27xxx_battery_get_property which
+	 * call bq27xxx_battery_poll.
+	 * Make sure that bq27xxx_battery_poll will not call
 	 * schedule_delayed_work again after unregister (which cause OOPS).
 	 */
 	poll_interval = 0;
@@ -838,7 +838,7 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
 }
 
 /* i2c specific code */
-#ifdef CONFIG_BATTERY_BQ27X00_I2C
+#ifdef CONFIG_BATTERY_BQ27XXX_I2C
 
 /* If the system has several batteries we need a different name for each
  * of them...
@@ -846,7 +846,8 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
 static DEFINE_IDR(battery_id);
 static DEFINE_MUTEX(battery_mutex);
 
-static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single)
+static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
+				    bool single)
 {
 	struct i2c_client *client = to_i2c_client(di->dev);
 	struct i2c_msg msg[2];
@@ -880,11 +881,11 @@ static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single)
 	return ret;
 }
 
-static int bq27x00_battery_probe(struct i2c_client *client,
-				 const struct i2c_device_id *id)
+static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
 {
 	char *name;
-	struct bq27x00_device_info *di;
+	struct bq27xxx_device_info *di;
 	int num;
 	int retval = 0;
 
@@ -910,9 +911,9 @@ static int bq27x00_battery_probe(struct i2c_client *client,
 	di->id = num;
 	di->dev = &client->dev;
 	di->chip = id->driver_data;
-	di->bus.read = &bq27x00_read_i2c;
+	di->bus.read = &bq27xxx_battery_i2c_read;
 
-	retval = bq27x00_powersupply_init(di, name);
+	retval = bq27xxx_powersupply_init(di, name);
 	if (retval)
 		goto batt_failed;
 
@@ -928,11 +929,11 @@ batt_failed:
 	return retval;
 }
 
-static int bq27x00_battery_remove(struct i2c_client *client)
+static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
 {
-	struct bq27x00_device_info *di = i2c_get_clientdata(client);
+	struct bq27xxx_device_info *di = i2c_get_clientdata(client);
 
-	bq27x00_powersupply_unregister(di);
+	bq27xxx_powersupply_unregister(di);
 
 	mutex_lock(&battery_mutex);
 	idr_remove(&battery_id, di->id);
@@ -941,7 +942,7 @@ static int bq27x00_battery_remove(struct i2c_client *client)
 	return 0;
 }
 
-static const struct i2c_device_id bq27x00_id[] = {
+static const struct i2c_device_id bq27xxx_id[] = {
 	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
 	{ "bq27500", BQ27500 },
 	{ "bq27425", BQ27425 },
@@ -949,47 +950,47 @@ static const struct i2c_device_id bq27x00_id[] = {
 	{ "bq27510", BQ27510 },
 	{},
 };
-MODULE_DEVICE_TABLE(i2c, bq27x00_id);
+MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
 
-static struct i2c_driver bq27x00_battery_driver = {
+static struct i2c_driver bq27xxx_battery_i2c_driver = {
 	.driver = {
-		.name = "bq27x00-battery",
+		.name = "bq27xxx-battery",
 	},
-	.probe = bq27x00_battery_probe,
-	.remove = bq27x00_battery_remove,
-	.id_table = bq27x00_id,
+	.probe = bq27xxx_battery_i2c_probe,
+	.remove = bq27xxx_battery_i2c_remove,
+	.id_table = bq27xxx_id,
 };
 
-static inline int bq27x00_battery_i2c_init(void)
+static inline int bq27xxx_battery_i2c_init(void)
 {
-	int ret = i2c_add_driver(&bq27x00_battery_driver);
+	int ret = i2c_add_driver(&bq27xxx_battery_i2c_driver);
 
 	if (ret)
-		pr_err("Unable to register BQ27x00 i2c driver\n");
+		pr_err("Unable to register BQ27xxx i2c driver\n");
 
 	return ret;
 }
 
-static inline void bq27x00_battery_i2c_exit(void)
+static inline void bq27xxx_battery_i2c_exit(void)
 {
-	i2c_del_driver(&bq27x00_battery_driver);
+	i2c_del_driver(&bq27xxx_battery_i2c_driver);
 }
 
 #else
 
-static inline int bq27x00_battery_i2c_init(void) { return 0; }
-static inline void bq27x00_battery_i2c_exit(void) {};
+static inline int bq27xxx_battery_i2c_init(void) { return 0; }
+static inline void bq27xxx_battery_i2c_exit(void) {};
 
 #endif
 
 /* platform specific code */
-#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
 
-static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
-				 bool single)
+static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg,
+					 bool single)
 {
 	struct device *dev = di->dev;
-	struct bq27000_platform_data *pdata = dev->platform_data;
+	struct bq27xxx_platform_data *pdata = dev->platform_data;
 	unsigned int timeout = 3;
 	int upper, lower;
 	int temp;
@@ -1019,10 +1020,10 @@ static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
 	return pdata->read(dev, reg);
 }
 
-static int bq27000_battery_probe(struct platform_device *pdev)
+static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 {
-	struct bq27x00_device_info *di;
-	struct bq27000_platform_data *pdata = pdev->dev.platform_data;
+	struct bq27xxx_device_info *di;
+	struct bq27xxx_platform_data *pdata = pdev->dev.platform_data;
 	const char *name;
 
 	if (!pdata) {
@@ -1045,47 +1046,47 @@ static int bq27000_battery_probe(struct platform_device *pdev)
 	di->chip = BQ27000;
 
 	name = pdata->name ?: dev_name(&pdev->dev);
-	di->bus.read = &bq27000_read_platform;
+	di->bus.read = &bq27xxx_battery_platform_read;
 
-	return bq27x00_powersupply_init(di, name);
+	return bq27xxx_powersupply_init(di, name);
 }
 
-static int bq27000_battery_remove(struct platform_device *pdev)
+static int bq27xxx_battery_platform_remove(struct platform_device *pdev)
 {
-	struct bq27x00_device_info *di = platform_get_drvdata(pdev);
+	struct bq27xxx_device_info *di = platform_get_drvdata(pdev);
 
-	bq27x00_powersupply_unregister(di);
+	bq27xxx_powersupply_unregister(di);
 
 	return 0;
 }
 
-static struct platform_driver bq27000_battery_driver = {
-	.probe	= bq27000_battery_probe,
-	.remove = bq27000_battery_remove,
+static struct platform_driver bq27xxx_battery_platform_driver = {
+	.probe	= bq27xxx_battery_platform_probe,
+	.remove = bq27xxx_battery_platform_remove,
 	.driver = {
 		.name = "bq27000-battery",
 	},
 };
 
-static inline int bq27x00_battery_platform_init(void)
+static inline int bq27xxx_battery_platform_init(void)
 {
-	int ret = platform_driver_register(&bq27000_battery_driver);
+	int ret = platform_driver_register(&bq27xxx_battery_platform_driver);
 
 	if (ret)
-		pr_err("Unable to register BQ27000 platform driver\n");
+		pr_err("Unable to register BQ27xxx platform driver\n");
 
 	return ret;
 }
 
-static inline void bq27x00_battery_platform_exit(void)
+static inline void bq27xxx_battery_platform_exit(void)
 {
-	platform_driver_unregister(&bq27000_battery_driver);
+	platform_driver_unregister(&bq27xxx_battery_platform_driver);
 }
 
 #else
 
-static inline int bq27x00_battery_platform_init(void) { return 0; }
-static inline void bq27x00_battery_platform_exit(void) {};
+static inline int bq27xxx_battery_platform_init(void) { return 0; }
+static inline void bq27xxx_battery_platform_exit(void) {};
 
 #endif
 
@@ -1093,33 +1094,33 @@ static inline void bq27x00_battery_platform_exit(void) {};
  * Module stuff
  */
 
-static int __init bq27x00_battery_init(void)
+static int __init bq27xxx_battery_init(void)
 {
 	int ret;
 
-	ret = bq27x00_battery_i2c_init();
+	ret = bq27xxx_battery_i2c_init();
 	if (ret)
 		return ret;
 
-	ret = bq27x00_battery_platform_init();
+	ret = bq27xxx_battery_platform_init();
 	if (ret)
-		bq27x00_battery_i2c_exit();
+		bq27xxx_battery_i2c_exit();
 
 	return ret;
 }
-module_init(bq27x00_battery_init);
+module_init(bq27xxx_battery_init);
 
-static void __exit bq27x00_battery_exit(void)
+static void __exit bq27xxx_battery_exit(void)
 {
-	bq27x00_battery_platform_exit();
-	bq27x00_battery_i2c_exit();
+	bq27xxx_battery_platform_exit();
+	bq27xxx_battery_i2c_exit();
 }
-module_exit(bq27x00_battery_exit);
+module_exit(bq27xxx_battery_exit);
 
-#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
 MODULE_ALIAS("platform:bq27000-battery");
 #endif
 
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
+MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
index caafb17..8480531 100644
--- a/drivers/w1/slaves/w1_bq27000.c
+++ b/drivers/w1/slaves/w1_bq27000.c
@@ -15,7 +15,7 @@
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
-#include <linux/power/bq27x00_battery.h>
+#include <linux/power/bq27xxx_battery.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
@@ -39,7 +39,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
 	return val;
 }
 
-static struct bq27000_platform_data bq27000_battery_info = {
+static struct bq27xxx_platform_data bq27000_battery_info = {
 	.read   = w1_bq27000_read,
 	.name   = "bq27000-battery",
 };
diff --git a/include/linux/power/bq27x00_battery.h b/include/linux/power/bq27xxx_battery.h
similarity index 85%
rename from include/linux/power/bq27x00_battery.h
rename to include/linux/power/bq27xxx_battery.h
index a857f71..e70a93a 100644
--- a/include/linux/power/bq27x00_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -2,7 +2,7 @@
 #define __LINUX_BQ27X00_BATTERY_H__
 
 /**
- * struct bq27000_plaform_data - Platform data for bq27000 devices
+ * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
  * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
  * @read: HDQ read callback.
  *	This function should provide access to the HDQ bus the battery is
@@ -11,7 +11,7 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
-struct bq27000_platform_data {
+struct bq27xxx_platform_data {
 	const char *name;
 	int (*read)(struct device *dev, unsigned int);
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Rename functions that are used by multiple devices. New devices
have been added and the function names and driver name are no longer
general enough for the functionality they provide.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 MAINTAINERS                                        |   4 +-
 arch/arm/configs/omap2plus_defconfig               |   2 +-
 arch/unicore32/Kconfig                             |   2 +-
 drivers/power/Kconfig                              |  22 +-
 drivers/power/Makefile                             |   2 +-
 .../power/{bq27x00_battery.c => bq27xxx_battery.c} | 333 +++++++++++----------
 drivers/w1/slaves/w1_bq27000.c                     |   4 +-
 .../power/{bq27x00_battery.h => bq27xxx_battery.h} |   4 +-
 8 files changed, 187 insertions(+), 186 deletions(-)
 rename drivers/power/{bq27x00_battery.c => bq27xxx_battery.c} (70%)
 rename include/linux/power/{bq27x00_battery.h => bq27xxx_battery.h} (85%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7ba7ab7..afa5910 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7393,10 +7393,10 @@ NOKIA N900 POWER SUPPLY DRIVERS
 M:	Pali Rohár <pali.rohar@gmail.com>
 S:	Maintained
 F:	include/linux/power/bq2415x_charger.h
-F:	include/linux/power/bq27x00_battery.h
+F:	include/linux/power/bq27xxx_battery.h
 F:	include/linux/power/isp1704_charger.h
 F:	drivers/power/bq2415x_charger.c
-F:	drivers/power/bq27x00_battery.c
+F:	drivers/power/bq27xxx_battery.c
 F:	drivers/power/isp1704_charger.c
 F:	drivers/power/rx51_battery.c
 
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 50c84e1..6a9ec3e 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -245,7 +245,7 @@ CONFIG_GPIO_TWL4030=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_W1=m
 CONFIG_HDQ_MASTER_OMAP=m
-CONFIG_BATTERY_BQ27x00=m
+CONFIG_BATTERY_BQ27XXX=m
 CONFIG_CHARGER_ISP1704=m
 CONFIG_CHARGER_TWL4030=m
 CONFIG_CHARGER_BQ2415X=m
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 928237a..c9faddc 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -222,7 +222,7 @@ config I2C_BATTERY_BQ27200
 	tristate "I2C Battery BQ27200 Support"
 	select I2C_PUV3
 	select POWER_SUPPLY
-	select BATTERY_BQ27x00
+	select BATTERY_BQ27XXX
 
 config I2C_EEPROM_AT24
 	tristate "I2C EEPROMs AT24 support"
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index f8758d6..53c7469 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -157,26 +157,26 @@ config BATTERY_SBS
 	  Say Y to include support for SBS battery driver for SBS-compliant
 	  gas gauges.
 
-config BATTERY_BQ27x00
-	tristate "BQ27x00 battery driver"
+config BATTERY_BQ27XXX
+	tristate "BQ27xxx battery driver"
 	depends on I2C || I2C=n
 	help
-	  Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (I2C/HDQ) chips.
 
-config BATTERY_BQ27X00_I2C
-	bool "BQ27200/BQ27500 support"
-	depends on BATTERY_BQ27x00
+config BATTERY_BQ27XXX_I2C
+	bool "BQ27xxx I2C support"
+	depends on BATTERY_BQ27XXX
 	depends on I2C
 	default y
 	help
-	  Say Y here to enable support for batteries with BQ27x00 (I2C) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (I2C) chips.
 
-config BATTERY_BQ27X00_PLATFORM
-	bool "BQ27000 support"
-	depends on BATTERY_BQ27x00
+config BATTERY_BQ27XXX_PLATFORM
+	bool "BQ27xxx HDQ support"
+	depends on BATTERY_BQ27XXX
 	default y
 	help
-	  Say Y here to enable support for batteries with BQ27000 (HDQ) chips.
+	  Say Y here to enable support for batteries with BQ27xxx (HDQ) chips.
 
 config BATTERY_DA9030
 	tristate "DA9030 battery driver"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 5752ce8..7a5bc96 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_BATTERY_COLLIE)	+= collie_battery.o
 obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
 obj-$(CONFIG_BATTERY_WM97XX)	+= wm97xx_battery.o
 obj-$(CONFIG_BATTERY_SBS)	+= sbs-battery.o
-obj-$(CONFIG_BATTERY_BQ27x00)	+= bq27x00_battery.o
+obj-$(CONFIG_BATTERY_BQ27XXX)	+= bq27xxx_battery.o
 obj-$(CONFIG_BATTERY_DA9030)	+= da9030_battery.o
 obj-$(CONFIG_BATTERY_DA9052)	+= da9052-battery.o
 obj-$(CONFIG_CHARGER_DA9150)	+= da9150-charger.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27xxx_battery.c
similarity index 70%
rename from drivers/power/bq27x00_battery.c
rename to drivers/power/bq27xxx_battery.c
index d0b2f3b..e72055c 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -1,5 +1,5 @@
 /*
- * BQ27x00 battery driver
+ * BQ27xxx battery driver
  *
  * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
@@ -37,7 +37,7 @@
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 
-#include <linux/power/bq27x00_battery.h>
+#include <linux/power/bq27xxx_battery.h>
 
 #define DRIVER_VERSION		"1.2.0"
 
@@ -83,17 +83,17 @@
 #define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
 #define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
 
-#define BQ27000_RS			20 /* Resistor sense */
-#define BQ27x00_POWER_CONSTANT		(256 * 29200 / 1000)
+#define BQ27XXX_RS			20 /* Resistor sense */
+#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
 
-struct bq27x00_device_info;
-struct bq27x00_access_methods {
-	int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);
+struct bq27xxx_device_info;
+struct bq27xxx_access_methods {
+	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
-enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
+enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
 
-struct bq27x00_reg_cache {
+struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
 	int time_to_empty_avg;
@@ -107,12 +107,12 @@ struct bq27x00_reg_cache {
 	int health;
 };
 
-struct bq27x00_device_info {
+struct bq27xxx_device_info {
 	struct device		*dev;
 	int			id;
-	enum bq27x00_chip	chip;
+	enum bq27xxx_chip	chip;
 
-	struct bq27x00_reg_cache cache;
+	struct bq27xxx_reg_cache cache;
 	int charge_design_full;
 
 	unsigned long last_update;
@@ -120,7 +120,7 @@ struct bq27x00_device_info {
 
 	struct power_supply	*bat;
 
-	struct bq27x00_access_methods bus;
+	struct bq27xxx_access_methods bus;
 
 	struct mutex lock;
 };
@@ -206,10 +206,10 @@ MODULE_PARM_DESC(poll_interval,
 		 "battery poll interval in seconds - 0 disables polling");
 
 /*
- * Common code for BQ27x00 devices
+ * Common code for BQ27xxx devices
  */
 
-static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
+static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
 			       bool single)
 {
 	if (di->chip == BQ27425)
@@ -222,7 +222,7 @@ static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
  * differ from BQ27000 and BQ27200 in calculation of certain
  * parameters. Hence we need to check for the chip type.
  */
-static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
+static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
 {
 	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
 	    || di->chip == BQ27510)
@@ -234,18 +234,18 @@ static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
  * Return the battery Relative State-of-Charge
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_rsoc(struct bq27xxx_device_info *di)
 {
 	int rsoc;
 
 	if (di->chip == BQ27500 || di->chip == BQ27742)
-		rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27500_REG_SOC, false);
 	else if (di->chip == BQ27510)
-		rsoc = bq27x00_read(di, BQ27510_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27510_REG_SOC, false);
 	else if (di->chip == BQ27425)
-		rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
+		rsoc = bq27xxx_read(di, BQ27425_REG_SOC, false);
 	else
-		rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
+		rsoc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
 
 	if (rsoc < 0)
 		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
@@ -257,11 +257,11 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
  * Return a battery charge value in µAh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 {
 	int charge;
 
-	charge = bq27x00_read(di, reg, false);
+	charge = bq27xxx_read(di, reg, false);
 	if (charge < 0) {
 		dev_dbg(di->dev, "error reading charge register %02x: %d\n",
 			reg, charge);
@@ -271,7 +271,7 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
 	if (bq27xxx_is_chip_version_higher(di))
 		charge *= 1000;
 	else
-		charge = charge * 3570 / BQ27000_RS;
+		charge = charge * 3570 / BQ27XXX_RS;
 
 	return charge;
 }
@@ -280,7 +280,7 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
  * Return the battery Nominal available capaciy in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)
+static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
 {
 	int flags;
 	bool is_bq27500 = di->chip == BQ27500;
@@ -288,39 +288,39 @@ static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)
 	bool is_higher = bq27xxx_is_chip_version_higher(di);
 	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	flags = bq27x00_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
 	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
 		return -ENODATA;
 
-	return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC);
+	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
 }
 
 /*
  * Return the battery Last measured discharge in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27x00_battery_read_lmd(struct bq27x00_device_info *di)
+static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
 {
-	return bq27x00_battery_read_charge(di, BQ27x00_REG_LMD);
+	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
 }
 
 /*
  * Return the battery Initial last measured discharge in µAh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
 {
 	int ilmd;
 
 	if (bq27xxx_is_chip_version_higher(di)) {
 		if (di->chip == BQ27425)
-			ilmd = bq27x00_read(di, BQ27425_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
 		else if (di->chip == BQ27510)
-			ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
 		else
-			ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);
+			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
 	} else {
-		ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
+		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
 	}
 
 	if (ilmd < 0) {
@@ -331,7 +331,7 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
 	if (bq27xxx_is_chip_version_higher(di))
 		ilmd *= 1000;
 	else
-		ilmd = ilmd * 256 * 3570 / BQ27000_RS;
+		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
 
 	return ilmd;
 }
@@ -340,11 +340,11 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
  * Return the battery Available energy in µWh
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
 {
 	int ae;
 
-	ae = bq27x00_read(di, BQ27x00_REG_AE, false);
+	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
 	if (ae < 0) {
 		dev_dbg(di->dev, "error reading available energy\n");
 		return ae;
@@ -353,7 +353,7 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
 	if (di->chip == BQ27500)
 		ae *= 1000;
 	else
-		ae = ae * 29200 / BQ27000_RS;
+		ae = ae * 29200 / BQ27XXX_RS;
 
 	return ae;
 }
@@ -362,11 +362,11 @@ static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
  * Return the battery temperature in tenths of degree Kelvin
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
 {
 	int temp;
 
-	temp = bq27x00_read(di, BQ27x00_REG_TEMP, false);
+	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
 	if (temp < 0) {
 		dev_err(di->dev, "error reading temperature\n");
 		return temp;
@@ -382,14 +382,14 @@ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
  * Return the battery Cycle count total
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
 {
 	int cyct;
 
 	if (di->chip == BQ27510)
-		cyct = bq27x00_read(di, BQ27510_REG_CYCT, false);
+		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
 	else
-		cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false);
+		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
 	if (cyct < 0)
 		dev_err(di->dev, "error reading cycle count total\n");
 
@@ -400,11 +400,11 @@ static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di)
  * Read a time register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
 {
 	int tval;
 
-	tval = bq27x00_read(di, reg, false);
+	tval = bq27xxx_read(di, reg, false);
 	if (tval < 0) {
 		dev_dbg(di->dev, "error reading time register %02x: %d\n",
 			reg, tval);
@@ -421,11 +421,11 @@ static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)
  * Read a power avg register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
+static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
 {
 	int tval;
 
-	tval = bq27x00_read(di, reg, false);
+	tval = bq27xxx_read(di, reg, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
 			reg, tval);
@@ -435,18 +435,18 @@ static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
 	if (di->chip == BQ27500)
 		return tval;
 	else
-		return (tval * BQ27x00_POWER_CONSTANT) / BQ27000_RS;
+		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
 }
 
 /*
  * Read flag register.
  * Return < 0 if something fails.
  */
-static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
+static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
 	int tval;
 
-	tval = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
+	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading flag register:%d\n", tval);
 		return tval;
@@ -475,16 +475,16 @@ static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
 	return -1;
 }
 
-static void bq27x00_update(struct bq27x00_device_info *di)
+static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 {
-	struct bq27x00_reg_cache cache = {0, };
+	struct bq27xxx_reg_cache cache = {0, };
 	bool is_bq27500 = di->chip == BQ27500;
 	bool is_bq27510 = di->chip == BQ27510;
 	bool is_bq27425 = di->chip == BQ27425;
 	bool is_bq27742 = di->chip == BQ27742;
 	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
 	if ((cache.flags & 0xff) == 0xff)
 		/* read error */
 		cache.flags = -1;
@@ -500,41 +500,41 @@ static void bq27x00_update(struct bq27x00_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
-			cache.capacity = bq27x00_battery_read_rsoc(di);
+			cache.capacity = bq27xxx_battery_read_rsoc(di);
 			if (is_bq27742 || is_bq27510)
 				cache.time_to_empty =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTE);
 			else if (!is_bq27425) {
-				cache.energy = bq27x00_battery_read_energy(di);
+				cache.energy = bq27xxx_battery_read_energy(di);
 				cache.time_to_empty =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTE);
 				cache.time_to_empty_avg =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTECP);
 				cache.time_to_full =
-					bq27x00_battery_read_time(di,
+					bq27xxx_battery_read_time(di,
 							BQ27x00_REG_TTF);
 			}
-			cache.charge_full = bq27x00_battery_read_lmd(di);
-			cache.health = bq27x00_battery_read_health(di);
+			cache.charge_full = bq27xxx_battery_read_lmd(di);
+			cache.health = bq27xxx_battery_read_health(di);
 		}
-		cache.temperature = bq27x00_battery_read_temperature(di);
+		cache.temperature = bq27xxx_battery_read_temperature(di);
 		if (!is_bq27425)
-			cache.cycle_count = bq27x00_battery_read_cyct(di);
+			cache.cycle_count = bq27xxx_battery_read_cyct(di);
 		if (is_bq27742)
 			cache.power_avg =
-				bq27x00_battery_read_pwr_avg(di,
+				bq27xxx_battery_read_pwr_avg(di,
 						BQ27742_POWER_AVG);
 		else
 			cache.power_avg =
-				bq27x00_battery_read_pwr_avg(di,
+				bq27xxx_battery_read_pwr_avg(di,
 						BQ27x00_POWER_AVG);
 
 		/* We only have to read charge design full once */
 		if (di->charge_design_full <= 0)
-			di->charge_design_full = bq27x00_battery_read_ilmd(di);
+			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
 	}
 
 	if (di->cache.capacity != cache.capacity)
@@ -546,12 +546,12 @@ static void bq27x00_update(struct bq27x00_device_info *di)
 	di->last_update = jiffies;
 }
 
-static void bq27x00_battery_poll(struct work_struct *work)
+static void bq27xxx_battery_poll(struct work_struct *work)
 {
-	struct bq27x00_device_info *di =
-		container_of(work, struct bq27x00_device_info, work.work);
+	struct bq27xxx_device_info *di =
+		container_of(work, struct bq27xxx_device_info, work.work);
 
-	bq27x00_update(di);
+	bq27xxx_battery_update(di);
 
 	if (poll_interval > 0) {
 		/* The timer does not have to be accurate. */
@@ -565,13 +565,13 @@ static void bq27x00_battery_poll(struct work_struct *work)
  * Note that current can be negative signed as well
  * Or 0 if something fails.
  */
-static int bq27x00_battery_current(struct bq27x00_device_info *di,
+static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
 				   union power_supply_propval *val)
 {
 	int curr;
 	int flags;
 
-	curr = bq27x00_read(di, BQ27x00_REG_AI, false);
+	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
 	if (curr < 0) {
 		dev_err(di->dev, "error reading current\n");
 		return curr;
@@ -581,19 +581,19 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di,
 		/* bq27500 returns signed value */
 		val->intval = (int)((s16)curr) * 1000;
 	} else {
-		flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
+		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
 		if (flags & BQ27000_FLAG_CHGS) {
 			dev_dbg(di->dev, "negative current!\n");
 			curr = -curr;
 		}
 
-		val->intval = curr * 3570 / BQ27000_RS;
+		val->intval = curr * 3570 / BQ27XXX_RS;
 	}
 
 	return 0;
 }
 
-static int bq27x00_battery_status(struct bq27x00_device_info *di,
+static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 				  union power_supply_propval *val)
 {
 	int status;
@@ -621,7 +621,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
 	return 0;
 }
 
-static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
+static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
 					  union power_supply_propval *val)
 {
 	int level;
@@ -655,12 +655,12 @@ static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
  * Return the battery Voltage in millivolts
  * Or < 0 if something fails.
  */
-static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
+static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
 				   union power_supply_propval *val)
 {
 	int volt;
 
-	volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
+	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
 	if (volt < 0) {
 		dev_err(di->dev, "error reading voltage\n");
 		return volt;
@@ -671,7 +671,7 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
 	return 0;
 }
 
-static int bq27x00_simple_value(int value,
+static int bq27xxx_simple_value(int value,
 				union power_supply_propval *val)
 {
 	if (value < 0)
@@ -682,17 +682,17 @@ static int bq27x00_simple_value(int value,
 	return 0;
 }
 
-static int bq27x00_battery_get_property(struct power_supply *psy,
+static int bq27xxx_battery_get_property(struct power_supply *psy,
 					enum power_supply_property psp,
 					union power_supply_propval *val)
 {
 	int ret = 0;
-	struct bq27x00_device_info *di = power_supply_get_drvdata(psy);
+	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
 	mutex_lock(&di->lock);
 	if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
 		cancel_delayed_work_sync(&di->work);
-		bq27x00_battery_poll(&di->work.work);
+		bq27xxx_battery_poll(&di->work.work);
 	}
 	mutex_unlock(&di->lock);
 
@@ -701,60 +701,60 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		ret = bq27x00_battery_status(di, val);
+		ret = bq27xxx_battery_status(di, val);
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		ret = bq27x00_battery_voltage(di, val);
+		ret = bq27xxx_battery_voltage(di, val);
 		break;
 	case POWER_SUPPLY_PROP_PRESENT:
 		val->intval = di->cache.flags < 0 ? 0 : 1;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		ret = bq27x00_battery_current(di, val);
+		ret = bq27xxx_battery_current(di, val);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
-		ret = bq27x00_simple_value(di->cache.capacity, val);
+		ret = bq27xxx_simple_value(di->cache.capacity, val);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
-		ret = bq27x00_battery_capacity_level(di, val);
+		ret = bq27xxx_battery_capacity_level(di, val);
 		break;
 	case POWER_SUPPLY_PROP_TEMP:
-		ret = bq27x00_simple_value(di->cache.temperature, val);
+		ret = bq27xxx_simple_value(di->cache.temperature, val);
 		if (ret == 0)
 			val->intval -= 2731;
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
-		ret = bq27x00_simple_value(di->cache.time_to_empty, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
-		ret = bq27x00_simple_value(di->cache.time_to_empty_avg, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_empty_avg, val);
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
-		ret = bq27x00_simple_value(di->cache.time_to_full, val);
+		ret = bq27xxx_simple_value(di->cache.time_to_full, val);
 		break;
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_NOW:
-		ret = bq27x00_simple_value(bq27x00_battery_read_nac(di), val);
+		ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL:
-		ret = bq27x00_simple_value(di->cache.charge_full, val);
+		ret = bq27xxx_simple_value(di->cache.charge_full, val);
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
-		ret = bq27x00_simple_value(di->charge_design_full, val);
+		ret = bq27xxx_simple_value(di->charge_design_full, val);
 		break;
 	case POWER_SUPPLY_PROP_CYCLE_COUNT:
-		ret = bq27x00_simple_value(di->cache.cycle_count, val);
+		ret = bq27xxx_simple_value(di->cache.cycle_count, val);
 		break;
 	case POWER_SUPPLY_PROP_ENERGY_NOW:
-		ret = bq27x00_simple_value(di->cache.energy, val);
+		ret = bq27xxx_simple_value(di->cache.energy, val);
 		break;
 	case POWER_SUPPLY_PROP_POWER_AVG:
-		ret = bq27x00_simple_value(di->cache.power_avg, val);
+		ret = bq27xxx_simple_value(di->cache.power_avg, val);
 		break;
 	case POWER_SUPPLY_PROP_HEALTH:
-		ret = bq27x00_simple_value(di->cache.health, val);
+		ret = bq27xxx_simple_value(di->cache.health, val);
 		break;
 	case POWER_SUPPLY_PROP_MANUFACTURER:
 		val->strval = BQ27XXX_MANUFACTURER;
@@ -766,15 +766,15 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
 	return ret;
 }
 
-static void bq27x00_external_power_changed(struct power_supply *psy)
+static void bq27xxx_external_power_changed(struct power_supply *psy)
 {
-	struct bq27x00_device_info *di = power_supply_get_drvdata(psy);
+	struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
 
 	cancel_delayed_work_sync(&di->work);
 	schedule_delayed_work(&di->work, 0);
 }
 
-static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
+static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
 				    const char *name)
 {
 	int ret;
@@ -800,10 +800,10 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
 		psy_desc->properties = bq27x00_battery_props;
 		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
 	}
-	psy_desc->get_property = bq27x00_battery_get_property;
-	psy_desc->external_power_changed = bq27x00_external_power_changed;
+	psy_desc->get_property = bq27xxx_battery_get_property;
+	psy_desc->external_power_changed = bq27xxx_external_power_changed;
 
-	INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll);
+	INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
 	mutex_init(&di->lock);
 
 	di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
@@ -815,17 +815,17 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di,
 
 	dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
 
-	bq27x00_update(di);
+	bq27xxx_battery_update(di);
 
 	return 0;
 }
 
-static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
+static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di)
 {
 	/*
-	 * power_supply_unregister call bq27x00_battery_get_property which
-	 * call bq27x00_battery_poll.
-	 * Make sure that bq27x00_battery_poll will not call
+	 * power_supply_unregister call bq27xxx_battery_get_property which
+	 * call bq27xxx_battery_poll.
+	 * Make sure that bq27xxx_battery_poll will not call
 	 * schedule_delayed_work again after unregister (which cause OOPS).
 	 */
 	poll_interval = 0;
@@ -838,7 +838,7 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
 }
 
 /* i2c specific code */
-#ifdef CONFIG_BATTERY_BQ27X00_I2C
+#ifdef CONFIG_BATTERY_BQ27XXX_I2C
 
 /* If the system has several batteries we need a different name for each
  * of them...
@@ -846,7 +846,8 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)
 static DEFINE_IDR(battery_id);
 static DEFINE_MUTEX(battery_mutex);
 
-static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single)
+static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
+				    bool single)
 {
 	struct i2c_client *client = to_i2c_client(di->dev);
 	struct i2c_msg msg[2];
@@ -880,11 +881,11 @@ static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single)
 	return ret;
 }
 
-static int bq27x00_battery_probe(struct i2c_client *client,
-				 const struct i2c_device_id *id)
+static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
 {
 	char *name;
-	struct bq27x00_device_info *di;
+	struct bq27xxx_device_info *di;
 	int num;
 	int retval = 0;
 
@@ -910,9 +911,9 @@ static int bq27x00_battery_probe(struct i2c_client *client,
 	di->id = num;
 	di->dev = &client->dev;
 	di->chip = id->driver_data;
-	di->bus.read = &bq27x00_read_i2c;
+	di->bus.read = &bq27xxx_battery_i2c_read;
 
-	retval = bq27x00_powersupply_init(di, name);
+	retval = bq27xxx_powersupply_init(di, name);
 	if (retval)
 		goto batt_failed;
 
@@ -928,11 +929,11 @@ batt_failed:
 	return retval;
 }
 
-static int bq27x00_battery_remove(struct i2c_client *client)
+static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
 {
-	struct bq27x00_device_info *di = i2c_get_clientdata(client);
+	struct bq27xxx_device_info *di = i2c_get_clientdata(client);
 
-	bq27x00_powersupply_unregister(di);
+	bq27xxx_powersupply_unregister(di);
 
 	mutex_lock(&battery_mutex);
 	idr_remove(&battery_id, di->id);
@@ -941,7 +942,7 @@ static int bq27x00_battery_remove(struct i2c_client *client)
 	return 0;
 }
 
-static const struct i2c_device_id bq27x00_id[] = {
+static const struct i2c_device_id bq27xxx_id[] = {
 	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
 	{ "bq27500", BQ27500 },
 	{ "bq27425", BQ27425 },
@@ -949,47 +950,47 @@ static const struct i2c_device_id bq27x00_id[] = {
 	{ "bq27510", BQ27510 },
 	{},
 };
-MODULE_DEVICE_TABLE(i2c, bq27x00_id);
+MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
 
-static struct i2c_driver bq27x00_battery_driver = {
+static struct i2c_driver bq27xxx_battery_i2c_driver = {
 	.driver = {
-		.name = "bq27x00-battery",
+		.name = "bq27xxx-battery",
 	},
-	.probe = bq27x00_battery_probe,
-	.remove = bq27x00_battery_remove,
-	.id_table = bq27x00_id,
+	.probe = bq27xxx_battery_i2c_probe,
+	.remove = bq27xxx_battery_i2c_remove,
+	.id_table = bq27xxx_id,
 };
 
-static inline int bq27x00_battery_i2c_init(void)
+static inline int bq27xxx_battery_i2c_init(void)
 {
-	int ret = i2c_add_driver(&bq27x00_battery_driver);
+	int ret = i2c_add_driver(&bq27xxx_battery_i2c_driver);
 
 	if (ret)
-		pr_err("Unable to register BQ27x00 i2c driver\n");
+		pr_err("Unable to register BQ27xxx i2c driver\n");
 
 	return ret;
 }
 
-static inline void bq27x00_battery_i2c_exit(void)
+static inline void bq27xxx_battery_i2c_exit(void)
 {
-	i2c_del_driver(&bq27x00_battery_driver);
+	i2c_del_driver(&bq27xxx_battery_i2c_driver);
 }
 
 #else
 
-static inline int bq27x00_battery_i2c_init(void) { return 0; }
-static inline void bq27x00_battery_i2c_exit(void) {};
+static inline int bq27xxx_battery_i2c_init(void) { return 0; }
+static inline void bq27xxx_battery_i2c_exit(void) {};
 
 #endif
 
 /* platform specific code */
-#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
 
-static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
-				 bool single)
+static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg,
+					 bool single)
 {
 	struct device *dev = di->dev;
-	struct bq27000_platform_data *pdata = dev->platform_data;
+	struct bq27xxx_platform_data *pdata = dev->platform_data;
 	unsigned int timeout = 3;
 	int upper, lower;
 	int temp;
@@ -1019,10 +1020,10 @@ static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,
 	return pdata->read(dev, reg);
 }
 
-static int bq27000_battery_probe(struct platform_device *pdev)
+static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 {
-	struct bq27x00_device_info *di;
-	struct bq27000_platform_data *pdata = pdev->dev.platform_data;
+	struct bq27xxx_device_info *di;
+	struct bq27xxx_platform_data *pdata = pdev->dev.platform_data;
 	const char *name;
 
 	if (!pdata) {
@@ -1045,47 +1046,47 @@ static int bq27000_battery_probe(struct platform_device *pdev)
 	di->chip = BQ27000;
 
 	name = pdata->name ?: dev_name(&pdev->dev);
-	di->bus.read = &bq27000_read_platform;
+	di->bus.read = &bq27xxx_battery_platform_read;
 
-	return bq27x00_powersupply_init(di, name);
+	return bq27xxx_powersupply_init(di, name);
 }
 
-static int bq27000_battery_remove(struct platform_device *pdev)
+static int bq27xxx_battery_platform_remove(struct platform_device *pdev)
 {
-	struct bq27x00_device_info *di = platform_get_drvdata(pdev);
+	struct bq27xxx_device_info *di = platform_get_drvdata(pdev);
 
-	bq27x00_powersupply_unregister(di);
+	bq27xxx_powersupply_unregister(di);
 
 	return 0;
 }
 
-static struct platform_driver bq27000_battery_driver = {
-	.probe	= bq27000_battery_probe,
-	.remove = bq27000_battery_remove,
+static struct platform_driver bq27xxx_battery_platform_driver = {
+	.probe	= bq27xxx_battery_platform_probe,
+	.remove = bq27xxx_battery_platform_remove,
 	.driver = {
 		.name = "bq27000-battery",
 	},
 };
 
-static inline int bq27x00_battery_platform_init(void)
+static inline int bq27xxx_battery_platform_init(void)
 {
-	int ret = platform_driver_register(&bq27000_battery_driver);
+	int ret = platform_driver_register(&bq27xxx_battery_platform_driver);
 
 	if (ret)
-		pr_err("Unable to register BQ27000 platform driver\n");
+		pr_err("Unable to register BQ27xxx platform driver\n");
 
 	return ret;
 }
 
-static inline void bq27x00_battery_platform_exit(void)
+static inline void bq27xxx_battery_platform_exit(void)
 {
-	platform_driver_unregister(&bq27000_battery_driver);
+	platform_driver_unregister(&bq27xxx_battery_platform_driver);
 }
 
 #else
 
-static inline int bq27x00_battery_platform_init(void) { return 0; }
-static inline void bq27x00_battery_platform_exit(void) {};
+static inline int bq27xxx_battery_platform_init(void) { return 0; }
+static inline void bq27xxx_battery_platform_exit(void) {};
 
 #endif
 
@@ -1093,33 +1094,33 @@ static inline void bq27x00_battery_platform_exit(void) {};
  * Module stuff
  */
 
-static int __init bq27x00_battery_init(void)
+static int __init bq27xxx_battery_init(void)
 {
 	int ret;
 
-	ret = bq27x00_battery_i2c_init();
+	ret = bq27xxx_battery_i2c_init();
 	if (ret)
 		return ret;
 
-	ret = bq27x00_battery_platform_init();
+	ret = bq27xxx_battery_platform_init();
 	if (ret)
-		bq27x00_battery_i2c_exit();
+		bq27xxx_battery_i2c_exit();
 
 	return ret;
 }
-module_init(bq27x00_battery_init);
+module_init(bq27xxx_battery_init);
 
-static void __exit bq27x00_battery_exit(void)
+static void __exit bq27xxx_battery_exit(void)
 {
-	bq27x00_battery_platform_exit();
-	bq27x00_battery_i2c_exit();
+	bq27xxx_battery_platform_exit();
+	bq27xxx_battery_i2c_exit();
 }
-module_exit(bq27x00_battery_exit);
+module_exit(bq27xxx_battery_exit);
 
-#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
 MODULE_ALIAS("platform:bq27000-battery");
 #endif
 
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
+MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
index caafb17..8480531 100644
--- a/drivers/w1/slaves/w1_bq27000.c
+++ b/drivers/w1/slaves/w1_bq27000.c
@@ -15,7 +15,7 @@
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
-#include <linux/power/bq27x00_battery.h>
+#include <linux/power/bq27xxx_battery.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
@@ -39,7 +39,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
 	return val;
 }
 
-static struct bq27000_platform_data bq27000_battery_info = {
+static struct bq27xxx_platform_data bq27000_battery_info = {
 	.read   = w1_bq27000_read,
 	.name   = "bq27000-battery",
 };
diff --git a/include/linux/power/bq27x00_battery.h b/include/linux/power/bq27xxx_battery.h
similarity index 85%
rename from include/linux/power/bq27x00_battery.h
rename to include/linux/power/bq27xxx_battery.h
index a857f71..e70a93a 100644
--- a/include/linux/power/bq27x00_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -2,7 +2,7 @@
 #define __LINUX_BQ27X00_BATTERY_H__
 
 /**
- * struct bq27000_plaform_data - Platform data for bq27000 devices
+ * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
  * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
  * @read: HDQ read callback.
  *	This function should provide access to the HDQ bus the battery is
@@ -11,7 +11,7 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
-struct bq27000_platform_data {
+struct bq27xxx_platform_data {
 	const char *name;
 	int (*read)(struct device *dev, unsigned int);
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

When initialized as a platform device the initializer must now specify
a device. An empty device name is no longer valid.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c       | 9 ++++++---
 drivers/w1/slaves/w1_bq27000.c        | 1 +
 include/linux/power/bq27xxx_battery.h | 6 +++++-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index e72055c..0734413 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -91,8 +91,6 @@ struct bq27xxx_access_methods {
 	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
-enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
-
 struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
@@ -1036,6 +1034,11 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	if (!pdata->chip) {
+		dev_err(&pdev->dev, "no device supplied\n");
+		return -EINVAL;
+	}
+
 	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
 	if (!di)
 		return -ENOMEM;
@@ -1043,7 +1046,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, di);
 
 	di->dev = &pdev->dev;
-	di->chip = BQ27000;
+	di->chip = pdata->chip;
 
 	name = pdata->name ?: dev_name(&pdev->dev);
 	di->bus.read = &bq27xxx_battery_platform_read;
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
index 8480531..9f4a86b 100644
--- a/drivers/w1/slaves/w1_bq27000.c
+++ b/drivers/w1/slaves/w1_bq27000.c
@@ -42,6 +42,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
 static struct bq27xxx_platform_data bq27000_battery_info = {
 	.read   = w1_bq27000_read,
 	.name   = "bq27000-battery",
+	.chip   = BQ27000,
 };
 
 static int w1_bq27000_add_slave(struct w1_slave *sl)
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index e70a93a..a4efb10 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -3,7 +3,8 @@
 
 /**
  * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
- * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
+ * @name: Name of the battery.
+ * @chip: Chip class number of this device.
  * @read: HDQ read callback.
  *	This function should provide access to the HDQ bus the battery is
  *	connected to.
@@ -11,8 +12,11 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
+enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
+
 struct bq27xxx_platform_data {
 	const char *name;
+	enum bq27xxx_chip chip;
 	int (*read)(struct device *dev, unsigned int);
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

When initialized as a platform device the initializer must now specify
a device. An empty device name is no longer valid.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c       | 9 ++++++---
 drivers/w1/slaves/w1_bq27000.c        | 1 +
 include/linux/power/bq27xxx_battery.h | 6 +++++-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index e72055c..0734413 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -91,8 +91,6 @@ struct bq27xxx_access_methods {
 	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
-enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
-
 struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
@@ -1036,6 +1034,11 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	if (!pdata->chip) {
+		dev_err(&pdev->dev, "no device supplied\n");
+		return -EINVAL;
+	}
+
 	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
 	if (!di)
 		return -ENOMEM;
@@ -1043,7 +1046,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, di);
 
 	di->dev = &pdev->dev;
-	di->chip = BQ27000;
+	di->chip = pdata->chip;
 
 	name = pdata->name ?: dev_name(&pdev->dev);
 	di->bus.read = &bq27xxx_battery_platform_read;
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
index 8480531..9f4a86b 100644
--- a/drivers/w1/slaves/w1_bq27000.c
+++ b/drivers/w1/slaves/w1_bq27000.c
@@ -42,6 +42,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
 static struct bq27xxx_platform_data bq27000_battery_info = {
 	.read   = w1_bq27000_read,
 	.name   = "bq27000-battery",
+	.chip   = BQ27000,
 };
 
 static int w1_bq27000_add_slave(struct w1_slave *sl)
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index e70a93a..a4efb10 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -3,7 +3,8 @@
 
 /**
  * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
- * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
+ * @name: Name of the battery.
+ * @chip: Chip class number of this device.
  * @read: HDQ read callback.
  *	This function should provide access to the HDQ bus the battery is
  *	connected to.
@@ -11,8 +12,11 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
+enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
+
 struct bq27xxx_platform_data {
 	const char *name;
+	enum bq27xxx_chip chip;
 	int (*read)(struct device *dev, unsigned int);
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 4/7] power: bq27xxx_battery: Fix typos and change naming for state of charge functions
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Fix typos and change "relative state of charge" to "state of charge" as not
all supported devices use relative state of charge.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 0734413..1ff88ad 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -229,26 +229,26 @@ static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
 }
 
 /*
- * Return the battery Relative State-of-Charge
+ * Return the battery State-of-Charge
  * Or < 0 if something fails.
  */
-static int bq27xxx_battery_read_rsoc(struct bq27xxx_device_info *di)
+static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
 {
-	int rsoc;
+	int soc;
 
 	if (di->chip == BQ27500 || di->chip == BQ27742)
-		rsoc = bq27xxx_read(di, BQ27500_REG_SOC, false);
+		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
 	else if (di->chip == BQ27510)
-		rsoc = bq27xxx_read(di, BQ27510_REG_SOC, false);
+		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
 	else if (di->chip == BQ27425)
-		rsoc = bq27xxx_read(di, BQ27425_REG_SOC, false);
-	else
-		rsoc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
+		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
+	else /* for the bq27000 we read the "relative" SoC register */
+		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
 
-	if (rsoc < 0)
-		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
+	if (soc < 0)
+		dev_dbg(di->dev, "error reading State-of-Charge\n");
 
-	return rsoc;
+	return soc;
 }
 
 /*
@@ -275,7 +275,7 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 }
 
 /*
- * Return the battery Nominal available capaciy in µAh
+ * Return the battery Nominal available capacity in µAh
  * Or < 0 if something fails.
  */
 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
@@ -416,7 +416,7 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
 }
 
 /*
- * Read a power avg register.
+ * Read an average power register.
  * Return < 0 if something fails.
  */
 static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
@@ -498,7 +498,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
-			cache.capacity = bq27xxx_battery_read_rsoc(di);
+			cache.capacity = bq27xxx_battery_read_soc(di);
 			if (is_bq27742 || is_bq27510)
 				cache.time_to_empty =
 					bq27xxx_battery_read_time(di,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 4/7] power: bq27xxx_battery: Fix typos and change naming for state of charge functions
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Fix typos and change "relative state of charge" to "state of charge" as not
all supported devices use relative state of charge.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 0734413..1ff88ad 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -229,26 +229,26 @@ static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
 }
 
 /*
- * Return the battery Relative State-of-Charge
+ * Return the battery State-of-Charge
  * Or < 0 if something fails.
  */
-static int bq27xxx_battery_read_rsoc(struct bq27xxx_device_info *di)
+static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
 {
-	int rsoc;
+	int soc;
 
 	if (di->chip == BQ27500 || di->chip == BQ27742)
-		rsoc = bq27xxx_read(di, BQ27500_REG_SOC, false);
+		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
 	else if (di->chip == BQ27510)
-		rsoc = bq27xxx_read(di, BQ27510_REG_SOC, false);
+		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
 	else if (di->chip == BQ27425)
-		rsoc = bq27xxx_read(di, BQ27425_REG_SOC, false);
-	else
-		rsoc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
+		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
+	else /* for the bq27000 we read the "relative" SoC register */
+		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
 
-	if (rsoc < 0)
-		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
+	if (soc < 0)
+		dev_dbg(di->dev, "error reading State-of-Charge\n");
 
-	return rsoc;
+	return soc;
 }
 
 /*
@@ -275,7 +275,7 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 }
 
 /*
- * Return the battery Nominal available capaciy in µAh
+ * Return the battery Nominal available capacity in µAh
  * Or < 0 if something fails.
  */
 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
@@ -416,7 +416,7 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
 }
 
 /*
- * Read a power avg register.
+ * Read an average power register.
  * Return < 0 if something fails.
  */
 static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
@@ -498,7 +498,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
-			cache.capacity = bq27xxx_battery_read_rsoc(di);
+			cache.capacity = bq27xxx_battery_read_soc(di);
 			if (is_bq27742 || is_bq27510)
 				cache.time_to_empty =
 					bq27xxx_battery_read_time(di,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Add support for additional devices and register equivalent family devices
including the bq27010, bq27210, bq27500, bq27510, bq27520, bq27530,
bq27531, bq27541, bq27542, bq27546, bq27545, bq27441, bq27421, and the
bq27641.

To facilitate this process the register mapings have been moved to tables
and other small cleanups have been made.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c       | 627 +++++++++++++++++++++++-----------
 include/linux/power/bq27xxx_battery.h |  10 +-
 2 files changed, 428 insertions(+), 209 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 1ff88ad..3098609 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -17,11 +17,24 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * Datasheets:
- * http://focus.ti.com/docs/prod/folders/print/bq27000.html
- * http://focus.ti.com/docs/prod/folders/print/bq27500.html
+ * http://www.ti.com/product/bq27000
+ * http://www.ti.com/product/bq27200
+ * http://www.ti.com/product/bq27010
+ * http://www.ti.com/product/bq27210
+ * http://www.ti.com/product/bq27500
+ * http://www.ti.com/product/bq27510-g3
+ * http://www.ti.com/product/bq27520-g4
+ * http://www.ti.com/product/bq27530-g1
+ * http://www.ti.com/product/bq27531-g1
+ * http://www.ti.com/product/bq27541-g1
+ * http://www.ti.com/product/bq27542-g1
+ * http://www.ti.com/product/bq27546-g1
+ * http://www.ti.com/product/bq27742-g1
+ * http://www.ti.com/product/bq27545-g1
+ * http://www.ti.com/product/bq27421-g1
  * http://www.ti.com/product/bq27425-g1
- * http://www.ti.com/product/BQ27742-G1
- * http://www.ti.com/product/BQ27510-G3
+ * http://www.ti.com/product/bq27411-g1
+ * http://www.ti.com/product/bq27621-g1
  */
 
 #include <linux/device.h>
@@ -43,54 +56,57 @@
 
 #define BQ27XXX_MANUFACTURER	"Texas Instruments"
 
-#define BQ27x00_REG_TEMP	0x06
-#define BQ27x00_REG_VOLT	0x08
-#define BQ27x00_REG_AI		0x14
-#define BQ27x00_REG_FLAGS	0x0A
-#define BQ27x00_REG_TTE		0x16
-#define BQ27x00_REG_TTF		0x18
-#define BQ27x00_REG_TTECP	0x26
-#define BQ27x00_REG_NAC		0x0C /* Nominal available capacity */
-#define BQ27x00_REG_LMD		0x12 /* Last measured discharge */
-#define BQ27x00_REG_CYCT	0x2A /* Cycle count total */
-#define BQ27x00_REG_AE		0x22 /* Available energy */
-#define BQ27x00_POWER_AVG	0x24
-
-#define BQ27000_REG_RSOC	0x0B /* Relative State-of-Charge */
-#define BQ27000_REG_ILMD	0x76 /* Initial last measured discharge */
+/* BQ27XXX Flags */
+#define BQ27XXX_FLAG_DSC	BIT(0)
+#define BQ27XXX_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
+#define BQ27XXX_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
+#define BQ27XXX_FLAG_FC		BIT(9)
+#define BQ27XXX_FLAG_OTD	BIT(14)
+#define BQ27XXX_FLAG_OTC	BIT(15)
+
+/* BQ27000 has different layout for Flags register */
 #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
 #define BQ27000_FLAG_EDV1	BIT(1) /* First End-of-Discharge-Voltage flag */
 #define BQ27000_FLAG_CI		BIT(4) /* Capacity Inaccurate flag */
 #define BQ27000_FLAG_FC		BIT(5)
 #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
 
-#define BQ27500_REG_SOC		0x2C
-#define BQ27500_REG_DCAP	0x3C /* Design capacity */
-#define BQ27500_FLAG_DSC	BIT(0)
-#define BQ27500_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
-#define BQ27500_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
-#define BQ27500_FLAG_FC		BIT(9)
-#define BQ27500_FLAG_OTC	BIT(15)
-
-#define BQ27742_POWER_AVG	0x76
-
-#define BQ27510_REG_SOC		0x20
-#define BQ27510_REG_DCAP	0x2E /* Design capacity */
-#define BQ27510_REG_CYCT	0x1E /* Cycle count total */
-
-/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
-#define BQ27425_REG_OFFSET	0x04
-#define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
-#define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
-
-#define BQ27XXX_RS			20 /* Resistor sense */
-#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
+#define BQ27XXX_RS			(20) /* Resistor sense mOhm */
+#define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
+#define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
 
 struct bq27xxx_device_info;
 struct bq27xxx_access_methods {
 	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
+#define INVALID_REG_ADDR	0xff
+
+/*
+ * bq27xxx_reg_index - Register names
+ *
+ * These are indexes into a device's register mapping array.
+ */
+enum bq27xxx_reg_index {
+	BQ27XXX_REG_CTRL = 0,	/* Control */
+	BQ27XXX_REG_TEMP,	/* Temperature */
+	BQ27XXX_REG_INT_TEMP,	/* Internal Temperature */
+	BQ27XXX_REG_VOLT,	/* Voltage */
+	BQ27XXX_REG_AI,		/* Average Current */
+	BQ27XXX_REG_FLAGS,	/* Flags */
+	BQ27XXX_REG_TTE,	/* Time-to-Empty */
+	BQ27XXX_REG_TTF,	/* Time-to-Full */
+	BQ27XXX_REG_TTES,	/* Time-to-Empty Standby */
+	BQ27XXX_REG_TTECP,	/* Time-to-Empty at Constant Power */
+	BQ27XXX_REG_NAC,	/* Nominal Available Capacity */
+	BQ27XXX_REG_FCC,	/* Full Charge Capacity */
+	BQ27XXX_REG_CYCT,	/* Cycle Count */
+	BQ27XXX_REG_AE,		/* Available Energy */
+	BQ27XXX_REG_SOC,	/* State-of-Charge */
+	BQ27XXX_REG_DCAP,	/* Design Capacity */
+	BQ27XXX_REG_AP,		/* Average Power */
+};
+
 struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
@@ -121,9 +137,152 @@ struct bq27xxx_device_info {
 	struct bq27xxx_access_methods bus;
 
 	struct mutex lock;
+
+	u8 *regs;
+};
+
+/* Register mappings */
+static u8 bq27000_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	INVALID_REG_ADDR,	/* INT TEMP - NA*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	0x18,	/* TTF		*/
+	0x1c,	/* TTES		*/
+	0x26,	/* TTECP	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	0x22,	/* AE		*/
+	0x0b,	/* SOC(RSOC)	*/
+	0x76,	/* DCAP(ILMD)	*/
+	0x24,	/* AP		*/
+};
+
+static u8 bq27010_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	INVALID_REG_ADDR,	/* INT TEMP - NA*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	0x18,	/* TTF		*/
+	0x1c,	/* TTES		*/
+	0x26,	/* TTECP	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x0b,	/* SOC(RSOC)	*/
+	0x76,	/* DCAP(ILMD)	*/
+	INVALID_REG_ADDR,	/* AP - NA	*/
+};
+
+static u8 bq27500_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	0x1a,	/* TTES		*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x1e,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x20,	/* SOC(RSOC)	*/
+	0x2e,	/* DCAP(ILMD)	*/
+	INVALID_REG_ADDR,	/* AP - NA	*/
 };
 
-static enum power_supply_property bq27x00_battery_props[] = {
+static u8 bq27530_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x32,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	INVALID_REG_ADDR,	/* DCAP - NA	*/
+	0x24,	/* AP		*/
+};
+
+static u8 bq27541_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	0x3c,	/* DCAP		*/
+	0x76,	/* AP		*/
+};
+
+static u8 bq27545_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	INVALID_REG_ADDR,	/* DCAP - NA */
+	0x24,	/* AP		*/
+};
+
+static u8 bq27421_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x02,	/* TEMP		*/
+	0x1e,	/* INT TEMP	*/
+	0x04,	/* VOLT		*/
+	0x10,	/* AVG CURR	*/
+	0x06,	/* FLAGS	*/
+	INVALID_REG_ADDR,	/* TTE - NA	*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x08,	/* NAC		*/
+	0x0e,	/* FCC		*/
+	INVALID_REG_ADDR,	/* CYCT - NA	*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x1c,	/* SOC		*/
+	0x3c,	/* DCAP		*/
+	0x18,	/* AP		*/
+};
+
+static enum power_supply_property bq27000_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -145,7 +304,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27425_battery_props[] = {
+static enum power_supply_property bq27010_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -153,14 +312,19 @@ static enum power_supply_property bq27425_battery_props[] = {
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
 	POWER_SUPPLY_PROP_CHARGE_FULL,
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_HEALTH,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27742_battery_props[] = {
+static enum power_supply_property bq27500_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -174,12 +338,29 @@ static enum power_supply_property bq27742_battery_props[] = {
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property bq27530_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510_battery_props[] = {
+static enum power_supply_property bq27541_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -198,6 +379,39 @@ static enum power_supply_property bq27510_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
+static enum power_supply_property bq27545_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_POWER_AVG,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property bq27421_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
 static unsigned int poll_interval = 360;
 module_param(poll_interval, uint, 0644);
 MODULE_PARM_DESC(poll_interval,
@@ -207,25 +421,14 @@ MODULE_PARM_DESC(poll_interval,
  * Common code for BQ27xxx devices
  */
 
-static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
+static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
 			       bool single)
 {
-	if (di->chip == BQ27425)
-		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
-	return di->bus.read(di, reg, single);
-}
+	/* Reports EINVAL for invalid/missing registers */
+	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
+		return -EINVAL;
 
-/*
- * Higher versions of the chip like BQ27425 and BQ27500
- * differ from BQ27000 and BQ27200 in calculation of certain
- * parameters. Hence we need to check for the chip type.
- */
-static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
-{
-	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
-	    || di->chip == BQ27510)
-		return true;
-	return false;
+	return di->bus.read(di, di->regs[reg_index], single);
 }
 
 /*
@@ -236,14 +439,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
 {
 	int soc;
 
-	if (di->chip == BQ27500 || di->chip == BQ27742)
-		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
-	else if (di->chip == BQ27510)
-		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
-	else if (di->chip == BQ27425)
-		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
-	else /* for the bq27000 we read the "relative" SoC register */
-		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
+	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
 
 	if (soc < 0)
 		dev_dbg(di->dev, "error reading State-of-Charge\n");
@@ -266,10 +462,10 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 		return charge;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di))
-		charge *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
 	else
-		charge = charge * 3570 / BQ27XXX_RS;
+		charge *= 1000;
 
 	return charge;
 }
@@ -281,57 +477,46 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
 {
 	int flags;
-	bool is_bq27500 = di->chip == BQ27500;
-	bool is_bq27742 = di->chip == BQ27742;
-	bool is_higher = bq27xxx_is_chip_version_higher(di);
-	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
-	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
-		return -ENODATA;
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
+		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
+			return -ENODATA;
+	}
 
-	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
+	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
 }
 
 /*
- * Return the battery Last measured discharge in µAh
+ * Return the battery Full Charge Capacity in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
+static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di)
 {
-	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
+	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC);
 }
 
 /*
- * Return the battery Initial last measured discharge in µAh
+ * Return the Design Capacity in µAh
  * Or < 0 if something fails.
  */
-static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
+static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
 {
-	int ilmd;
+	int dcap;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->chip == BQ27425)
-			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
-		else if (di->chip == BQ27510)
-			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
-		else
-			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
-	} else {
-		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
-	}
+	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
 
-	if (ilmd < 0) {
+	if (dcap < 0) {
 		dev_dbg(di->dev, "error reading initial last measured discharge\n");
-		return ilmd;
+		return dcap;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di))
-		ilmd *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
 	else
-		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
+		dcap *= 1000;
 
-	return ilmd;
+	return dcap;
 }
 
 /*
@@ -342,16 +527,16 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
 {
 	int ae;
 
-	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
+	ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);
 	if (ae < 0) {
 		dev_dbg(di->dev, "error reading available energy\n");
 		return ae;
 	}
 
-	if (di->chip == BQ27500)
-		ae *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
 	else
-		ae = ae * 29200 / BQ27XXX_RS;
+		ae *= 1000;
 
 	return ae;
 }
@@ -364,13 +549,13 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
 {
 	int temp;
 
-	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
+	temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);
 	if (temp < 0) {
 		dev_err(di->dev, "error reading temperature\n");
 		return temp;
 	}
 
-	if (!bq27xxx_is_chip_version_higher(di))
+	if (di->chip == BQ27000 || di->chip == BQ27010)
 		temp = 5 * temp / 2;
 
 	return temp;
@@ -384,10 +569,7 @@ static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
 {
 	int cyct;
 
-	if (di->chip == BQ27510)
-		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
-	else
-		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
+	cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);
 	if (cyct < 0)
 		dev_err(di->dev, "error reading cycle count total\n");
 
@@ -419,21 +601,32 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
  * Read an average power register.
  * Return < 0 if something fails.
  */
-static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
+static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
 {
 	int tval;
 
-	tval = bq27xxx_read(di, reg, false);
+	tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
 	if (tval < 0) {
-		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
-			reg, tval);
+		dev_err(di->dev, "error reading average power register  %02x: %d\n",
+			BQ27XXX_REG_AP, tval);
 		return tval;
 	}
 
-	if (di->chip == BQ27500)
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+	else
 		return tval;
+}
+
+/*
+ * Returns true if a battery over temperature condition is detected
+ */
+static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27500 || di->chip == BQ27541)
+		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
 	else
-		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+		return flags & BQ27XXX_FLAG_OTC;
 }
 
 /*
@@ -442,53 +635,43 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
  */
 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
-	int tval;
+	u16 tval;
 
-	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
+	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading flag register:%d\n", tval);
 		return tval;
 	}
 
-	if (di->chip == BQ27500) {
-		if (tval & BQ27500_FLAG_SOCF)
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		if (tval & BQ27000_FLAG_EDV1)
 			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else if (tval & BQ27500_FLAG_OTC)
-			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
 		else
 			tval = POWER_SUPPLY_HEALTH_GOOD;
-		return tval;
-	} else if (di->chip == BQ27510) {
-		if (tval & BQ27500_FLAG_OTC)
-			return POWER_SUPPLY_HEALTH_OVERHEAT;
-		return POWER_SUPPLY_HEALTH_GOOD;
 	} else {
-		if (tval & BQ27000_FLAG_EDV1)
+		if (tval & BQ27XXX_FLAG_SOCF)
 			tval = POWER_SUPPLY_HEALTH_DEAD;
+		else if (bq27xxx_battery_overtemp(di, tval))
+			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
 		else
 			tval = POWER_SUPPLY_HEALTH_GOOD;
-		return tval;
 	}
 
-	return -1;
+	return tval;
 }
 
 static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 {
 	struct bq27xxx_reg_cache cache = {0, };
-	bool is_bq27500 = di->chip == BQ27500;
-	bool is_bq27510 = di->chip == BQ27510;
-	bool is_bq27425 = di->chip == BQ27425;
-	bool is_bq27742 = di->chip == BQ27742;
-	bool flags_1b = !(is_bq27500 || is_bq27742);
+	bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
+	bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
 
-	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
 	if ((cache.flags & 0xff) == 0xff)
-		/* read error */
-		cache.flags = -1;
+		cache.flags = -1; /* read error */
 	if (cache.flags >= 0) {
-		if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510
-				&& (cache.flags & BQ27000_FLAG_CI)) {
+		cache.temperature = bq27xxx_battery_read_temperature(di);
+		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
 			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
 			cache.capacity = -ENODATA;
 			cache.energy = -ENODATA;
@@ -498,41 +681,26 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
+			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
+				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
+			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
+				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
+			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
+				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+			cache.charge_full = bq27xxx_battery_read_fcc(di);
 			cache.capacity = bq27xxx_battery_read_soc(di);
-			if (is_bq27742 || is_bq27510)
-				cache.time_to_empty =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTE);
-			else if (!is_bq27425) {
+			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
 				cache.energy = bq27xxx_battery_read_energy(di);
-				cache.time_to_empty =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTE);
-				cache.time_to_empty_avg =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTECP);
-				cache.time_to_full =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTF);
-			}
-			cache.charge_full = bq27xxx_battery_read_lmd(di);
 			cache.health = bq27xxx_battery_read_health(di);
 		}
-		cache.temperature = bq27xxx_battery_read_temperature(di);
-		if (!is_bq27425)
+		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
 			cache.cycle_count = bq27xxx_battery_read_cyct(di);
-		if (is_bq27742)
-			cache.power_avg =
-				bq27xxx_battery_read_pwr_avg(di,
-						BQ27742_POWER_AVG);
-		else
-			cache.power_avg =
-				bq27xxx_battery_read_pwr_avg(di,
-						BQ27x00_POWER_AVG);
+		if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
+			cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
 
 		/* We only have to read charge design full once */
 		if (di->charge_design_full <= 0)
-			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
+			di->charge_design_full = bq27xxx_battery_read_dcap(di);
 	}
 
 	if (di->cache.capacity != cache.capacity)
@@ -547,7 +715,8 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 static void bq27xxx_battery_poll(struct work_struct *work)
 {
 	struct bq27xxx_device_info *di =
-		container_of(work, struct bq27xxx_device_info, work.work);
+			container_of(work, struct bq27xxx_device_info,
+				     work.work);
 
 	bq27xxx_battery_update(di);
 
@@ -569,23 +738,23 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
 	int curr;
 	int flags;
 
-	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
+	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
 	if (curr < 0) {
 		dev_err(di->dev, "error reading current\n");
 		return curr;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		/* bq27500 returns signed value */
-		val->intval = (int)((s16)curr) * 1000;
-	} else {
-		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
 		if (flags & BQ27000_FLAG_CHGS) {
 			dev_dbg(di->dev, "negative current!\n");
 			curr = -curr;
 		}
 
-		val->intval = curr * 3570 / BQ27XXX_RS;
+		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+	} else {
+		/* Other gauges return signed value */
+		val->intval = (int)((s16)curr) * 1000;
 	}
 
 	return 0;
@@ -596,14 +765,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 {
 	int status;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->cache.flags & BQ27500_FLAG_FC)
-			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27500_FLAG_DSC)
-			status = POWER_SUPPLY_STATUS_DISCHARGING;
-		else
-			status = POWER_SUPPLY_STATUS_CHARGING;
-	} else {
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
 		if (di->cache.flags & BQ27000_FLAG_FC)
 			status = POWER_SUPPLY_STATUS_FULL;
 		else if (di->cache.flags & BQ27000_FLAG_CHGS)
@@ -612,6 +774,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 		else
 			status = POWER_SUPPLY_STATUS_DISCHARGING;
+	} else {
+		if (di->cache.flags & BQ27XXX_FLAG_FC)
+			status = POWER_SUPPLY_STATUS_FULL;
+		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
+			status = POWER_SUPPLY_STATUS_DISCHARGING;
+		else
+			status = POWER_SUPPLY_STATUS_CHARGING;
 	}
 
 	val->intval = status;
@@ -624,21 +793,21 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
 {
 	int level;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->cache.flags & BQ27500_FLAG_FC)
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		if (di->cache.flags & BQ27000_FLAG_FC)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
-		else if (di->cache.flags & BQ27500_FLAG_SOC1)
+		else if (di->cache.flags & BQ27000_FLAG_EDV1)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
-		else if (di->cache.flags & BQ27500_FLAG_SOCF)
+		else if (di->cache.flags & BQ27000_FLAG_EDVF)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 		else
 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
 	} else {
-		if (di->cache.flags & BQ27000_FLAG_FC)
+		if (di->cache.flags & BQ27XXX_FLAG_FC)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
-		else if (di->cache.flags & BQ27000_FLAG_EDV1)
+		else if (di->cache.flags & BQ27XXX_FLAG_SOC1)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
-		else if (di->cache.flags & BQ27000_FLAG_EDVF)
+		else if (di->cache.flags & BQ27XXX_FLAG_SOCF)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 		else
 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
@@ -658,7 +827,7 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
 {
 	int volt;
 
-	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
+	volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);
 	if (volt < 0) {
 		dev_err(di->dev, "error reading voltage\n");
 		return volt;
@@ -719,7 +888,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
 	case POWER_SUPPLY_PROP_TEMP:
 		ret = bq27xxx_simple_value(di->cache.temperature, val);
 		if (ret == 0)
-			val->intval -= 2731;
+			val->intval -= 2731; /* convert decidegree k to c */
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
 		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
@@ -785,18 +954,27 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
 
 	psy_desc->name = name;
 	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
-	if (di->chip == BQ27425) {
-		psy_desc->properties = bq27425_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props);
-	} else if (di->chip == BQ27742) {
-		psy_desc->properties = bq27742_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props);
-	} else if (di->chip == BQ27510) {
-		psy_desc->properties = bq27510_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props);
+	if (di->chip == BQ27000) {
+		psy_desc->properties = bq27000_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27000_battery_props);
+	} else if (di->chip == BQ27010) {
+		psy_desc->properties = bq27010_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27010_battery_props);
+	} else if (di->chip == BQ27500) {
+		psy_desc->properties = bq27500_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27500_battery_props);
+	} else if (di->chip == BQ27530) {
+		psy_desc->properties = bq27530_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27530_battery_props);
+	} else if (di->chip == BQ27541) {
+		psy_desc->properties = bq27541_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27541_battery_props);
+	} else if (di->chip == BQ27545) {
+		psy_desc->properties = bq27545_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27545_battery_props);
 	} else {
-		psy_desc->properties = bq27x00_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
+		psy_desc->properties = bq27421_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27421_battery_props);
 	}
 	psy_desc->get_property = bq27xxx_battery_get_property;
 	psy_desc->external_power_changed = bq27xxx_external_power_changed;
@@ -911,10 +1089,32 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 	di->chip = id->driver_data;
 	di->bus.read = &bq27xxx_battery_i2c_read;
 
+	if (di->chip == BQ27000) {
+		di->regs = bq27000_regs;
+	} else if (di->chip == BQ27010) {
+		di->regs = bq27010_regs;
+	} else if (di->chip == BQ27500) {
+		di->regs = bq27500_regs;
+	} else if (di->chip == BQ27530) {
+		di->regs = bq27530_regs;
+	} else if (di->chip == BQ27541) {
+		di->regs = bq27541_regs;
+	} else if (di->chip == BQ27545) {
+		di->regs = bq27545_regs;
+	} else if (di->chip == BQ27421) {
+		di->regs = bq27421_regs;
+	} else {
+		dev_err(&client->dev, "Unexpected gas gauge: %d\n", di->chip);
+		di->regs = bq27000_regs;
+	}
+
 	retval = bq27xxx_powersupply_init(di, name);
 	if (retval)
 		goto batt_failed;
 
+	/* Schedule a polling after about 1 min */
+	schedule_delayed_work(&di->work, 60 * HZ);
+
 	i2c_set_clientdata(client, di);
 
 	return 0;
@@ -941,11 +1141,22 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id bq27xxx_id[] = {
-	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
+	{ "bq27200", BQ27000 },
+	{ "bq27210", BQ27010 },
 	{ "bq27500", BQ27500 },
-	{ "bq27425", BQ27425 },
-	{ "bq27742", BQ27742 },
-	{ "bq27510", BQ27510 },
+	{ "bq27510", BQ27500 },
+	{ "bq27520", BQ27500 },
+	{ "bq27530", BQ27530 },
+	{ "bq27531", BQ27530 },
+	{ "bq27541", BQ27541 },
+	{ "bq27542", BQ27541 },
+	{ "bq27546", BQ27541 },
+	{ "bq27742", BQ27541 },
+	{ "bq27545", BQ27545 },
+	{ "bq27421", BQ27421 },
+	{ "bq27425", BQ27421 },
+	{ "bq27441", BQ27421 },
+	{ "bq27621", BQ27421 },
 	{},
 };
 MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index a4efb10..45f6a7b 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -12,7 +12,15 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
-enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
+enum bq27xxx_chip {
+	BQ27000 = 1, /* bq27000, bq27200 */
+	BQ27010, /* bq27010, bq27210 */
+	BQ27500, /* bq27500, bq27510, bq27520 */
+	BQ27530, /* bq27530, bq27531 */
+	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
+	BQ27545, /* bq27545 */
+	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+};
 
 struct bq27xxx_platform_data {
 	const char *name;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Add support for additional devices and register equivalent family devices
including the bq27010, bq27210, bq27500, bq27510, bq27520, bq27530,
bq27531, bq27541, bq27542, bq27546, bq27545, bq27441, bq27421, and the
bq27641.

To facilitate this process the register mapings have been moved to tables
and other small cleanups have been made.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c       | 627 +++++++++++++++++++++++-----------
 include/linux/power/bq27xxx_battery.h |  10 +-
 2 files changed, 428 insertions(+), 209 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 1ff88ad..3098609 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -17,11 +17,24 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * Datasheets:
- * http://focus.ti.com/docs/prod/folders/print/bq27000.html
- * http://focus.ti.com/docs/prod/folders/print/bq27500.html
+ * http://www.ti.com/product/bq27000
+ * http://www.ti.com/product/bq27200
+ * http://www.ti.com/product/bq27010
+ * http://www.ti.com/product/bq27210
+ * http://www.ti.com/product/bq27500
+ * http://www.ti.com/product/bq27510-g3
+ * http://www.ti.com/product/bq27520-g4
+ * http://www.ti.com/product/bq27530-g1
+ * http://www.ti.com/product/bq27531-g1
+ * http://www.ti.com/product/bq27541-g1
+ * http://www.ti.com/product/bq27542-g1
+ * http://www.ti.com/product/bq27546-g1
+ * http://www.ti.com/product/bq27742-g1
+ * http://www.ti.com/product/bq27545-g1
+ * http://www.ti.com/product/bq27421-g1
  * http://www.ti.com/product/bq27425-g1
- * http://www.ti.com/product/BQ27742-G1
- * http://www.ti.com/product/BQ27510-G3
+ * http://www.ti.com/product/bq27411-g1
+ * http://www.ti.com/product/bq27621-g1
  */
 
 #include <linux/device.h>
@@ -43,54 +56,57 @@
 
 #define BQ27XXX_MANUFACTURER	"Texas Instruments"
 
-#define BQ27x00_REG_TEMP	0x06
-#define BQ27x00_REG_VOLT	0x08
-#define BQ27x00_REG_AI		0x14
-#define BQ27x00_REG_FLAGS	0x0A
-#define BQ27x00_REG_TTE		0x16
-#define BQ27x00_REG_TTF		0x18
-#define BQ27x00_REG_TTECP	0x26
-#define BQ27x00_REG_NAC		0x0C /* Nominal available capacity */
-#define BQ27x00_REG_LMD		0x12 /* Last measured discharge */
-#define BQ27x00_REG_CYCT	0x2A /* Cycle count total */
-#define BQ27x00_REG_AE		0x22 /* Available energy */
-#define BQ27x00_POWER_AVG	0x24
-
-#define BQ27000_REG_RSOC	0x0B /* Relative State-of-Charge */
-#define BQ27000_REG_ILMD	0x76 /* Initial last measured discharge */
+/* BQ27XXX Flags */
+#define BQ27XXX_FLAG_DSC	BIT(0)
+#define BQ27XXX_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
+#define BQ27XXX_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
+#define BQ27XXX_FLAG_FC		BIT(9)
+#define BQ27XXX_FLAG_OTD	BIT(14)
+#define BQ27XXX_FLAG_OTC	BIT(15)
+
+/* BQ27000 has different layout for Flags register */
 #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
 #define BQ27000_FLAG_EDV1	BIT(1) /* First End-of-Discharge-Voltage flag */
 #define BQ27000_FLAG_CI		BIT(4) /* Capacity Inaccurate flag */
 #define BQ27000_FLAG_FC		BIT(5)
 #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
 
-#define BQ27500_REG_SOC		0x2C
-#define BQ27500_REG_DCAP	0x3C /* Design capacity */
-#define BQ27500_FLAG_DSC	BIT(0)
-#define BQ27500_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
-#define BQ27500_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
-#define BQ27500_FLAG_FC		BIT(9)
-#define BQ27500_FLAG_OTC	BIT(15)
-
-#define BQ27742_POWER_AVG	0x76
-
-#define BQ27510_REG_SOC		0x20
-#define BQ27510_REG_DCAP	0x2E /* Design capacity */
-#define BQ27510_REG_CYCT	0x1E /* Cycle count total */
-
-/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
-#define BQ27425_REG_OFFSET	0x04
-#define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
-#define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
-
-#define BQ27XXX_RS			20 /* Resistor sense */
-#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
+#define BQ27XXX_RS			(20) /* Resistor sense mOhm */
+#define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
+#define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
 
 struct bq27xxx_device_info;
 struct bq27xxx_access_methods {
 	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
 };
 
+#define INVALID_REG_ADDR	0xff
+
+/*
+ * bq27xxx_reg_index - Register names
+ *
+ * These are indexes into a device's register mapping array.
+ */
+enum bq27xxx_reg_index {
+	BQ27XXX_REG_CTRL = 0,	/* Control */
+	BQ27XXX_REG_TEMP,	/* Temperature */
+	BQ27XXX_REG_INT_TEMP,	/* Internal Temperature */
+	BQ27XXX_REG_VOLT,	/* Voltage */
+	BQ27XXX_REG_AI,		/* Average Current */
+	BQ27XXX_REG_FLAGS,	/* Flags */
+	BQ27XXX_REG_TTE,	/* Time-to-Empty */
+	BQ27XXX_REG_TTF,	/* Time-to-Full */
+	BQ27XXX_REG_TTES,	/* Time-to-Empty Standby */
+	BQ27XXX_REG_TTECP,	/* Time-to-Empty at Constant Power */
+	BQ27XXX_REG_NAC,	/* Nominal Available Capacity */
+	BQ27XXX_REG_FCC,	/* Full Charge Capacity */
+	BQ27XXX_REG_CYCT,	/* Cycle Count */
+	BQ27XXX_REG_AE,		/* Available Energy */
+	BQ27XXX_REG_SOC,	/* State-of-Charge */
+	BQ27XXX_REG_DCAP,	/* Design Capacity */
+	BQ27XXX_REG_AP,		/* Average Power */
+};
+
 struct bq27xxx_reg_cache {
 	int temperature;
 	int time_to_empty;
@@ -121,9 +137,152 @@ struct bq27xxx_device_info {
 	struct bq27xxx_access_methods bus;
 
 	struct mutex lock;
+
+	u8 *regs;
+};
+
+/* Register mappings */
+static u8 bq27000_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	INVALID_REG_ADDR,	/* INT TEMP - NA*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	0x18,	/* TTF		*/
+	0x1c,	/* TTES		*/
+	0x26,	/* TTECP	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	0x22,	/* AE		*/
+	0x0b,	/* SOC(RSOC)	*/
+	0x76,	/* DCAP(ILMD)	*/
+	0x24,	/* AP		*/
+};
+
+static u8 bq27010_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	INVALID_REG_ADDR,	/* INT TEMP - NA*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	0x18,	/* TTF		*/
+	0x1c,	/* TTES		*/
+	0x26,	/* TTECP	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x0b,	/* SOC(RSOC)	*/
+	0x76,	/* DCAP(ILMD)	*/
+	INVALID_REG_ADDR,	/* AP - NA	*/
+};
+
+static u8 bq27500_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	0x1a,	/* TTES		*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x1e,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x20,	/* SOC(RSOC)	*/
+	0x2e,	/* DCAP(ILMD)	*/
+	INVALID_REG_ADDR,	/* AP - NA	*/
 };
 
-static enum power_supply_property bq27x00_battery_props[] = {
+static u8 bq27530_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x32,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	INVALID_REG_ADDR,	/* DCAP - NA	*/
+	0x24,	/* AP		*/
+};
+
+static u8 bq27541_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	0x3c,	/* DCAP		*/
+	0x76,	/* AP		*/
+};
+
+static u8 bq27545_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x06,	/* TEMP		*/
+	0x28,	/* INT TEMP	*/
+	0x08,	/* VOLT		*/
+	0x14,	/* AVG CURR	*/
+	0x0a,	/* FLAGS	*/
+	0x16,	/* TTE		*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x0c,	/* NAC		*/
+	0x12,	/* LMD(FCC)	*/
+	0x2a,	/* CYCT		*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x2c,	/* SOC(RSOC)	*/
+	INVALID_REG_ADDR,	/* DCAP - NA */
+	0x24,	/* AP		*/
+};
+
+static u8 bq27421_regs[] = {
+	0x00,	/* CONTROL	*/
+	0x02,	/* TEMP		*/
+	0x1e,	/* INT TEMP	*/
+	0x04,	/* VOLT		*/
+	0x10,	/* AVG CURR	*/
+	0x06,	/* FLAGS	*/
+	INVALID_REG_ADDR,	/* TTE - NA	*/
+	INVALID_REG_ADDR,	/* TTF - NA	*/
+	INVALID_REG_ADDR,	/* TTES - NA	*/
+	INVALID_REG_ADDR,	/* TTECP - NA	*/
+	0x08,	/* NAC		*/
+	0x0e,	/* FCC		*/
+	INVALID_REG_ADDR,	/* CYCT - NA	*/
+	INVALID_REG_ADDR,	/* AE - NA	*/
+	0x1c,	/* SOC		*/
+	0x3c,	/* DCAP		*/
+	0x18,	/* AP		*/
+};
+
+static enum power_supply_property bq27000_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -145,7 +304,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27425_battery_props[] = {
+static enum power_supply_property bq27010_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -153,14 +312,19 @@ static enum power_supply_property bq27425_battery_props[] = {
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
 	POWER_SUPPLY_PROP_CHARGE_FULL,
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_HEALTH,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27742_battery_props[] = {
+static enum power_supply_property bq27500_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -174,12 +338,29 @@ static enum power_supply_property bq27742_battery_props[] = {
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property bq27530_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510_battery_props[] = {
+static enum power_supply_property bq27541_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -198,6 +379,39 @@ static enum power_supply_property bq27510_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
+static enum power_supply_property bq27545_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_POWER_AVG,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property bq27421_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
 static unsigned int poll_interval = 360;
 module_param(poll_interval, uint, 0644);
 MODULE_PARM_DESC(poll_interval,
@@ -207,25 +421,14 @@ MODULE_PARM_DESC(poll_interval,
  * Common code for BQ27xxx devices
  */
 
-static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
+static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
 			       bool single)
 {
-	if (di->chip == BQ27425)
-		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
-	return di->bus.read(di, reg, single);
-}
+	/* Reports EINVAL for invalid/missing registers */
+	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
+		return -EINVAL;
 
-/*
- * Higher versions of the chip like BQ27425 and BQ27500
- * differ from BQ27000 and BQ27200 in calculation of certain
- * parameters. Hence we need to check for the chip type.
- */
-static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
-{
-	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
-	    || di->chip == BQ27510)
-		return true;
-	return false;
+	return di->bus.read(di, di->regs[reg_index], single);
 }
 
 /*
@@ -236,14 +439,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
 {
 	int soc;
 
-	if (di->chip == BQ27500 || di->chip == BQ27742)
-		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
-	else if (di->chip == BQ27510)
-		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
-	else if (di->chip == BQ27425)
-		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
-	else /* for the bq27000 we read the "relative" SoC register */
-		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
+	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
 
 	if (soc < 0)
 		dev_dbg(di->dev, "error reading State-of-Charge\n");
@@ -266,10 +462,10 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 		return charge;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di))
-		charge *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
 	else
-		charge = charge * 3570 / BQ27XXX_RS;
+		charge *= 1000;
 
 	return charge;
 }
@@ -281,57 +477,46 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
 {
 	int flags;
-	bool is_bq27500 = di->chip == BQ27500;
-	bool is_bq27742 = di->chip == BQ27742;
-	bool is_higher = bq27xxx_is_chip_version_higher(di);
-	bool flags_1b = !(is_bq27500 || is_bq27742);
 
-	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
-	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
-		return -ENODATA;
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
+		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
+			return -ENODATA;
+	}
 
-	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
+	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
 }
 
 /*
- * Return the battery Last measured discharge in µAh
+ * Return the battery Full Charge Capacity in µAh
  * Or < 0 if something fails.
  */
-static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
+static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di)
 {
-	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
+	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC);
 }
 
 /*
- * Return the battery Initial last measured discharge in µAh
+ * Return the Design Capacity in µAh
  * Or < 0 if something fails.
  */
-static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
+static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
 {
-	int ilmd;
+	int dcap;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->chip == BQ27425)
-			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
-		else if (di->chip == BQ27510)
-			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
-		else
-			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
-	} else {
-		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
-	}
+	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
 
-	if (ilmd < 0) {
+	if (dcap < 0) {
 		dev_dbg(di->dev, "error reading initial last measured discharge\n");
-		return ilmd;
+		return dcap;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di))
-		ilmd *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
 	else
-		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
+		dcap *= 1000;
 
-	return ilmd;
+	return dcap;
 }
 
 /*
@@ -342,16 +527,16 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
 {
 	int ae;
 
-	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
+	ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);
 	if (ae < 0) {
 		dev_dbg(di->dev, "error reading available energy\n");
 		return ae;
 	}
 
-	if (di->chip == BQ27500)
-		ae *= 1000;
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
 	else
-		ae = ae * 29200 / BQ27XXX_RS;
+		ae *= 1000;
 
 	return ae;
 }
@@ -364,13 +549,13 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
 {
 	int temp;
 
-	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
+	temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);
 	if (temp < 0) {
 		dev_err(di->dev, "error reading temperature\n");
 		return temp;
 	}
 
-	if (!bq27xxx_is_chip_version_higher(di))
+	if (di->chip == BQ27000 || di->chip == BQ27010)
 		temp = 5 * temp / 2;
 
 	return temp;
@@ -384,10 +569,7 @@ static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
 {
 	int cyct;
 
-	if (di->chip == BQ27510)
-		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
-	else
-		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
+	cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);
 	if (cyct < 0)
 		dev_err(di->dev, "error reading cycle count total\n");
 
@@ -419,21 +601,32 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
  * Read an average power register.
  * Return < 0 if something fails.
  */
-static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
+static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
 {
 	int tval;
 
-	tval = bq27xxx_read(di, reg, false);
+	tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
 	if (tval < 0) {
-		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
-			reg, tval);
+		dev_err(di->dev, "error reading average power register  %02x: %d\n",
+			BQ27XXX_REG_AP, tval);
 		return tval;
 	}
 
-	if (di->chip == BQ27500)
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+	else
 		return tval;
+}
+
+/*
+ * Returns true if a battery over temperature condition is detected
+ */
+static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27500 || di->chip == BQ27541)
+		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
 	else
-		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+		return flags & BQ27XXX_FLAG_OTC;
 }
 
 /*
@@ -442,53 +635,43 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
  */
 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
-	int tval;
+	u16 tval;
 
-	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
+	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
 	if (tval < 0) {
 		dev_err(di->dev, "error reading flag register:%d\n", tval);
 		return tval;
 	}
 
-	if (di->chip == BQ27500) {
-		if (tval & BQ27500_FLAG_SOCF)
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		if (tval & BQ27000_FLAG_EDV1)
 			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else if (tval & BQ27500_FLAG_OTC)
-			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
 		else
 			tval = POWER_SUPPLY_HEALTH_GOOD;
-		return tval;
-	} else if (di->chip == BQ27510) {
-		if (tval & BQ27500_FLAG_OTC)
-			return POWER_SUPPLY_HEALTH_OVERHEAT;
-		return POWER_SUPPLY_HEALTH_GOOD;
 	} else {
-		if (tval & BQ27000_FLAG_EDV1)
+		if (tval & BQ27XXX_FLAG_SOCF)
 			tval = POWER_SUPPLY_HEALTH_DEAD;
+		else if (bq27xxx_battery_overtemp(di, tval))
+			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
 		else
 			tval = POWER_SUPPLY_HEALTH_GOOD;
-		return tval;
 	}
 
-	return -1;
+	return tval;
 }
 
 static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 {
 	struct bq27xxx_reg_cache cache = {0, };
-	bool is_bq27500 = di->chip == BQ27500;
-	bool is_bq27510 = di->chip == BQ27510;
-	bool is_bq27425 = di->chip == BQ27425;
-	bool is_bq27742 = di->chip == BQ27742;
-	bool flags_1b = !(is_bq27500 || is_bq27742);
+	bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
+	bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
 
-	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
+	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
 	if ((cache.flags & 0xff) == 0xff)
-		/* read error */
-		cache.flags = -1;
+		cache.flags = -1; /* read error */
 	if (cache.flags >= 0) {
-		if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510
-				&& (cache.flags & BQ27000_FLAG_CI)) {
+		cache.temperature = bq27xxx_battery_read_temperature(di);
+		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
 			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
 			cache.capacity = -ENODATA;
 			cache.energy = -ENODATA;
@@ -498,41 +681,26 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 			cache.charge_full = -ENODATA;
 			cache.health = -ENODATA;
 		} else {
+			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
+				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
+			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
+				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
+			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
+				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+			cache.charge_full = bq27xxx_battery_read_fcc(di);
 			cache.capacity = bq27xxx_battery_read_soc(di);
-			if (is_bq27742 || is_bq27510)
-				cache.time_to_empty =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTE);
-			else if (!is_bq27425) {
+			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
 				cache.energy = bq27xxx_battery_read_energy(di);
-				cache.time_to_empty =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTE);
-				cache.time_to_empty_avg =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTECP);
-				cache.time_to_full =
-					bq27xxx_battery_read_time(di,
-							BQ27x00_REG_TTF);
-			}
-			cache.charge_full = bq27xxx_battery_read_lmd(di);
 			cache.health = bq27xxx_battery_read_health(di);
 		}
-		cache.temperature = bq27xxx_battery_read_temperature(di);
-		if (!is_bq27425)
+		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
 			cache.cycle_count = bq27xxx_battery_read_cyct(di);
-		if (is_bq27742)
-			cache.power_avg =
-				bq27xxx_battery_read_pwr_avg(di,
-						BQ27742_POWER_AVG);
-		else
-			cache.power_avg =
-				bq27xxx_battery_read_pwr_avg(di,
-						BQ27x00_POWER_AVG);
+		if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
+			cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
 
 		/* We only have to read charge design full once */
 		if (di->charge_design_full <= 0)
-			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
+			di->charge_design_full = bq27xxx_battery_read_dcap(di);
 	}
 
 	if (di->cache.capacity != cache.capacity)
@@ -547,7 +715,8 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 static void bq27xxx_battery_poll(struct work_struct *work)
 {
 	struct bq27xxx_device_info *di =
-		container_of(work, struct bq27xxx_device_info, work.work);
+			container_of(work, struct bq27xxx_device_info,
+				     work.work);
 
 	bq27xxx_battery_update(di);
 
@@ -569,23 +738,23 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
 	int curr;
 	int flags;
 
-	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
+	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
 	if (curr < 0) {
 		dev_err(di->dev, "error reading current\n");
 		return curr;
 	}
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		/* bq27500 returns signed value */
-		val->intval = (int)((s16)curr) * 1000;
-	} else {
-		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
 		if (flags & BQ27000_FLAG_CHGS) {
 			dev_dbg(di->dev, "negative current!\n");
 			curr = -curr;
 		}
 
-		val->intval = curr * 3570 / BQ27XXX_RS;
+		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+	} else {
+		/* Other gauges return signed value */
+		val->intval = (int)((s16)curr) * 1000;
 	}
 
 	return 0;
@@ -596,14 +765,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 {
 	int status;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->cache.flags & BQ27500_FLAG_FC)
-			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27500_FLAG_DSC)
-			status = POWER_SUPPLY_STATUS_DISCHARGING;
-		else
-			status = POWER_SUPPLY_STATUS_CHARGING;
-	} else {
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
 		if (di->cache.flags & BQ27000_FLAG_FC)
 			status = POWER_SUPPLY_STATUS_FULL;
 		else if (di->cache.flags & BQ27000_FLAG_CHGS)
@@ -612,6 +774,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 		else
 			status = POWER_SUPPLY_STATUS_DISCHARGING;
+	} else {
+		if (di->cache.flags & BQ27XXX_FLAG_FC)
+			status = POWER_SUPPLY_STATUS_FULL;
+		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
+			status = POWER_SUPPLY_STATUS_DISCHARGING;
+		else
+			status = POWER_SUPPLY_STATUS_CHARGING;
 	}
 
 	val->intval = status;
@@ -624,21 +793,21 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
 {
 	int level;
 
-	if (bq27xxx_is_chip_version_higher(di)) {
-		if (di->cache.flags & BQ27500_FLAG_FC)
+	if (di->chip == BQ27000 || di->chip == BQ27010) {
+		if (di->cache.flags & BQ27000_FLAG_FC)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
-		else if (di->cache.flags & BQ27500_FLAG_SOC1)
+		else if (di->cache.flags & BQ27000_FLAG_EDV1)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
-		else if (di->cache.flags & BQ27500_FLAG_SOCF)
+		else if (di->cache.flags & BQ27000_FLAG_EDVF)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 		else
 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
 	} else {
-		if (di->cache.flags & BQ27000_FLAG_FC)
+		if (di->cache.flags & BQ27XXX_FLAG_FC)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
-		else if (di->cache.flags & BQ27000_FLAG_EDV1)
+		else if (di->cache.flags & BQ27XXX_FLAG_SOC1)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
-		else if (di->cache.flags & BQ27000_FLAG_EDVF)
+		else if (di->cache.flags & BQ27XXX_FLAG_SOCF)
 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 		else
 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
@@ -658,7 +827,7 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
 {
 	int volt;
 
-	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
+	volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);
 	if (volt < 0) {
 		dev_err(di->dev, "error reading voltage\n");
 		return volt;
@@ -719,7 +888,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
 	case POWER_SUPPLY_PROP_TEMP:
 		ret = bq27xxx_simple_value(di->cache.temperature, val);
 		if (ret == 0)
-			val->intval -= 2731;
+			val->intval -= 2731; /* convert decidegree k to c */
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
 		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
@@ -785,18 +954,27 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
 
 	psy_desc->name = name;
 	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
-	if (di->chip == BQ27425) {
-		psy_desc->properties = bq27425_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props);
-	} else if (di->chip == BQ27742) {
-		psy_desc->properties = bq27742_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props);
-	} else if (di->chip == BQ27510) {
-		psy_desc->properties = bq27510_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props);
+	if (di->chip == BQ27000) {
+		psy_desc->properties = bq27000_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27000_battery_props);
+	} else if (di->chip == BQ27010) {
+		psy_desc->properties = bq27010_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27010_battery_props);
+	} else if (di->chip == BQ27500) {
+		psy_desc->properties = bq27500_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27500_battery_props);
+	} else if (di->chip == BQ27530) {
+		psy_desc->properties = bq27530_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27530_battery_props);
+	} else if (di->chip == BQ27541) {
+		psy_desc->properties = bq27541_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27541_battery_props);
+	} else if (di->chip == BQ27545) {
+		psy_desc->properties = bq27545_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27545_battery_props);
 	} else {
-		psy_desc->properties = bq27x00_battery_props;
-		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
+		psy_desc->properties = bq27421_battery_props;
+		psy_desc->num_properties = ARRAY_SIZE(bq27421_battery_props);
 	}
 	psy_desc->get_property = bq27xxx_battery_get_property;
 	psy_desc->external_power_changed = bq27xxx_external_power_changed;
@@ -911,10 +1089,32 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 	di->chip = id->driver_data;
 	di->bus.read = &bq27xxx_battery_i2c_read;
 
+	if (di->chip == BQ27000) {
+		di->regs = bq27000_regs;
+	} else if (di->chip == BQ27010) {
+		di->regs = bq27010_regs;
+	} else if (di->chip == BQ27500) {
+		di->regs = bq27500_regs;
+	} else if (di->chip == BQ27530) {
+		di->regs = bq27530_regs;
+	} else if (di->chip == BQ27541) {
+		di->regs = bq27541_regs;
+	} else if (di->chip == BQ27545) {
+		di->regs = bq27545_regs;
+	} else if (di->chip == BQ27421) {
+		di->regs = bq27421_regs;
+	} else {
+		dev_err(&client->dev, "Unexpected gas gauge: %d\n", di->chip);
+		di->regs = bq27000_regs;
+	}
+
 	retval = bq27xxx_powersupply_init(di, name);
 	if (retval)
 		goto batt_failed;
 
+	/* Schedule a polling after about 1 min */
+	schedule_delayed_work(&di->work, 60 * HZ);
+
 	i2c_set_clientdata(client, di);
 
 	return 0;
@@ -941,11 +1141,22 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id bq27xxx_id[] = {
-	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
+	{ "bq27200", BQ27000 },
+	{ "bq27210", BQ27010 },
 	{ "bq27500", BQ27500 },
-	{ "bq27425", BQ27425 },
-	{ "bq27742", BQ27742 },
-	{ "bq27510", BQ27510 },
+	{ "bq27510", BQ27500 },
+	{ "bq27520", BQ27500 },
+	{ "bq27530", BQ27530 },
+	{ "bq27531", BQ27530 },
+	{ "bq27541", BQ27541 },
+	{ "bq27542", BQ27541 },
+	{ "bq27546", BQ27541 },
+	{ "bq27742", BQ27541 },
+	{ "bq27545", BQ27545 },
+	{ "bq27421", BQ27421 },
+	{ "bq27425", BQ27421 },
+	{ "bq27441", BQ27421 },
+	{ "bq27621", BQ27421 },
 	{},
 };
 MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index a4efb10..45f6a7b 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -12,7 +12,15 @@
  *	register to be read. The return value should either be the content of
  *	the passed register or an error value.
  */
-enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
+enum bq27xxx_chip {
+	BQ27000 = 1, /* bq27000, bq27200 */
+	BQ27010, /* bq27010, bq27210 */
+	BQ27500, /* bq27500, bq27510, bq27520 */
+	BQ27530, /* bq27530, bq27531 */
+	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
+	BQ27545, /* bq27545 */
+	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+};
 
 struct bq27xxx_platform_data {
 	const char *name;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 6/7] power: bq27xxx_battery: Cleanup health checking
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Reorganize the logic checking battery health and add under temperature
condition checking.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 64 +++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 3098609..10be8a6 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -63,6 +63,8 @@
 #define BQ27XXX_FLAG_FC		BIT(9)
 #define BQ27XXX_FLAG_OTD	BIT(14)
 #define BQ27XXX_FLAG_OTC	BIT(15)
+#define BQ27XXX_FLAG_UT		BIT(14)
+#define BQ27XXX_FLAG_OT		BIT(15)
 
 /* BQ27000 has different layout for Flags register */
 #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
@@ -621,12 +623,36 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
 /*
  * Returns true if a battery over temperature condition is detected
  */
-static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
+static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
 {
-	if (di->chip == BQ27500 || di->chip == BQ27541)
+	if (di->chip == BQ27500 || di->chip == BQ27541 || di->chip == BQ27545)
 		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
+	if (di->chip == BQ27530 || di->chip == BQ27421)
+		return flags & BQ27XXX_FLAG_OT;
+
+	return false;
+}
+
+/*
+ * Returns true if a battery under temperature condition is detected
+ */
+static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27530 || di->chip == BQ27421)
+		return flags & BQ27XXX_FLAG_UT;
+
+	return false;
+}
+
+/*
+ * Returns true if a low state of charge condition is detected
+ */
+static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
 	else
-		return flags & BQ27XXX_FLAG_OTC;
+		return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
 }
 
 /*
@@ -635,29 +661,23 @@ static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
  */
 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
-	u16 tval;
+	u16 flags;
 
-	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
-	if (tval < 0) {
-		dev_err(di->dev, "error reading flag register:%d\n", tval);
-		return tval;
+	flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
+	if (flags < 0) {
+		dev_err(di->dev, "error reading flag register:%d\n", flags);
+		return flags;
 	}
 
-	if (di->chip == BQ27000 || di->chip == BQ27010) {
-		if (tval & BQ27000_FLAG_EDV1)
-			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else
-			tval = POWER_SUPPLY_HEALTH_GOOD;
-	} else {
-		if (tval & BQ27XXX_FLAG_SOCF)
-			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else if (bq27xxx_battery_overtemp(di, tval))
-			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
-		else
-			tval = POWER_SUPPLY_HEALTH_GOOD;
-	}
+	/* Unlikely but important to return first */
+	if (unlikely(bq27xxx_battery_overtemp(di, flags)))
+		return POWER_SUPPLY_HEALTH_OVERHEAT;
+	if (unlikely(bq27xxx_battery_undertemp(di, flags)))
+		return POWER_SUPPLY_HEALTH_COLD;
+	if (unlikely(bq27xxx_battery_dead(di, flags)))
+		return POWER_SUPPLY_HEALTH_DEAD;
 
-	return tval;
+	return POWER_SUPPLY_HEALTH_GOOD;
 }
 
 static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 6/7] power: bq27xxx_battery: Cleanup health checking
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Reorganize the logic checking battery health and add under temperature
condition checking.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 64 +++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 3098609..10be8a6 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -63,6 +63,8 @@
 #define BQ27XXX_FLAG_FC		BIT(9)
 #define BQ27XXX_FLAG_OTD	BIT(14)
 #define BQ27XXX_FLAG_OTC	BIT(15)
+#define BQ27XXX_FLAG_UT		BIT(14)
+#define BQ27XXX_FLAG_OT		BIT(15)
 
 /* BQ27000 has different layout for Flags register */
 #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
@@ -621,12 +623,36 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
 /*
  * Returns true if a battery over temperature condition is detected
  */
-static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
+static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
 {
-	if (di->chip == BQ27500 || di->chip == BQ27541)
+	if (di->chip == BQ27500 || di->chip == BQ27541 || di->chip == BQ27545)
 		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
+	if (di->chip == BQ27530 || di->chip == BQ27421)
+		return flags & BQ27XXX_FLAG_OT;
+
+	return false;
+}
+
+/*
+ * Returns true if a battery under temperature condition is detected
+ */
+static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27530 || di->chip == BQ27421)
+		return flags & BQ27XXX_FLAG_UT;
+
+	return false;
+}
+
+/*
+ * Returns true if a low state of charge condition is detected
+ */
+static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
+{
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
 	else
-		return flags & BQ27XXX_FLAG_OTC;
+		return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
 }
 
 /*
@@ -635,29 +661,23 @@ static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
  */
 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
 {
-	u16 tval;
+	u16 flags;
 
-	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
-	if (tval < 0) {
-		dev_err(di->dev, "error reading flag register:%d\n", tval);
-		return tval;
+	flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
+	if (flags < 0) {
+		dev_err(di->dev, "error reading flag register:%d\n", flags);
+		return flags;
 	}
 
-	if (di->chip == BQ27000 || di->chip == BQ27010) {
-		if (tval & BQ27000_FLAG_EDV1)
-			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else
-			tval = POWER_SUPPLY_HEALTH_GOOD;
-	} else {
-		if (tval & BQ27XXX_FLAG_SOCF)
-			tval = POWER_SUPPLY_HEALTH_DEAD;
-		else if (bq27xxx_battery_overtemp(di, tval))
-			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
-		else
-			tval = POWER_SUPPLY_HEALTH_GOOD;
-	}
+	/* Unlikely but important to return first */
+	if (unlikely(bq27xxx_battery_overtemp(di, flags)))
+		return POWER_SUPPLY_HEALTH_OVERHEAT;
+	if (unlikely(bq27xxx_battery_undertemp(di, flags)))
+		return POWER_SUPPLY_HEALTH_COLD;
+	if (unlikely(bq27xxx_battery_dead(di, flags)))
+		return POWER_SUPPLY_HEALTH_DEAD;
 
-	return tval;
+	return POWER_SUPPLY_HEALTH_GOOD;
 }
 
 static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 7/7] power: bq27xxx_battery: Add interrupt handling support
  2015-09-14 21:26 ` Andrew F. Davis
@ 2015-09-14 21:26   ` Andrew F. Davis
  -1 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Some devices have a pin that can generate an interrupt when
the battery's status changes. Add an interrupt handler to
read the new battery status.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 10be8a6..29fdcd7 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -48,6 +48,7 @@
 #include <linux/idr.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <asm/unaligned.h>
 
 #include <linux/power/bq27xxx_battery.h>
@@ -732,6 +733,15 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 	di->last_update = jiffies;
 }
 
+static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
+{
+	struct bq27xxx_device_info *di = data;
+
+	bq27xxx_battery_update(di);
+
+	return IRQ_HANDLED;
+}
+
 static void bq27xxx_battery_poll(struct work_struct *work)
 {
 	struct bq27xxx_device_info *di =
@@ -1137,6 +1147,19 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, di);
 
+	if (client->irq) {
+		retval = devm_request_threaded_irq(&client->dev, client->irq,
+				NULL, bq27xxx_battery_irq_handler_thread,
+				IRQF_ONESHOT,
+				name, di);
+		if (retval) {
+			dev_err(&client->dev,
+				"Unable to register IRQ %d error %d\n",
+				client->irq, retval);
+			return retval;
+		}
+	}
+
 	return 0;
 
 batt_failed:
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 7/7] power: bq27xxx_battery: Add interrupt handling support
@ 2015-09-14 21:26   ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-14 21:26 UTC (permalink / raw)
  To: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse
  Cc: Dan Murphy, linux-pm, linux-kernel, Andrew F. Davis

Some devices have a pin that can generate an interrupt when
the battery's status changes. Add an interrupt handler to
read the new battery status.

Signed-off-by: Andrew F. Davis <afd@ti.com>
---
 drivers/power/bq27xxx_battery.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 10be8a6..29fdcd7 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -48,6 +48,7 @@
 #include <linux/idr.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <asm/unaligned.h>
 
 #include <linux/power/bq27xxx_battery.h>
@@ -732,6 +733,15 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
 	di->last_update = jiffies;
 }
 
+static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
+{
+	struct bq27xxx_device_info *di = data;
+
+	bq27xxx_battery_update(di);
+
+	return IRQ_HANDLED;
+}
+
 static void bq27xxx_battery_poll(struct work_struct *work)
 {
 	struct bq27xxx_device_info *di =
@@ -1137,6 +1147,19 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, di);
 
+	if (client->irq) {
+		retval = devm_request_threaded_irq(&client->dev, client->irq,
+				NULL, bq27xxx_battery_irq_handler_thread,
+				IRQF_ONESHOT,
+				name, di);
+		if (retval) {
+			dev_err(&client->dev,
+				"Unable to register IRQ %d error %d\n",
+				client->irq, retval);
+			return retval;
+		}
+	}
+
 	return 0;
 
 batt_failed:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-15  8:32   ` Laurentiu Palcu
  2015-09-15 16:53     ` Andrew F. Davis
  -1 siblings, 1 reply; 31+ messages in thread
From: Laurentiu Palcu @ 2015-09-15  8:32 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse, Dan Murphy, linux-pm, linux-kernel

On Mon, Sep 14, 2015 at 04:26:08PM -0500, Andrew F. Davis wrote:
> Rename functions that are used by multiple devices. New devices
> have been added and the function names and driver name are no longer
> general enough for the functionality they provide.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  MAINTAINERS                                        |   4 +-
>  arch/arm/configs/omap2plus_defconfig               |   2 +-
>  arch/unicore32/Kconfig                             |   2 +-
>  drivers/power/Kconfig                              |  22 +-
>  drivers/power/Makefile                             |   2 +-
>  .../power/{bq27x00_battery.c => bq27xxx_battery.c} | 333 +++++++++++----------

1000 chips! That's how many potential chips is this driver supposed to
support, after the rename, with little or no modifications. Is it even
possible to guarantee that all future chips, starting with 'bq27' in
their naming scheme, are register compatible?

Call me conservative, but when I see driver names/renames containing
wildcards, I get chills down my spine. I can probably get over single
digit wildcards but 3 digit wildcards is a little too much. :)

I can't help but wonder what will one have to do if one single newly
released bq27xxx chip is completely different... :/

laurentiu



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency
  2015-09-15  8:32   ` Laurentiu Palcu
@ 2015-09-15 16:53     ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-15 16:53 UTC (permalink / raw)
  To: Laurentiu Palcu
  Cc: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse, Dan Murphy, linux-pm, linux-kernel

On 09/15/2015 03:32 AM, Laurentiu Palcu wrote:
> On Mon, Sep 14, 2015 at 04:26:08PM -0500, Andrew F. Davis wrote:
>> Rename functions that are used by multiple devices. New devices
>> have been added and the function names and driver name are no longer
>> general enough for the functionality they provide.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   MAINTAINERS                                        |   4 +-
>>   arch/arm/configs/omap2plus_defconfig               |   2 +-
>>   arch/unicore32/Kconfig                             |   2 +-
>>   drivers/power/Kconfig                              |  22 +-
>>   drivers/power/Makefile                             |   2 +-
>>   .../power/{bq27x00_battery.c => bq27xxx_battery.c} | 333 +++++++++++----------
>
> 1000 chips! That's how many potential chips is this driver supposed to
> support, after the rename, with little or no modifications.Is it even
> possible to guarantee that all future chips, starting with 'bq27' in
> their naming scheme, are register compatible?
>  

After this series we support three times as many chips, and almost none
of them follow the 27x00 naming (only the bq27000 and bq27200 ever did).

Also almost *none* of the new chips added are register compatible, that's
why this series moves register mapping to a table, but they all perform the
same task (fuel gauging) in almost the same way so it works well.

> Call me conservative, but when I see driver names/renames containing
> wildcards, I get chills down my spine. I can probably get over single
> digit wildcards but 3 digit wildcards is a little too much. :)
>

Perhaps just bq27x :)

> I can't help but wonder what will one have to do if one single newly
> released bq27xxx chip is completely different... :/
>

If someday they make a part that is so different it doesn't fit in this
driver then it can be the oddball with its own named driver file.

Regards,
Andrew

> laurentiu
>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 7/7] power: bq27xxx_battery: Add interrupt handling support
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-15 18:47   ` Andreas Dannenberg
  2015-09-15 20:53     ` Andrew F. Davis
  -1 siblings, 1 reply; 31+ messages in thread
From: Andreas Dannenberg @ 2015-09-15 18:47 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse, Dan Murphy, linux-pm, linux-kernel

On Mon, Sep 14, 2015 at 04:26:13PM -0500, Andrew F. Davis wrote:
> Some devices have a pin that can generate an interrupt when
> the battery's status changes. Add an interrupt handler to
> read the new battery status.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/power/bq27xxx_battery.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
> index 10be8a6..29fdcd7 100644
> --- a/drivers/power/bq27xxx_battery.c
> +++ b/drivers/power/bq27xxx_battery.c
> @@ -48,6 +48,7 @@
>  #include <linux/idr.h>
>  #include <linux/i2c.h>
>  #include <linux/slab.h>
> +#include <linux/interrupt.h>
>  #include <asm/unaligned.h>
>  
>  #include <linux/power/bq27xxx_battery.h>
> @@ -732,6 +733,15 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>  	di->last_update = jiffies;
>  }
>  
> +static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
> +{
> +	struct bq27xxx_device_info *di = data;
> +
> +	bq27xxx_battery_update(di);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static void bq27xxx_battery_poll(struct work_struct *work)
>  {
>  	struct bq27xxx_device_info *di =
> @@ -1137,6 +1147,19 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
>  
>  	i2c_set_clientdata(client, di);
>  
> +	if (client->irq) {
> +		retval = devm_request_threaded_irq(&client->dev, client->irq,
> +				NULL, bq27xxx_battery_irq_handler_thread,
> +				IRQF_ONESHOT,
> +				name, di);

Hi Andrew,
I think it'll be better if you explicitly specify the rising vs. falling
edge interrupt flags according to exactly what the bq27xxx will trigger
on to ensure the corresponding GPIO module is always configured properly.

While we are at it, was the platform-data based initialization in
conjunction with interrupts tested?

Regards,

--
Andreas Dannenberg
Texas Instruments Inc


> +		if (retval) {
> +			dev_err(&client->dev,
> +				"Unable to register IRQ %d error %d\n",
> +				client->irq, retval);
> +			return retval;
> +		}
> +	}
> +
>  	return 0;
>  
>  batt_failed:
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 7/7] power: bq27xxx_battery: Add interrupt handling support
  2015-09-15 18:47   ` Andreas Dannenberg
@ 2015-09-15 20:53     ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-15 20:53 UTC (permalink / raw)
  To: Andreas Dannenberg
  Cc: Pali Rohár, Sebastian Reichel, Dmitry Eremin-Solenikov,
	David Woodhouse, Dan Murphy, linux-pm, linux-kernel

On 09/15/2015 01:47 PM, Andreas Dannenberg wrote:
> On Mon, Sep 14, 2015 at 04:26:13PM -0500, Andrew F. Davis wrote:
>> Some devices have a pin that can generate an interrupt when
>> the battery's status changes. Add an interrupt handler to
>> read the new battery status.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/power/bq27xxx_battery.c | 23 +++++++++++++++++++++++
>>   1 file changed, 23 insertions(+)
>>
>> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
>> index 10be8a6..29fdcd7 100644
>> --- a/drivers/power/bq27xxx_battery.c
>> +++ b/drivers/power/bq27xxx_battery.c
>> @@ -48,6 +48,7 @@
>>   #include <linux/idr.h>
>>   #include <linux/i2c.h>
>>   #include <linux/slab.h>
>> +#include <linux/interrupt.h>
>>   #include <asm/unaligned.h>
>>
>>   #include <linux/power/bq27xxx_battery.h>
>> @@ -732,6 +733,15 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   	di->last_update = jiffies;
>>   }
>>
>> +static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
>> +{
>> +	struct bq27xxx_device_info *di = data;
>> +
>> +	bq27xxx_battery_update(di);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>>   static void bq27xxx_battery_poll(struct work_struct *work)
>>   {
>>   	struct bq27xxx_device_info *di =
>> @@ -1137,6 +1147,19 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
>>
>>   	i2c_set_clientdata(client, di);
>>
>> +	if (client->irq) {
>> +		retval = devm_request_threaded_irq(&client->dev, client->irq,
>> +				NULL, bq27xxx_battery_irq_handler_thread,
>> +				IRQF_ONESHOT,
>> +				name, di);
>
> Hi Andrew,
> I think it'll be better if you explicitly specify the rising vs. falling
> edge interrupt flags according to exactly what the bq27xxx will trigger
> on to ensure the corresponding GPIO module is always configured properly.
>

That was how I was going to have it, but this may be device dependent, so
I decided to leave it up to the interrupt controller and set it with DT:

interrupts = <28 IRQ_TYPE_EDGE_FALLING>;

> While we are at it, was the platform-data based initialization in
> conjunction with interrupts tested?
>

The only time we initialize with platform-data is when we are wired
with HDQ, in that case this IRQ code does not get called, so nothing
changes.

Regards,
Andrew

> Regards,
>
> --
> Andreas Dannenberg
> Texas Instruments Inc
>
>
>> +		if (retval) {
>> +			dev_err(&client->dev,
>> +				"Unable to register IRQ %d error %d\n",
>> +				client->irq, retval);
>> +			return retval;
>> +		}
>> +	}
>> +
>>   	return 0;
>>
>>   batt_failed:
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 1/7] power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-21  8:33   ` Pali Rohár
  -1 siblings, 0 replies; 31+ messages in thread
From: Pali Rohár @ 2015-09-21  8:33 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On Monday 14 September 2015 16:26:07 Andrew F. Davis wrote:
> The MODULE_DEVICE_TABLE macro automatically adds all needed
> i2c MODULE_ALIASes so remove the extra MODULE_ALIAS.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>

Acked-by: Pali Rohár <pali.rohar@gmail.com>

> ---
>  drivers/power/bq27x00_battery.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
> index 8287261f..d0b2f3b 100644
> --- a/drivers/power/bq27x00_battery.c
> +++ b/drivers/power/bq27x00_battery.c
> @@ -1120,10 +1120,6 @@ module_exit(bq27x00_battery_exit);
>  MODULE_ALIAS("platform:bq27000-battery");
>  #endif
>  
> -#ifdef CONFIG_BATTERY_BQ27X00_I2C
> -MODULE_ALIAS("i2c:bq27000-battery");
> -#endif
> -
>  MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
>  MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
>  MODULE_LICENSE("GPL");

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 6/7] power: bq27xxx_battery: Cleanup health checking
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-21  8:35   ` Pali Rohár
  -1 siblings, 0 replies; 31+ messages in thread
From: Pali Rohár @ 2015-09-21  8:35 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On Monday 14 September 2015 16:26:12 Andrew F. Davis wrote:
> Reorganize the logic checking battery health and add under temperature
> condition checking.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>

Acked-by: Pali Rohár <pali.rohar@gmail.com>

> ---
>  drivers/power/bq27xxx_battery.c | 64 +++++++++++++++++++++++++++--------------
>  1 file changed, 42 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
> index 3098609..10be8a6 100644
> --- a/drivers/power/bq27xxx_battery.c
> +++ b/drivers/power/bq27xxx_battery.c
> @@ -63,6 +63,8 @@
>  #define BQ27XXX_FLAG_FC		BIT(9)
>  #define BQ27XXX_FLAG_OTD	BIT(14)
>  #define BQ27XXX_FLAG_OTC	BIT(15)
> +#define BQ27XXX_FLAG_UT		BIT(14)
> +#define BQ27XXX_FLAG_OT		BIT(15)
>  
>  /* BQ27000 has different layout for Flags register */
>  #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
> @@ -621,12 +623,36 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
>  /*
>   * Returns true if a battery over temperature condition is detected
>   */
> -static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
> +static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>  {
> -	if (di->chip == BQ27500 || di->chip == BQ27541)
> +	if (di->chip == BQ27500 || di->chip == BQ27541 || di->chip == BQ27545)
>  		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
> +	if (di->chip == BQ27530 || di->chip == BQ27421)
> +		return flags & BQ27XXX_FLAG_OT;
> +
> +	return false;
> +}
> +
> +/*
> + * Returns true if a battery under temperature condition is detected
> + */
> +static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
> +{
> +	if (di->chip == BQ27530 || di->chip == BQ27421)
> +		return flags & BQ27XXX_FLAG_UT;
> +
> +	return false;
> +}
> +
> +/*
> + * Returns true if a low state of charge condition is detected
> + */
> +static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
> +{
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
> +		return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
>  	else
> -		return flags & BQ27XXX_FLAG_OTC;
> +		return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
>  }
>  
>  /*
> @@ -635,29 +661,23 @@ static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>   */
>  static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
>  {
> -	u16 tval;
> +	u16 flags;
>  
> -	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
> -	if (tval < 0) {
> -		dev_err(di->dev, "error reading flag register:%d\n", tval);
> -		return tval;
> +	flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
> +	if (flags < 0) {
> +		dev_err(di->dev, "error reading flag register:%d\n", flags);
> +		return flags;
>  	}
>  
> -	if (di->chip == BQ27000 || di->chip == BQ27010) {
> -		if (tval & BQ27000_FLAG_EDV1)
> -			tval = POWER_SUPPLY_HEALTH_DEAD;
> -		else
> -			tval = POWER_SUPPLY_HEALTH_GOOD;
> -	} else {
> -		if (tval & BQ27XXX_FLAG_SOCF)
> -			tval = POWER_SUPPLY_HEALTH_DEAD;
> -		else if (bq27xxx_battery_overtemp(di, tval))
> -			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
> -		else
> -			tval = POWER_SUPPLY_HEALTH_GOOD;
> -	}
> +	/* Unlikely but important to return first */
> +	if (unlikely(bq27xxx_battery_overtemp(di, flags)))
> +		return POWER_SUPPLY_HEALTH_OVERHEAT;
> +	if (unlikely(bq27xxx_battery_undertemp(di, flags)))
> +		return POWER_SUPPLY_HEALTH_COLD;
> +	if (unlikely(bq27xxx_battery_dead(di, flags)))
> +		return POWER_SUPPLY_HEALTH_DEAD;
>  
> -	return tval;
> +	return POWER_SUPPLY_HEALTH_GOOD;
>  }
>  
>  static void bq27xxx_battery_update(struct bq27xxx_device_info *di)

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 4/7] power: bq27xxx_battery: Fix typos and change naming for state of charge functions
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-21  8:36   ` Pali Rohár
  -1 siblings, 0 replies; 31+ messages in thread
From: Pali Rohár @ 2015-09-21  8:36 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On Monday 14 September 2015 16:26:10 Andrew F. Davis wrote:
> Fix typos and change "relative state of charge" to "state of charge" as not
> all supported devices use relative state of charge.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>

Acked-by: Pali Rohár <pali.rohar@gmail.com>

> ---
>  drivers/power/bq27xxx_battery.c | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
> index 0734413..1ff88ad 100644
> --- a/drivers/power/bq27xxx_battery.c
> +++ b/drivers/power/bq27xxx_battery.c
> @@ -229,26 +229,26 @@ static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
>  }
>  
>  /*
> - * Return the battery Relative State-of-Charge
> + * Return the battery State-of-Charge
>   * Or < 0 if something fails.
>   */
> -static int bq27xxx_battery_read_rsoc(struct bq27xxx_device_info *di)
> +static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
>  {
> -	int rsoc;
> +	int soc;
>  
>  	if (di->chip == BQ27500 || di->chip == BQ27742)
> -		rsoc = bq27xxx_read(di, BQ27500_REG_SOC, false);
> +		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
>  	else if (di->chip == BQ27510)
> -		rsoc = bq27xxx_read(di, BQ27510_REG_SOC, false);
> +		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
>  	else if (di->chip == BQ27425)
> -		rsoc = bq27xxx_read(di, BQ27425_REG_SOC, false);
> -	else
> -		rsoc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
> +		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
> +	else /* for the bq27000 we read the "relative" SoC register */
> +		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
>  
> -	if (rsoc < 0)
> -		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
> +	if (soc < 0)
> +		dev_dbg(di->dev, "error reading State-of-Charge\n");
>  
> -	return rsoc;
> +	return soc;
>  }
>  
>  /*
> @@ -275,7 +275,7 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>  }
>  
>  /*
> - * Return the battery Nominal available capaciy in µAh
> + * Return the battery Nominal available capacity in µAh
>   * Or < 0 if something fails.
>   */
>  static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
> @@ -416,7 +416,7 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
>  }
>  
>  /*
> - * Read a power avg register.
> + * Read an average power register.
>   * Return < 0 if something fails.
>   */
>  static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
> @@ -498,7 +498,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>  			cache.charge_full = -ENODATA;
>  			cache.health = -ENODATA;
>  		} else {
> -			cache.capacity = bq27xxx_battery_read_rsoc(di);
> +			cache.capacity = bq27xxx_battery_read_soc(di);
>  			if (is_bq27742 || is_bq27510)
>  				cache.time_to_empty =
>  					bq27xxx_battery_read_time(di,

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-21  8:41   ` Pali Rohár
  2015-09-21 18:40       ` Andrew F. Davis
  -1 siblings, 1 reply; 31+ messages in thread
From: Pali Rohár @ 2015-09-21  8:41 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On Monday 14 September 2015 16:26:09 Andrew F. Davis wrote:
> When initialized as a platform device the initializer must now specify
> a device. An empty device name is no longer valid.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/power/bq27xxx_battery.c       | 9 ++++++---
>  drivers/w1/slaves/w1_bq27000.c        | 1 +
>  include/linux/power/bq27xxx_battery.h | 6 +++++-
>  3 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
> index e72055c..0734413 100644
> --- a/drivers/power/bq27xxx_battery.c
> +++ b/drivers/power/bq27xxx_battery.c
> @@ -91,8 +91,6 @@ struct bq27xxx_access_methods {
>  	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>  };
>  
> -enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
> -
>  struct bq27xxx_reg_cache {
>  	int temperature;
>  	int time_to_empty;
> @@ -1036,6 +1034,11 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> +	if (!pdata->chip) {
> +		dev_err(&pdev->dev, "no device supplied\n");
> +		return -EINVAL;
> +	}
> +
>  	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
>  	if (!di)
>  		return -ENOMEM;
> @@ -1043,7 +1046,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>  	platform_set_drvdata(pdev, di);
>  
>  	di->dev = &pdev->dev;
> -	di->chip = BQ27000;
> +	di->chip = pdata->chip;
>  
>  	name = pdata->name ?: dev_name(&pdev->dev);
>  	di->bus.read = &bq27xxx_battery_platform_read;
> diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
> index 8480531..9f4a86b 100644
> --- a/drivers/w1/slaves/w1_bq27000.c
> +++ b/drivers/w1/slaves/w1_bq27000.c
> @@ -42,6 +42,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
>  static struct bq27xxx_platform_data bq27000_battery_info = {
>  	.read   = w1_bq27000_read,
>  	.name   = "bq27000-battery",
> +	.chip   = BQ27000,
>  };
>  
>  static int w1_bq27000_add_slave(struct w1_slave *sl)
> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
> index e70a93a..a4efb10 100644
> --- a/include/linux/power/bq27xxx_battery.h
> +++ b/include/linux/power/bq27xxx_battery.h
> @@ -3,7 +3,8 @@
>  
>  /**
>   * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
> - * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
> + * @name: Name of the battery.
> + * @chip: Chip class number of this device.
>   * @read: HDQ read callback.
>   *	This function should provide access to the HDQ bus the battery is
>   *	connected to.
> @@ -11,8 +12,11 @@
>   *	register to be read. The return value should either be the content of
>   *	the passed register or an error value.
>   */
> +enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
> +
>  struct bq27xxx_platform_data {
>  	const char *name;
> +	enum bq27xxx_chip chip;

Do we still need name property if we have chip enum? And if yes who use
it and why?

>  	int (*read)(struct device *dev, unsigned int);
>  };
>  

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
@ 2015-09-21  8:46   ` Pali Rohár
  2015-09-21 19:02       ` Andrew F. Davis
  -1 siblings, 1 reply; 31+ messages in thread
From: Pali Rohár @ 2015-09-21  8:46 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On Monday 14 September 2015 16:26:11 Andrew F. Davis wrote:
> Add support for additional devices and register equivalent family devices
> including the bq27010, bq27210, bq27500, bq27510, bq27520, bq27530,
> bq27531, bq27541, bq27542, bq27546, bq27545, bq27441, bq27421, and the
> bq27641.
> 
> To facilitate this process the register mapings have been moved to tables
> and other small cleanups have been made.
> 
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
>  drivers/power/bq27xxx_battery.c       | 627 +++++++++++++++++++++++-----------
>  include/linux/power/bq27xxx_battery.h |  10 +-
>  2 files changed, 428 insertions(+), 209 deletions(-)
> 
> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
> index 1ff88ad..3098609 100644
> --- a/drivers/power/bq27xxx_battery.c
> +++ b/drivers/power/bq27xxx_battery.c
> @@ -17,11 +17,24 @@
>   * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>   *
>   * Datasheets:
> - * http://focus.ti.com/docs/prod/folders/print/bq27000.html
> - * http://focus.ti.com/docs/prod/folders/print/bq27500.html
> + * http://www.ti.com/product/bq27000
> + * http://www.ti.com/product/bq27200
> + * http://www.ti.com/product/bq27010
> + * http://www.ti.com/product/bq27210
> + * http://www.ti.com/product/bq27500
> + * http://www.ti.com/product/bq27510-g3
> + * http://www.ti.com/product/bq27520-g4
> + * http://www.ti.com/product/bq27530-g1
> + * http://www.ti.com/product/bq27531-g1
> + * http://www.ti.com/product/bq27541-g1
> + * http://www.ti.com/product/bq27542-g1
> + * http://www.ti.com/product/bq27546-g1
> + * http://www.ti.com/product/bq27742-g1
> + * http://www.ti.com/product/bq27545-g1
> + * http://www.ti.com/product/bq27421-g1
>   * http://www.ti.com/product/bq27425-g1
> - * http://www.ti.com/product/BQ27742-G1
> - * http://www.ti.com/product/BQ27510-G3
> + * http://www.ti.com/product/bq27411-g1
> + * http://www.ti.com/product/bq27621-g1
>   */
>  
>  #include <linux/device.h>
> @@ -43,54 +56,57 @@
>  
>  #define BQ27XXX_MANUFACTURER	"Texas Instruments"
>  
> -#define BQ27x00_REG_TEMP	0x06
> -#define BQ27x00_REG_VOLT	0x08
> -#define BQ27x00_REG_AI		0x14
> -#define BQ27x00_REG_FLAGS	0x0A
> -#define BQ27x00_REG_TTE		0x16
> -#define BQ27x00_REG_TTF		0x18
> -#define BQ27x00_REG_TTECP	0x26
> -#define BQ27x00_REG_NAC		0x0C /* Nominal available capacity */
> -#define BQ27x00_REG_LMD		0x12 /* Last measured discharge */
> -#define BQ27x00_REG_CYCT	0x2A /* Cycle count total */
> -#define BQ27x00_REG_AE		0x22 /* Available energy */
> -#define BQ27x00_POWER_AVG	0x24
> -
> -#define BQ27000_REG_RSOC	0x0B /* Relative State-of-Charge */
> -#define BQ27000_REG_ILMD	0x76 /* Initial last measured discharge */
> +/* BQ27XXX Flags */
> +#define BQ27XXX_FLAG_DSC	BIT(0)
> +#define BQ27XXX_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
> +#define BQ27XXX_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
> +#define BQ27XXX_FLAG_FC		BIT(9)
> +#define BQ27XXX_FLAG_OTD	BIT(14)
> +#define BQ27XXX_FLAG_OTC	BIT(15)
> +
> +/* BQ27000 has different layout for Flags register */
>  #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
>  #define BQ27000_FLAG_EDV1	BIT(1) /* First End-of-Discharge-Voltage flag */
>  #define BQ27000_FLAG_CI		BIT(4) /* Capacity Inaccurate flag */
>  #define BQ27000_FLAG_FC		BIT(5)
>  #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
>  
> -#define BQ27500_REG_SOC		0x2C
> -#define BQ27500_REG_DCAP	0x3C /* Design capacity */
> -#define BQ27500_FLAG_DSC	BIT(0)
> -#define BQ27500_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
> -#define BQ27500_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
> -#define BQ27500_FLAG_FC		BIT(9)
> -#define BQ27500_FLAG_OTC	BIT(15)
> -
> -#define BQ27742_POWER_AVG	0x76
> -
> -#define BQ27510_REG_SOC		0x20
> -#define BQ27510_REG_DCAP	0x2E /* Design capacity */
> -#define BQ27510_REG_CYCT	0x1E /* Cycle count total */
> -
> -/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
> -#define BQ27425_REG_OFFSET	0x04
> -#define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
> -#define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
> -
> -#define BQ27XXX_RS			20 /* Resistor sense */
> -#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
> +#define BQ27XXX_RS			(20) /* Resistor sense mOhm */
> +#define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
> +#define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
>  
>  struct bq27xxx_device_info;
>  struct bq27xxx_access_methods {
>  	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>  };
>  
> +#define INVALID_REG_ADDR	0xff
> +
> +/*
> + * bq27xxx_reg_index - Register names
> + *
> + * These are indexes into a device's register mapping array.
> + */
> +enum bq27xxx_reg_index {
> +	BQ27XXX_REG_CTRL = 0,	/* Control */
> +	BQ27XXX_REG_TEMP,	/* Temperature */
> +	BQ27XXX_REG_INT_TEMP,	/* Internal Temperature */
> +	BQ27XXX_REG_VOLT,	/* Voltage */
> +	BQ27XXX_REG_AI,		/* Average Current */
> +	BQ27XXX_REG_FLAGS,	/* Flags */
> +	BQ27XXX_REG_TTE,	/* Time-to-Empty */
> +	BQ27XXX_REG_TTF,	/* Time-to-Full */
> +	BQ27XXX_REG_TTES,	/* Time-to-Empty Standby */
> +	BQ27XXX_REG_TTECP,	/* Time-to-Empty at Constant Power */
> +	BQ27XXX_REG_NAC,	/* Nominal Available Capacity */
> +	BQ27XXX_REG_FCC,	/* Full Charge Capacity */
> +	BQ27XXX_REG_CYCT,	/* Cycle Count */
> +	BQ27XXX_REG_AE,		/* Available Energy */
> +	BQ27XXX_REG_SOC,	/* State-of-Charge */
> +	BQ27XXX_REG_DCAP,	/* Design Capacity */
> +	BQ27XXX_REG_AP,		/* Average Power */
> +};
> +
>  struct bq27xxx_reg_cache {
>  	int temperature;
>  	int time_to_empty;
> @@ -121,9 +137,152 @@ struct bq27xxx_device_info {
>  	struct bq27xxx_access_methods bus;
>  
>  	struct mutex lock;
> +
> +	u8 *regs;
> +};
> +
> +/* Register mappings */
> +static u8 bq27000_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	0x18,	/* TTF		*/
> +	0x1c,	/* TTES		*/
> +	0x26,	/* TTECP	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x2a,	/* CYCT		*/
> +	0x22,	/* AE		*/
> +	0x0b,	/* SOC(RSOC)	*/
> +	0x76,	/* DCAP(ILMD)	*/
> +	0x24,	/* AP		*/
> +};
> +
> +static u8 bq27010_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	0x18,	/* TTF		*/
> +	0x1c,	/* TTES		*/
> +	0x26,	/* TTECP	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x2a,	/* CYCT		*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x0b,	/* SOC(RSOC)	*/
> +	0x76,	/* DCAP(ILMD)	*/
> +	INVALID_REG_ADDR,	/* AP - NA	*/
> +};
> +
> +static u8 bq27500_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	0x28,	/* INT TEMP	*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	INVALID_REG_ADDR,	/* TTF - NA	*/
> +	0x1a,	/* TTES		*/
> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x1e,	/* CYCT		*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x20,	/* SOC(RSOC)	*/
> +	0x2e,	/* DCAP(ILMD)	*/
> +	INVALID_REG_ADDR,	/* AP - NA	*/
>  };
>  
> -static enum power_supply_property bq27x00_battery_props[] = {
> +static u8 bq27530_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	0x32,	/* INT TEMP	*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	INVALID_REG_ADDR,	/* TTF - NA	*/
> +	INVALID_REG_ADDR,	/* TTES - NA	*/
> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x2a,	/* CYCT		*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x2c,	/* SOC(RSOC)	*/
> +	INVALID_REG_ADDR,	/* DCAP - NA	*/
> +	0x24,	/* AP		*/
> +};
> +
> +static u8 bq27541_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	0x28,	/* INT TEMP	*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	INVALID_REG_ADDR,	/* TTF - NA	*/
> +	INVALID_REG_ADDR,	/* TTES - NA	*/
> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x2a,	/* CYCT		*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x2c,	/* SOC(RSOC)	*/
> +	0x3c,	/* DCAP		*/
> +	0x76,	/* AP		*/
> +};
> +
> +static u8 bq27545_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x06,	/* TEMP		*/
> +	0x28,	/* INT TEMP	*/
> +	0x08,	/* VOLT		*/
> +	0x14,	/* AVG CURR	*/
> +	0x0a,	/* FLAGS	*/
> +	0x16,	/* TTE		*/
> +	INVALID_REG_ADDR,	/* TTF - NA	*/
> +	INVALID_REG_ADDR,	/* TTES - NA	*/
> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
> +	0x0c,	/* NAC		*/
> +	0x12,	/* LMD(FCC)	*/
> +	0x2a,	/* CYCT		*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x2c,	/* SOC(RSOC)	*/
> +	INVALID_REG_ADDR,	/* DCAP - NA */
> +	0x24,	/* AP		*/
> +};
> +
> +static u8 bq27421_regs[] = {
> +	0x00,	/* CONTROL	*/
> +	0x02,	/* TEMP		*/
> +	0x1e,	/* INT TEMP	*/
> +	0x04,	/* VOLT		*/
> +	0x10,	/* AVG CURR	*/
> +	0x06,	/* FLAGS	*/
> +	INVALID_REG_ADDR,	/* TTE - NA	*/
> +	INVALID_REG_ADDR,	/* TTF - NA	*/
> +	INVALID_REG_ADDR,	/* TTES - NA	*/
> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
> +	0x08,	/* NAC		*/
> +	0x0e,	/* FCC		*/
> +	INVALID_REG_ADDR,	/* CYCT - NA	*/
> +	INVALID_REG_ADDR,	/* AE - NA	*/
> +	0x1c,	/* SOC		*/
> +	0x3c,	/* DCAP		*/
> +	0x18,	/* AP		*/
> +};
> +
> +static enum power_supply_property bq27000_battery_props[] = {
>  	POWER_SUPPLY_PROP_STATUS,
>  	POWER_SUPPLY_PROP_PRESENT,
>  	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> @@ -145,7 +304,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
>  	POWER_SUPPLY_PROP_MANUFACTURER,
>  };
>  
> -static enum power_supply_property bq27425_battery_props[] = {
> +static enum power_supply_property bq27010_battery_props[] = {
>  	POWER_SUPPLY_PROP_STATUS,
>  	POWER_SUPPLY_PROP_PRESENT,
>  	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> @@ -153,14 +312,19 @@ static enum power_supply_property bq27425_battery_props[] = {
>  	POWER_SUPPLY_PROP_CAPACITY,
>  	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>  	POWER_SUPPLY_PROP_TEMP,
> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
> +	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
>  	POWER_SUPPLY_PROP_TECHNOLOGY,
>  	POWER_SUPPLY_PROP_CHARGE_FULL,
>  	POWER_SUPPLY_PROP_CHARGE_NOW,
>  	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
> +	POWER_SUPPLY_PROP_HEALTH,
>  	POWER_SUPPLY_PROP_MANUFACTURER,
>  };
>  
> -static enum power_supply_property bq27742_battery_props[] = {
> +static enum power_supply_property bq27500_battery_props[] = {
>  	POWER_SUPPLY_PROP_STATUS,
>  	POWER_SUPPLY_PROP_PRESENT,
>  	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> @@ -174,12 +338,29 @@ static enum power_supply_property bq27742_battery_props[] = {
>  	POWER_SUPPLY_PROP_CHARGE_NOW,
>  	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>  	POWER_SUPPLY_PROP_CYCLE_COUNT,
> +	POWER_SUPPLY_PROP_HEALTH,
> +	POWER_SUPPLY_PROP_MANUFACTURER,
> +};
> +
> +static enum power_supply_property bq27530_battery_props[] = {
> +	POWER_SUPPLY_PROP_STATUS,
> +	POWER_SUPPLY_PROP_PRESENT,
> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +	POWER_SUPPLY_PROP_CURRENT_NOW,
> +	POWER_SUPPLY_PROP_CAPACITY,
> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
> +	POWER_SUPPLY_PROP_TEMP,
> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
> +	POWER_SUPPLY_PROP_TECHNOLOGY,
> +	POWER_SUPPLY_PROP_CHARGE_FULL,
> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>  	POWER_SUPPLY_PROP_POWER_AVG,
>  	POWER_SUPPLY_PROP_HEALTH,
> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>  	POWER_SUPPLY_PROP_MANUFACTURER,
>  };
>  
> -static enum power_supply_property bq27510_battery_props[] = {
> +static enum power_supply_property bq27541_battery_props[] = {
>  	POWER_SUPPLY_PROP_STATUS,
>  	POWER_SUPPLY_PROP_PRESENT,
>  	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> @@ -198,6 +379,39 @@ static enum power_supply_property bq27510_battery_props[] = {
>  	POWER_SUPPLY_PROP_MANUFACTURER,
>  };
>  
> +static enum power_supply_property bq27545_battery_props[] = {
> +	POWER_SUPPLY_PROP_STATUS,
> +	POWER_SUPPLY_PROP_PRESENT,
> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +	POWER_SUPPLY_PROP_CURRENT_NOW,
> +	POWER_SUPPLY_PROP_CAPACITY,
> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
> +	POWER_SUPPLY_PROP_TEMP,
> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
> +	POWER_SUPPLY_PROP_TECHNOLOGY,
> +	POWER_SUPPLY_PROP_CHARGE_FULL,
> +	POWER_SUPPLY_PROP_CHARGE_NOW,
> +	POWER_SUPPLY_PROP_HEALTH,
> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
> +	POWER_SUPPLY_PROP_POWER_AVG,
> +	POWER_SUPPLY_PROP_MANUFACTURER,
> +};
> +
> +static enum power_supply_property bq27421_battery_props[] = {
> +	POWER_SUPPLY_PROP_STATUS,
> +	POWER_SUPPLY_PROP_PRESENT,
> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +	POWER_SUPPLY_PROP_CURRENT_NOW,
> +	POWER_SUPPLY_PROP_CAPACITY,
> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
> +	POWER_SUPPLY_PROP_TEMP,
> +	POWER_SUPPLY_PROP_TECHNOLOGY,
> +	POWER_SUPPLY_PROP_CHARGE_FULL,
> +	POWER_SUPPLY_PROP_CHARGE_NOW,
> +	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> +	POWER_SUPPLY_PROP_MANUFACTURER,
> +};
> +
>  static unsigned int poll_interval = 360;
>  module_param(poll_interval, uint, 0644);
>  MODULE_PARM_DESC(poll_interval,
> @@ -207,25 +421,14 @@ MODULE_PARM_DESC(poll_interval,
>   * Common code for BQ27xxx devices
>   */
>  
> -static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
> +static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
>  			       bool single)
>  {
> -	if (di->chip == BQ27425)
> -		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
> -	return di->bus.read(di, reg, single);
> -}
> +	/* Reports EINVAL for invalid/missing registers */
> +	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
> +		return -EINVAL;
>  
> -/*
> - * Higher versions of the chip like BQ27425 and BQ27500
> - * differ from BQ27000 and BQ27200 in calculation of certain
> - * parameters. Hence we need to check for the chip type.
> - */
> -static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
> -{
> -	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
> -	    || di->chip == BQ27510)
> -		return true;
> -	return false;
> +	return di->bus.read(di, di->regs[reg_index], single);
>  }
>  
>  /*
> @@ -236,14 +439,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
>  {
>  	int soc;
>  
> -	if (di->chip == BQ27500 || di->chip == BQ27742)
> -		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
> -	else if (di->chip == BQ27510)
> -		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
> -	else if (di->chip == BQ27425)
> -		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
> -	else /* for the bq27000 we read the "relative" SoC register */
> -		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
> +	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
>  
>  	if (soc < 0)
>  		dev_dbg(di->dev, "error reading State-of-Charge\n");
> @@ -266,10 +462,10 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>  		return charge;
>  	}
>  
> -	if (bq27xxx_is_chip_version_higher(di))
> -		charge *= 1000;
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
> +		charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>  	else
> -		charge = charge * 3570 / BQ27XXX_RS;
> +		charge *= 1000;
>  
>  	return charge;
>  }
> @@ -281,57 +477,46 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>  static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
>  {
>  	int flags;
> -	bool is_bq27500 = di->chip == BQ27500;
> -	bool is_bq27742 = di->chip == BQ27742;
> -	bool is_higher = bq27xxx_is_chip_version_higher(di);
> -	bool flags_1b = !(is_bq27500 || is_bq27742);
>  
> -	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
> -	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
> -		return -ENODATA;
> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
> +		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
> +			return -ENODATA;
> +	}
>  
> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
>  }
>  
>  /*
> - * Return the battery Last measured discharge in µAh
> + * Return the battery Full Charge Capacity in µAh
>   * Or < 0 if something fails.
>   */
> -static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
> +static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di)
>  {
> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC);
>  }
>  
>  /*
> - * Return the battery Initial last measured discharge in µAh
> + * Return the Design Capacity in µAh
>   * Or < 0 if something fails.
>   */
> -static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
> +static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
>  {
> -	int ilmd;
> +	int dcap;
>  
> -	if (bq27xxx_is_chip_version_higher(di)) {
> -		if (di->chip == BQ27425)
> -			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
> -		else if (di->chip == BQ27510)
> -			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
> -		else
> -			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
> -	} else {
> -		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
> -	}
> +	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
>  
> -	if (ilmd < 0) {
> +	if (dcap < 0) {
>  		dev_dbg(di->dev, "error reading initial last measured discharge\n");
> -		return ilmd;
> +		return dcap;
>  	}
>  
> -	if (bq27xxx_is_chip_version_higher(di))
> -		ilmd *= 1000;
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
> +		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>  	else
> -		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
> +		dcap *= 1000;
>  
> -	return ilmd;
> +	return dcap;
>  }
>  
>  /*
> @@ -342,16 +527,16 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
>  {
>  	int ae;
>  
> -	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
> +	ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);
>  	if (ae < 0) {
>  		dev_dbg(di->dev, "error reading available energy\n");
>  		return ae;
>  	}
>  
> -	if (di->chip == BQ27500)
> -		ae *= 1000;
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
> +		ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
>  	else
> -		ae = ae * 29200 / BQ27XXX_RS;
> +		ae *= 1000;
>  
>  	return ae;
>  }
> @@ -364,13 +549,13 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
>  {
>  	int temp;
>  
> -	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
> +	temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);
>  	if (temp < 0) {
>  		dev_err(di->dev, "error reading temperature\n");
>  		return temp;
>  	}
>  
> -	if (!bq27xxx_is_chip_version_higher(di))
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>  		temp = 5 * temp / 2;
>  
>  	return temp;
> @@ -384,10 +569,7 @@ static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
>  {
>  	int cyct;
>  
> -	if (di->chip == BQ27510)
> -		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
> -	else
> -		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
> +	cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);
>  	if (cyct < 0)
>  		dev_err(di->dev, "error reading cycle count total\n");
>  
> @@ -419,21 +601,32 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
>   * Read an average power register.
>   * Return < 0 if something fails.
>   */
> -static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
> +static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
>  {
>  	int tval;
>  
> -	tval = bq27xxx_read(di, reg, false);
> +	tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
>  	if (tval < 0) {
> -		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
> -			reg, tval);
> +		dev_err(di->dev, "error reading average power register  %02x: %d\n",
> +			BQ27XXX_REG_AP, tval);
>  		return tval;
>  	}
>  
> -	if (di->chip == BQ27500)
> +	if (di->chip == BQ27000 || di->chip == BQ27010)
> +		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
> +	else
>  		return tval;
> +}
> +
> +/*
> + * Returns true if a battery over temperature condition is detected
> + */
> +static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
> +{
> +	if (di->chip == BQ27500 || di->chip == BQ27541)
> +		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
>  	else
> -		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
> +		return flags & BQ27XXX_FLAG_OTC;
>  }
>  
>  /*
> @@ -442,53 +635,43 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
>   */
>  static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
>  {
> -	int tval;
> +	u16 tval;
>  
> -	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
> +	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>  	if (tval < 0) {
>  		dev_err(di->dev, "error reading flag register:%d\n", tval);
>  		return tval;
>  	}
>  
> -	if (di->chip == BQ27500) {
> -		if (tval & BQ27500_FLAG_SOCF)
> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
> +		if (tval & BQ27000_FLAG_EDV1)
>  			tval = POWER_SUPPLY_HEALTH_DEAD;
> -		else if (tval & BQ27500_FLAG_OTC)
> -			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>  		else
>  			tval = POWER_SUPPLY_HEALTH_GOOD;
> -		return tval;
> -	} else if (di->chip == BQ27510) {
> -		if (tval & BQ27500_FLAG_OTC)
> -			return POWER_SUPPLY_HEALTH_OVERHEAT;
> -		return POWER_SUPPLY_HEALTH_GOOD;
>  	} else {
> -		if (tval & BQ27000_FLAG_EDV1)
> +		if (tval & BQ27XXX_FLAG_SOCF)
>  			tval = POWER_SUPPLY_HEALTH_DEAD;
> +		else if (bq27xxx_battery_overtemp(di, tval))
> +			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>  		else
>  			tval = POWER_SUPPLY_HEALTH_GOOD;
> -		return tval;
>  	}
>  
> -	return -1;
> +	return tval;
>  }
>  
>  static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>  {
>  	struct bq27xxx_reg_cache cache = {0, };
> -	bool is_bq27500 = di->chip == BQ27500;
> -	bool is_bq27510 = di->chip == BQ27510;
> -	bool is_bq27425 = di->chip == BQ27425;
> -	bool is_bq27742 = di->chip == BQ27742;
> -	bool flags_1b = !(is_bq27500 || is_bq27742);
> +	bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
> +	bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
>  
> -	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
> +	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
>  	if ((cache.flags & 0xff) == 0xff)
> -		/* read error */
> -		cache.flags = -1;
> +		cache.flags = -1; /* read error */
>  	if (cache.flags >= 0) {
> -		if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510
> -				&& (cache.flags & BQ27000_FLAG_CI)) {
> +		cache.temperature = bq27xxx_battery_read_temperature(di);
> +		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
>  			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
>  			cache.capacity = -ENODATA;
>  			cache.energy = -ENODATA;
> @@ -498,41 +681,26 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>  			cache.charge_full = -ENODATA;
>  			cache.health = -ENODATA;
>  		} else {
> +			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
> +				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
> +			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
> +				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
> +			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
> +				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
> +			cache.charge_full = bq27xxx_battery_read_fcc(di);
>  			cache.capacity = bq27xxx_battery_read_soc(di);
> -			if (is_bq27742 || is_bq27510)
> -				cache.time_to_empty =
> -					bq27xxx_battery_read_time(di,
> -							BQ27x00_REG_TTE);
> -			else if (!is_bq27425) {
> +			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
>  				cache.energy = bq27xxx_battery_read_energy(di);
> -				cache.time_to_empty =
> -					bq27xxx_battery_read_time(di,
> -							BQ27x00_REG_TTE);
> -				cache.time_to_empty_avg =
> -					bq27xxx_battery_read_time(di,
> -							BQ27x00_REG_TTECP);
> -				cache.time_to_full =
> -					bq27xxx_battery_read_time(di,
> -							BQ27x00_REG_TTF);
> -			}
> -			cache.charge_full = bq27xxx_battery_read_lmd(di);
>  			cache.health = bq27xxx_battery_read_health(di);
>  		}
> -		cache.temperature = bq27xxx_battery_read_temperature(di);
> -		if (!is_bq27425)
> +		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
>  			cache.cycle_count = bq27xxx_battery_read_cyct(di);
> -		if (is_bq27742)
> -			cache.power_avg =
> -				bq27xxx_battery_read_pwr_avg(di,
> -						BQ27742_POWER_AVG);
> -		else
> -			cache.power_avg =
> -				bq27xxx_battery_read_pwr_avg(di,
> -						BQ27x00_POWER_AVG);
> +		if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
> +			cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
>  
>  		/* We only have to read charge design full once */
>  		if (di->charge_design_full <= 0)
> -			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
> +			di->charge_design_full = bq27xxx_battery_read_dcap(di);
>  	}
>  
>  	if (di->cache.capacity != cache.capacity)
> @@ -547,7 +715,8 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>  static void bq27xxx_battery_poll(struct work_struct *work)
>  {
>  	struct bq27xxx_device_info *di =
> -		container_of(work, struct bq27xxx_device_info, work.work);
> +			container_of(work, struct bq27xxx_device_info,
> +				     work.work);
>  
>  	bq27xxx_battery_update(di);
>  
> @@ -569,23 +738,23 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
>  	int curr;
>  	int flags;
>  
> -	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
> +	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
>  	if (curr < 0) {
>  		dev_err(di->dev, "error reading current\n");
>  		return curr;
>  	}
>  
> -	if (bq27xxx_is_chip_version_higher(di)) {
> -		/* bq27500 returns signed value */
> -		val->intval = (int)((s16)curr) * 1000;
> -	} else {
> -		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>  		if (flags & BQ27000_FLAG_CHGS) {
>  			dev_dbg(di->dev, "negative current!\n");
>  			curr = -curr;
>  		}
>  
> -		val->intval = curr * 3570 / BQ27XXX_RS;
> +		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
> +	} else {
> +		/* Other gauges return signed value */
> +		val->intval = (int)((s16)curr) * 1000;
>  	}
>  
>  	return 0;
> @@ -596,14 +765,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>  {
>  	int status;
>  
> -	if (bq27xxx_is_chip_version_higher(di)) {
> -		if (di->cache.flags & BQ27500_FLAG_FC)
> -			status = POWER_SUPPLY_STATUS_FULL;
> -		else if (di->cache.flags & BQ27500_FLAG_DSC)
> -			status = POWER_SUPPLY_STATUS_DISCHARGING;
> -		else
> -			status = POWER_SUPPLY_STATUS_CHARGING;
> -	} else {
> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>  		if (di->cache.flags & BQ27000_FLAG_FC)
>  			status = POWER_SUPPLY_STATUS_FULL;
>  		else if (di->cache.flags & BQ27000_FLAG_CHGS)
> @@ -612,6 +774,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>  			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
>  		else
>  			status = POWER_SUPPLY_STATUS_DISCHARGING;
> +	} else {
> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
> +			status = POWER_SUPPLY_STATUS_FULL;
> +		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
> +			status = POWER_SUPPLY_STATUS_DISCHARGING;
> +		else
> +			status = POWER_SUPPLY_STATUS_CHARGING;
>  	}
>  
>  	val->intval = status;
> @@ -624,21 +793,21 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
>  {
>  	int level;
>  
> -	if (bq27xxx_is_chip_version_higher(di)) {
> -		if (di->cache.flags & BQ27500_FLAG_FC)
> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
> +		if (di->cache.flags & BQ27000_FLAG_FC)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
> -		else if (di->cache.flags & BQ27500_FLAG_SOC1)
> +		else if (di->cache.flags & BQ27000_FLAG_EDV1)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
> -		else if (di->cache.flags & BQ27500_FLAG_SOCF)
> +		else if (di->cache.flags & BQ27000_FLAG_EDVF)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>  		else
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
>  	} else {
> -		if (di->cache.flags & BQ27000_FLAG_FC)
> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
> -		else if (di->cache.flags & BQ27000_FLAG_EDV1)
> +		else if (di->cache.flags & BQ27XXX_FLAG_SOC1)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
> -		else if (di->cache.flags & BQ27000_FLAG_EDVF)
> +		else if (di->cache.flags & BQ27XXX_FLAG_SOCF)
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>  		else
>  			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
> @@ -658,7 +827,7 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
>  {
>  	int volt;
>  
> -	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
> +	volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);
>  	if (volt < 0) {
>  		dev_err(di->dev, "error reading voltage\n");
>  		return volt;
> @@ -719,7 +888,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>  	case POWER_SUPPLY_PROP_TEMP:
>  		ret = bq27xxx_simple_value(di->cache.temperature, val);
>  		if (ret == 0)
> -			val->intval -= 2731;
> +			val->intval -= 2731; /* convert decidegree k to c */
>  		break;
>  	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
>  		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
> @@ -785,18 +954,27 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
>  
>  	psy_desc->name = name;
>  	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
> -	if (di->chip == BQ27425) {
> -		psy_desc->properties = bq27425_battery_props;
> -		psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props);
> -	} else if (di->chip == BQ27742) {
> -		psy_desc->properties = bq27742_battery_props;
> -		psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props);
> -	} else if (di->chip == BQ27510) {
> -		psy_desc->properties = bq27510_battery_props;
> -		psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props);
> +	if (di->chip == BQ27000) {
> +		psy_desc->properties = bq27000_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27000_battery_props);
> +	} else if (di->chip == BQ27010) {
> +		psy_desc->properties = bq27010_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27010_battery_props);
> +	} else if (di->chip == BQ27500) {
> +		psy_desc->properties = bq27500_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27500_battery_props);
> +	} else if (di->chip == BQ27530) {
> +		psy_desc->properties = bq27530_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27530_battery_props);
> +	} else if (di->chip == BQ27541) {
> +		psy_desc->properties = bq27541_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27541_battery_props);
> +	} else if (di->chip == BQ27545) {
> +		psy_desc->properties = bq27545_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27545_battery_props);
>  	} else {
> -		psy_desc->properties = bq27x00_battery_props;
> -		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
> +		psy_desc->properties = bq27421_battery_props;
> +		psy_desc->num_properties = ARRAY_SIZE(bq27421_battery_props);
>  	}

This if-else-if-else code is too long...

>  	psy_desc->get_property = bq27xxx_battery_get_property;
>  	psy_desc->external_power_changed = bq27xxx_external_power_changed;
> @@ -911,10 +1089,32 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
>  	di->chip = id->driver_data;
>  	di->bus.read = &bq27xxx_battery_i2c_read;
>  
> +	if (di->chip == BQ27000) {
> +		di->regs = bq27000_regs;
> +	} else if (di->chip == BQ27010) {
> +		di->regs = bq27010_regs;
> +	} else if (di->chip == BQ27500) {
> +		di->regs = bq27500_regs;
> +	} else if (di->chip == BQ27530) {
> +		di->regs = bq27530_regs;
> +	} else if (di->chip == BQ27541) {
> +		di->regs = bq27541_regs;
> +	} else if (di->chip == BQ27545) {
> +		di->regs = bq27545_regs;
> +	} else if (di->chip == BQ27421) {
> +		di->regs = bq27421_regs;
> +	} else {

... and this too.

What about creating array indexed by chip enum which will contains
pointers to _regs and _props? With something like this you could reduce
code to just two assignments and separate battery properties into
semantical array variable(s)...

> +		dev_err(&client->dev, "Unexpected gas gauge: %d\n", di->chip);
> +		di->regs = bq27000_regs;
> +	}
> +
>  	retval = bq27xxx_powersupply_init(di, name);
>  	if (retval)
>  		goto batt_failed;
>  
> +	/* Schedule a polling after about 1 min */
> +	schedule_delayed_work(&di->work, 60 * HZ);
> +
>  	i2c_set_clientdata(client, di);
>  
>  	return 0;
> @@ -941,11 +1141,22 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
>  }
>  
>  static const struct i2c_device_id bq27xxx_id[] = {
> -	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
> +	{ "bq27200", BQ27000 },
> +	{ "bq27210", BQ27010 },
>  	{ "bq27500", BQ27500 },
> -	{ "bq27425", BQ27425 },
> -	{ "bq27742", BQ27742 },
> -	{ "bq27510", BQ27510 },
> +	{ "bq27510", BQ27500 },
> +	{ "bq27520", BQ27500 },
> +	{ "bq27530", BQ27530 },
> +	{ "bq27531", BQ27530 },
> +	{ "bq27541", BQ27541 },
> +	{ "bq27542", BQ27541 },
> +	{ "bq27546", BQ27541 },
> +	{ "bq27742", BQ27541 },
> +	{ "bq27545", BQ27545 },
> +	{ "bq27421", BQ27421 },
> +	{ "bq27425", BQ27421 },
> +	{ "bq27441", BQ27421 },
> +	{ "bq27621", BQ27421 },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
> index a4efb10..45f6a7b 100644
> --- a/include/linux/power/bq27xxx_battery.h
> +++ b/include/linux/power/bq27xxx_battery.h
> @@ -12,7 +12,15 @@
>   *	register to be read. The return value should either be the content of
>   *	the passed register or an error value.
>   */
> -enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
> +enum bq27xxx_chip {
> +	BQ27000 = 1, /* bq27000, bq27200 */
> +	BQ27010, /* bq27010, bq27210 */
> +	BQ27500, /* bq27500, bq27510, bq27520 */
> +	BQ27530, /* bq27530, bq27531 */
> +	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
> +	BQ27545, /* bq27545 */
> +	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
> +};
>  
>  struct bq27xxx_platform_data {
>  	const char *name;

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device
  2015-09-21  8:41   ` Pali Rohár
@ 2015-09-21 18:40       ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-21 18:40 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On 09/21/2015 03:41 AM, Pali Rohár wrote:
> On Monday 14 September 2015 16:26:09 Andrew F. Davis wrote:
>> When initialized as a platform device the initializer must now specify
>> a device. An empty device name is no longer valid.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/power/bq27xxx_battery.c       | 9 ++++++---
>>   drivers/w1/slaves/w1_bq27000.c        | 1 +
>>   include/linux/power/bq27xxx_battery.h | 6 +++++-
>>   3 files changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
>> index e72055c..0734413 100644
>> --- a/drivers/power/bq27xxx_battery.c
>> +++ b/drivers/power/bq27xxx_battery.c
>> @@ -91,8 +91,6 @@ struct bq27xxx_access_methods {
>>   	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>>   };
>>
>> -enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
>> -
>>   struct bq27xxx_reg_cache {
>>   	int temperature;
>>   	int time_to_empty;
>> @@ -1036,6 +1034,11 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>>   		return -EINVAL;
>>   	}
>>
>> +	if (!pdata->chip) {
>> +		dev_err(&pdev->dev, "no device supplied\n");
>> +		return -EINVAL;
>> +	}
>> +
>>   	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
>>   	if (!di)
>>   		return -ENOMEM;
>> @@ -1043,7 +1046,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>>   	platform_set_drvdata(pdev, di);
>>
>>   	di->dev = &pdev->dev;
>> -	di->chip = BQ27000;
>> +	di->chip = pdata->chip;
>>
>>   	name = pdata->name ?: dev_name(&pdev->dev);
>>   	di->bus.read = &bq27xxx_battery_platform_read;
>> diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
>> index 8480531..9f4a86b 100644
>> --- a/drivers/w1/slaves/w1_bq27000.c
>> +++ b/drivers/w1/slaves/w1_bq27000.c
>> @@ -42,6 +42,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
>>   static struct bq27xxx_platform_data bq27000_battery_info = {
>>   	.read   = w1_bq27000_read,
>>   	.name   = "bq27000-battery",
>> +	.chip   = BQ27000,
>>   };
>>
>>   static int w1_bq27000_add_slave(struct w1_slave *sl)
>> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
>> index e70a93a..a4efb10 100644
>> --- a/include/linux/power/bq27xxx_battery.h
>> +++ b/include/linux/power/bq27xxx_battery.h
>> @@ -3,7 +3,8 @@
>>
>>   /**
>>    * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
>> - * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
>> + * @name: Name of the battery.
>> + * @chip: Chip class number of this device.
>>    * @read: HDQ read callback.
>>    *	This function should provide access to the HDQ bus the battery is
>>    *	connected to.
>> @@ -11,8 +12,11 @@
>>    *	register to be read. The return value should either be the content of
>>    *	the passed register or an error value.
>>    */
>> +enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
>> +
>>   struct bq27xxx_platform_data {
>>   	const char *name;
>> +	enum bq27xxx_chip chip;
>
> Do we still need name property if we have chip enum? And if yes who use
> it and why?
>

The enum only relates to the family of chip, not its name, passing name with
platform data allows us to give unique names to the supply should we need.

>>   	int (*read)(struct device *dev, unsigned int);
>>   };
>>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device
@ 2015-09-21 18:40       ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-21 18:40 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On 09/21/2015 03:41 AM, Pali Rohár wrote:
> On Monday 14 September 2015 16:26:09 Andrew F. Davis wrote:
>> When initialized as a platform device the initializer must now specify
>> a device. An empty device name is no longer valid.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/power/bq27xxx_battery.c       | 9 ++++++---
>>   drivers/w1/slaves/w1_bq27000.c        | 1 +
>>   include/linux/power/bq27xxx_battery.h | 6 +++++-
>>   3 files changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
>> index e72055c..0734413 100644
>> --- a/drivers/power/bq27xxx_battery.c
>> +++ b/drivers/power/bq27xxx_battery.c
>> @@ -91,8 +91,6 @@ struct bq27xxx_access_methods {
>>   	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>>   };
>>
>> -enum bq27xxx_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510};
>> -
>>   struct bq27xxx_reg_cache {
>>   	int temperature;
>>   	int time_to_empty;
>> @@ -1036,6 +1034,11 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>>   		return -EINVAL;
>>   	}
>>
>> +	if (!pdata->chip) {
>> +		dev_err(&pdev->dev, "no device supplied\n");
>> +		return -EINVAL;
>> +	}
>> +
>>   	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
>>   	if (!di)
>>   		return -ENOMEM;
>> @@ -1043,7 +1046,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
>>   	platform_set_drvdata(pdev, di);
>>
>>   	di->dev = &pdev->dev;
>> -	di->chip = BQ27000;
>> +	di->chip = pdata->chip;
>>
>>   	name = pdata->name ?: dev_name(&pdev->dev);
>>   	di->bus.read = &bq27xxx_battery_platform_read;
>> diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
>> index 8480531..9f4a86b 100644
>> --- a/drivers/w1/slaves/w1_bq27000.c
>> +++ b/drivers/w1/slaves/w1_bq27000.c
>> @@ -42,6 +42,7 @@ static int w1_bq27000_read(struct device *dev, unsigned int reg)
>>   static struct bq27xxx_platform_data bq27000_battery_info = {
>>   	.read   = w1_bq27000_read,
>>   	.name   = "bq27000-battery",
>> +	.chip   = BQ27000,
>>   };
>>
>>   static int w1_bq27000_add_slave(struct w1_slave *sl)
>> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
>> index e70a93a..a4efb10 100644
>> --- a/include/linux/power/bq27xxx_battery.h
>> +++ b/include/linux/power/bq27xxx_battery.h
>> @@ -3,7 +3,8 @@
>>
>>   /**
>>    * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
>> - * @name: Name of the battery. If NULL the driver will fallback to "bq27000".
>> + * @name: Name of the battery.
>> + * @chip: Chip class number of this device.
>>    * @read: HDQ read callback.
>>    *	This function should provide access to the HDQ bus the battery is
>>    *	connected to.
>> @@ -11,8 +12,11 @@
>>    *	register to be read. The return value should either be the content of
>>    *	the passed register or an error value.
>>    */
>> +enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
>> +
>>   struct bq27xxx_platform_data {
>>   	const char *name;
>> +	enum bq27xxx_chip chip;
>
> Do we still need name property if we have chip enum? And if yes who use
> it and why?
>

The enum only relates to the family of chip, not its name, passing name with
platform data allows us to give unique names to the supply should we need.

>>   	int (*read)(struct device *dev, unsigned int);
>>   };
>>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices
  2015-09-21  8:46   ` Pali Rohár
@ 2015-09-21 19:02       ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-21 19:02 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On 09/21/2015 03:46 AM, Pali Rohár wrote:
> On Monday 14 September 2015 16:26:11 Andrew F. Davis wrote:
>> Add support for additional devices and register equivalent family devices
>> including the bq27010, bq27210, bq27500, bq27510, bq27520, bq27530,
>> bq27531, bq27541, bq27542, bq27546, bq27545, bq27441, bq27421, and the
>> bq27641.
>>
>> To facilitate this process the register mapings have been moved to tables
>> and other small cleanups have been made.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/power/bq27xxx_battery.c       | 627 +++++++++++++++++++++++-----------
>>   include/linux/power/bq27xxx_battery.h |  10 +-
>>   2 files changed, 428 insertions(+), 209 deletions(-)
>>
>> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
>> index 1ff88ad..3098609 100644
>> --- a/drivers/power/bq27xxx_battery.c
>> +++ b/drivers/power/bq27xxx_battery.c
>> @@ -17,11 +17,24 @@
>>    * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>>    *
>>    * Datasheets:
>> - * http://focus.ti.com/docs/prod/folders/print/bq27000.html
>> - * http://focus.ti.com/docs/prod/folders/print/bq27500.html
>> + * http://www.ti.com/product/bq27000
>> + * http://www.ti.com/product/bq27200
>> + * http://www.ti.com/product/bq27010
>> + * http://www.ti.com/product/bq27210
>> + * http://www.ti.com/product/bq27500
>> + * http://www.ti.com/product/bq27510-g3
>> + * http://www.ti.com/product/bq27520-g4
>> + * http://www.ti.com/product/bq27530-g1
>> + * http://www.ti.com/product/bq27531-g1
>> + * http://www.ti.com/product/bq27541-g1
>> + * http://www.ti.com/product/bq27542-g1
>> + * http://www.ti.com/product/bq27546-g1
>> + * http://www.ti.com/product/bq27742-g1
>> + * http://www.ti.com/product/bq27545-g1
>> + * http://www.ti.com/product/bq27421-g1
>>    * http://www.ti.com/product/bq27425-g1
>> - * http://www.ti.com/product/BQ27742-G1
>> - * http://www.ti.com/product/BQ27510-G3
>> + * http://www.ti.com/product/bq27411-g1
>> + * http://www.ti.com/product/bq27621-g1
>>    */
>>
>>   #include <linux/device.h>
>> @@ -43,54 +56,57 @@
>>
>>   #define BQ27XXX_MANUFACTURER	"Texas Instruments"
>>
>> -#define BQ27x00_REG_TEMP	0x06
>> -#define BQ27x00_REG_VOLT	0x08
>> -#define BQ27x00_REG_AI		0x14
>> -#define BQ27x00_REG_FLAGS	0x0A
>> -#define BQ27x00_REG_TTE		0x16
>> -#define BQ27x00_REG_TTF		0x18
>> -#define BQ27x00_REG_TTECP	0x26
>> -#define BQ27x00_REG_NAC		0x0C /* Nominal available capacity */
>> -#define BQ27x00_REG_LMD		0x12 /* Last measured discharge */
>> -#define BQ27x00_REG_CYCT	0x2A /* Cycle count total */
>> -#define BQ27x00_REG_AE		0x22 /* Available energy */
>> -#define BQ27x00_POWER_AVG	0x24
>> -
>> -#define BQ27000_REG_RSOC	0x0B /* Relative State-of-Charge */
>> -#define BQ27000_REG_ILMD	0x76 /* Initial last measured discharge */
>> +/* BQ27XXX Flags */
>> +#define BQ27XXX_FLAG_DSC	BIT(0)
>> +#define BQ27XXX_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
>> +#define BQ27XXX_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
>> +#define BQ27XXX_FLAG_FC		BIT(9)
>> +#define BQ27XXX_FLAG_OTD	BIT(14)
>> +#define BQ27XXX_FLAG_OTC	BIT(15)
>> +
>> +/* BQ27000 has different layout for Flags register */
>>   #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
>>   #define BQ27000_FLAG_EDV1	BIT(1) /* First End-of-Discharge-Voltage flag */
>>   #define BQ27000_FLAG_CI		BIT(4) /* Capacity Inaccurate flag */
>>   #define BQ27000_FLAG_FC		BIT(5)
>>   #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
>>
>> -#define BQ27500_REG_SOC		0x2C
>> -#define BQ27500_REG_DCAP	0x3C /* Design capacity */
>> -#define BQ27500_FLAG_DSC	BIT(0)
>> -#define BQ27500_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
>> -#define BQ27500_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
>> -#define BQ27500_FLAG_FC		BIT(9)
>> -#define BQ27500_FLAG_OTC	BIT(15)
>> -
>> -#define BQ27742_POWER_AVG	0x76
>> -
>> -#define BQ27510_REG_SOC		0x20
>> -#define BQ27510_REG_DCAP	0x2E /* Design capacity */
>> -#define BQ27510_REG_CYCT	0x1E /* Cycle count total */
>> -
>> -/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
>> -#define BQ27425_REG_OFFSET	0x04
>> -#define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
>> -#define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
>> -
>> -#define BQ27XXX_RS			20 /* Resistor sense */
>> -#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
>> +#define BQ27XXX_RS			(20) /* Resistor sense mOhm */
>> +#define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
>> +#define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
>>
>>   struct bq27xxx_device_info;
>>   struct bq27xxx_access_methods {
>>   	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>>   };
>>
>> +#define INVALID_REG_ADDR	0xff
>> +
>> +/*
>> + * bq27xxx_reg_index - Register names
>> + *
>> + * These are indexes into a device's register mapping array.
>> + */
>> +enum bq27xxx_reg_index {
>> +	BQ27XXX_REG_CTRL = 0,	/* Control */
>> +	BQ27XXX_REG_TEMP,	/* Temperature */
>> +	BQ27XXX_REG_INT_TEMP,	/* Internal Temperature */
>> +	BQ27XXX_REG_VOLT,	/* Voltage */
>> +	BQ27XXX_REG_AI,		/* Average Current */
>> +	BQ27XXX_REG_FLAGS,	/* Flags */
>> +	BQ27XXX_REG_TTE,	/* Time-to-Empty */
>> +	BQ27XXX_REG_TTF,	/* Time-to-Full */
>> +	BQ27XXX_REG_TTES,	/* Time-to-Empty Standby */
>> +	BQ27XXX_REG_TTECP,	/* Time-to-Empty at Constant Power */
>> +	BQ27XXX_REG_NAC,	/* Nominal Available Capacity */
>> +	BQ27XXX_REG_FCC,	/* Full Charge Capacity */
>> +	BQ27XXX_REG_CYCT,	/* Cycle Count */
>> +	BQ27XXX_REG_AE,		/* Available Energy */
>> +	BQ27XXX_REG_SOC,	/* State-of-Charge */
>> +	BQ27XXX_REG_DCAP,	/* Design Capacity */
>> +	BQ27XXX_REG_AP,		/* Average Power */
>> +};
>> +
>>   struct bq27xxx_reg_cache {
>>   	int temperature;
>>   	int time_to_empty;
>> @@ -121,9 +137,152 @@ struct bq27xxx_device_info {
>>   	struct bq27xxx_access_methods bus;
>>
>>   	struct mutex lock;
>> +
>> +	u8 *regs;
>> +};
>> +
>> +/* Register mappings */
>> +static u8 bq27000_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	0x18,	/* TTF		*/
>> +	0x1c,	/* TTES		*/
>> +	0x26,	/* TTECP	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	0x22,	/* AE		*/
>> +	0x0b,	/* SOC(RSOC)	*/
>> +	0x76,	/* DCAP(ILMD)	*/
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27010_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	0x18,	/* TTF		*/
>> +	0x1c,	/* TTES		*/
>> +	0x26,	/* TTECP	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x0b,	/* SOC(RSOC)	*/
>> +	0x76,	/* DCAP(ILMD)	*/
>> +	INVALID_REG_ADDR,	/* AP - NA	*/
>> +};
>> +
>> +static u8 bq27500_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	0x1a,	/* TTES		*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x1e,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x20,	/* SOC(RSOC)	*/
>> +	0x2e,	/* DCAP(ILMD)	*/
>> +	INVALID_REG_ADDR,	/* AP - NA	*/
>>   };
>>
>> -static enum power_supply_property bq27x00_battery_props[] = {
>> +static u8 bq27530_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x32,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	INVALID_REG_ADDR,	/* DCAP - NA	*/
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27541_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	0x3c,	/* DCAP		*/
>> +	0x76,	/* AP		*/
>> +};
>> +
>> +static u8 bq27545_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	INVALID_REG_ADDR,	/* DCAP - NA */
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27421_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x02,	/* TEMP		*/
>> +	0x1e,	/* INT TEMP	*/
>> +	0x04,	/* VOLT		*/
>> +	0x10,	/* AVG CURR	*/
>> +	0x06,	/* FLAGS	*/
>> +	INVALID_REG_ADDR,	/* TTE - NA	*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x08,	/* NAC		*/
>> +	0x0e,	/* FCC		*/
>> +	INVALID_REG_ADDR,	/* CYCT - NA	*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x1c,	/* SOC		*/
>> +	0x3c,	/* DCAP		*/
>> +	0x18,	/* AP		*/
>> +};
>> +
>> +static enum power_supply_property bq27000_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -145,7 +304,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27425_battery_props[] = {
>> +static enum power_supply_property bq27010_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -153,14 +312,19 @@ static enum power_supply_property bq27425_battery_props[] = {
>>   	POWER_SUPPLY_PROP_CAPACITY,
>>   	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>>   	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
>> +	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
>>   	POWER_SUPPLY_PROP_TECHNOLOGY,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL,
>>   	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_HEALTH,
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27742_battery_props[] = {
>> +static enum power_supply_property bq27500_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -174,12 +338,29 @@ static enum power_supply_property bq27742_battery_props[] = {
>>   	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>>   	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>> +static enum power_supply_property bq27530_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_POWER_AVG,
>>   	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27510_battery_props[] = {
>> +static enum power_supply_property bq27541_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -198,6 +379,39 @@ static enum power_supply_property bq27510_battery_props[] = {
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> +static enum power_supply_property bq27545_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>> +	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_POWER_AVG,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>> +static enum power_supply_property bq27421_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>>   static unsigned int poll_interval = 360;
>>   module_param(poll_interval, uint, 0644);
>>   MODULE_PARM_DESC(poll_interval,
>> @@ -207,25 +421,14 @@ MODULE_PARM_DESC(poll_interval,
>>    * Common code for BQ27xxx devices
>>    */
>>
>> -static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
>> +static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
>>   			       bool single)
>>   {
>> -	if (di->chip == BQ27425)
>> -		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
>> -	return di->bus.read(di, reg, single);
>> -}
>> +	/* Reports EINVAL for invalid/missing registers */
>> +	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
>> +		return -EINVAL;
>>
>> -/*
>> - * Higher versions of the chip like BQ27425 and BQ27500
>> - * differ from BQ27000 and BQ27200 in calculation of certain
>> - * parameters. Hence we need to check for the chip type.
>> - */
>> -static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
>> -{
>> -	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
>> -	    || di->chip == BQ27510)
>> -		return true;
>> -	return false;
>> +	return di->bus.read(di, di->regs[reg_index], single);
>>   }
>>
>>   /*
>> @@ -236,14 +439,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
>>   {
>>   	int soc;
>>
>> -	if (di->chip == BQ27500 || di->chip == BQ27742)
>> -		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
>> -	else if (di->chip == BQ27510)
>> -		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
>> -	else if (di->chip == BQ27425)
>> -		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
>> -	else /* for the bq27000 we read the "relative" SoC register */
>> -		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
>> +	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
>>
>>   	if (soc < 0)
>>   		dev_dbg(di->dev, "error reading State-of-Charge\n");
>> @@ -266,10 +462,10 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>>   		return charge;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di))
>> -		charge *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		charge = charge * 3570 / BQ27XXX_RS;
>> +		charge *= 1000;
>>
>>   	return charge;
>>   }
>> @@ -281,57 +477,46 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>>   static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
>>   {
>>   	int flags;
>> -	bool is_bq27500 = di->chip == BQ27500;
>> -	bool is_bq27742 = di->chip == BQ27742;
>> -	bool is_higher = bq27xxx_is_chip_version_higher(di);
>> -	bool flags_1b = !(is_bq27500 || is_bq27742);
>>
>> -	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
>> -	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
>> -		return -ENODATA;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
>> +		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
>> +			return -ENODATA;
>> +	}
>>
>> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
>> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
>>   }
>>
>>   /*
>> - * Return the battery Last measured discharge in µAh
>> + * Return the battery Full Charge Capacity in µAh
>>    * Or < 0 if something fails.
>>    */
>> -static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
>> +static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di)
>>   {
>> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
>> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC);
>>   }
>>
>>   /*
>> - * Return the battery Initial last measured discharge in µAh
>> + * Return the Design Capacity in µAh
>>    * Or < 0 if something fails.
>>    */
>> -static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
>> +static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
>>   {
>> -	int ilmd;
>> +	int dcap;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->chip == BQ27425)
>> -			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
>> -		else if (di->chip == BQ27510)
>> -			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
>> -		else
>> -			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
>> -	} else {
>> -		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
>> -	}
>> +	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
>>
>> -	if (ilmd < 0) {
>> +	if (dcap < 0) {
>>   		dev_dbg(di->dev, "error reading initial last measured discharge\n");
>> -		return ilmd;
>> +		return dcap;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di))
>> -		ilmd *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
>> +		dcap *= 1000;
>>
>> -	return ilmd;
>> +	return dcap;
>>   }
>>
>>   /*
>> @@ -342,16 +527,16 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
>>   {
>>   	int ae;
>>
>> -	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
>> +	ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);
>>   	if (ae < 0) {
>>   		dev_dbg(di->dev, "error reading available energy\n");
>>   		return ae;
>>   	}
>>
>> -	if (di->chip == BQ27500)
>> -		ae *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		ae = ae * 29200 / BQ27XXX_RS;
>> +		ae *= 1000;
>>
>>   	return ae;
>>   }
>> @@ -364,13 +549,13 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
>>   {
>>   	int temp;
>>
>> -	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
>> +	temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);
>>   	if (temp < 0) {
>>   		dev_err(di->dev, "error reading temperature\n");
>>   		return temp;
>>   	}
>>
>> -	if (!bq27xxx_is_chip_version_higher(di))
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>>   		temp = 5 * temp / 2;
>>
>>   	return temp;
>> @@ -384,10 +569,7 @@ static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
>>   {
>>   	int cyct;
>>
>> -	if (di->chip == BQ27510)
>> -		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
>> -	else
>> -		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
>> +	cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);
>>   	if (cyct < 0)
>>   		dev_err(di->dev, "error reading cycle count total\n");
>>
>> @@ -419,21 +601,32 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
>>    * Read an average power register.
>>    * Return < 0 if something fails.
>>    */
>> -static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
>> +static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
>>   {
>>   	int tval;
>>
>> -	tval = bq27xxx_read(di, reg, false);
>> +	tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
>>   	if (tval < 0) {
>> -		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
>> -			reg, tval);
>> +		dev_err(di->dev, "error reading average power register  %02x: %d\n",
>> +			BQ27XXX_REG_AP, tval);
>>   		return tval;
>>   	}
>>
>> -	if (di->chip == BQ27500)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
>> +	else
>>   		return tval;
>> +}
>> +
>> +/*
>> + * Returns true if a battery over temperature condition is detected
>> + */
>> +static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>> +{
>> +	if (di->chip == BQ27500 || di->chip == BQ27541)
>> +		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
>>   	else
>> -		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
>> +		return flags & BQ27XXX_FLAG_OTC;
>>   }
>>
>>   /*
>> @@ -442,53 +635,43 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
>>    */
>>   static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
>>   {
>> -	int tval;
>> +	u16 tval;
>>
>> -	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
>> +	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>>   	if (tval < 0) {
>>   		dev_err(di->dev, "error reading flag register:%d\n", tval);
>>   		return tval;
>>   	}
>>
>> -	if (di->chip == BQ27500) {
>> -		if (tval & BQ27500_FLAG_SOCF)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		if (tval & BQ27000_FLAG_EDV1)
>>   			tval = POWER_SUPPLY_HEALTH_DEAD;
>> -		else if (tval & BQ27500_FLAG_OTC)
>> -			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>>   		else
>>   			tval = POWER_SUPPLY_HEALTH_GOOD;
>> -		return tval;
>> -	} else if (di->chip == BQ27510) {
>> -		if (tval & BQ27500_FLAG_OTC)
>> -			return POWER_SUPPLY_HEALTH_OVERHEAT;
>> -		return POWER_SUPPLY_HEALTH_GOOD;
>>   	} else {
>> -		if (tval & BQ27000_FLAG_EDV1)
>> +		if (tval & BQ27XXX_FLAG_SOCF)
>>   			tval = POWER_SUPPLY_HEALTH_DEAD;
>> +		else if (bq27xxx_battery_overtemp(di, tval))
>> +			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>>   		else
>>   			tval = POWER_SUPPLY_HEALTH_GOOD;
>> -		return tval;
>>   	}
>>
>> -	return -1;
>> +	return tval;
>>   }
>>
>>   static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   {
>>   	struct bq27xxx_reg_cache cache = {0, };
>> -	bool is_bq27500 = di->chip == BQ27500;
>> -	bool is_bq27510 = di->chip == BQ27510;
>> -	bool is_bq27425 = di->chip == BQ27425;
>> -	bool is_bq27742 = di->chip == BQ27742;
>> -	bool flags_1b = !(is_bq27500 || is_bq27742);
>> +	bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
>> +	bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
>>
>> -	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
>> +	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
>>   	if ((cache.flags & 0xff) == 0xff)
>> -		/* read error */
>> -		cache.flags = -1;
>> +		cache.flags = -1; /* read error */
>>   	if (cache.flags >= 0) {
>> -		if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510
>> -				&& (cache.flags & BQ27000_FLAG_CI)) {
>> +		cache.temperature = bq27xxx_battery_read_temperature(di);
>> +		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
>>   			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
>>   			cache.capacity = -ENODATA;
>>   			cache.energy = -ENODATA;
>> @@ -498,41 +681,26 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   			cache.charge_full = -ENODATA;
>>   			cache.health = -ENODATA;
>>   		} else {
>> +			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
>> +				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
>> +			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
>> +				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
>> +			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
>> +				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
>> +			cache.charge_full = bq27xxx_battery_read_fcc(di);
>>   			cache.capacity = bq27xxx_battery_read_soc(di);
>> -			if (is_bq27742 || is_bq27510)
>> -				cache.time_to_empty =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTE);
>> -			else if (!is_bq27425) {
>> +			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
>>   				cache.energy = bq27xxx_battery_read_energy(di);
>> -				cache.time_to_empty =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTE);
>> -				cache.time_to_empty_avg =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTECP);
>> -				cache.time_to_full =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTF);
>> -			}
>> -			cache.charge_full = bq27xxx_battery_read_lmd(di);
>>   			cache.health = bq27xxx_battery_read_health(di);
>>   		}
>> -		cache.temperature = bq27xxx_battery_read_temperature(di);
>> -		if (!is_bq27425)
>> +		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
>>   			cache.cycle_count = bq27xxx_battery_read_cyct(di);
>> -		if (is_bq27742)
>> -			cache.power_avg =
>> -				bq27xxx_battery_read_pwr_avg(di,
>> -						BQ27742_POWER_AVG);
>> -		else
>> -			cache.power_avg =
>> -				bq27xxx_battery_read_pwr_avg(di,
>> -						BQ27x00_POWER_AVG);
>> +		if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
>> +			cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
>>
>>   		/* We only have to read charge design full once */
>>   		if (di->charge_design_full <= 0)
>> -			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
>> +			di->charge_design_full = bq27xxx_battery_read_dcap(di);
>>   	}
>>
>>   	if (di->cache.capacity != cache.capacity)
>> @@ -547,7 +715,8 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   static void bq27xxx_battery_poll(struct work_struct *work)
>>   {
>>   	struct bq27xxx_device_info *di =
>> -		container_of(work, struct bq27xxx_device_info, work.work);
>> +			container_of(work, struct bq27xxx_device_info,
>> +				     work.work);
>>
>>   	bq27xxx_battery_update(di);
>>
>> @@ -569,23 +738,23 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
>>   	int curr;
>>   	int flags;
>>
>> -	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
>> +	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
>>   	if (curr < 0) {
>>   		dev_err(di->dev, "error reading current\n");
>>   		return curr;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		/* bq27500 returns signed value */
>> -		val->intval = (int)((s16)curr) * 1000;
>> -	} else {
>> -		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>>   		if (flags & BQ27000_FLAG_CHGS) {
>>   			dev_dbg(di->dev, "negative current!\n");
>>   			curr = -curr;
>>   		}
>>
>> -		val->intval = curr * 3570 / BQ27XXX_RS;
>> +		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>> +	} else {
>> +		/* Other gauges return signed value */
>> +		val->intval = (int)((s16)curr) * 1000;
>>   	}
>>
>>   	return 0;
>> @@ -596,14 +765,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>>   {
>>   	int status;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->cache.flags & BQ27500_FLAG_FC)
>> -			status = POWER_SUPPLY_STATUS_FULL;
>> -		else if (di->cache.flags & BQ27500_FLAG_DSC)
>> -			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> -		else
>> -			status = POWER_SUPPLY_STATUS_CHARGING;
>> -	} else {
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>>   		if (di->cache.flags & BQ27000_FLAG_FC)
>>   			status = POWER_SUPPLY_STATUS_FULL;
>>   		else if (di->cache.flags & BQ27000_FLAG_CHGS)
>> @@ -612,6 +774,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>>   			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
>>   		else
>>   			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> +	} else {
>> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
>> +			status = POWER_SUPPLY_STATUS_FULL;
>> +		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
>> +			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> +		else
>> +			status = POWER_SUPPLY_STATUS_CHARGING;
>>   	}
>>
>>   	val->intval = status;
>> @@ -624,21 +793,21 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
>>   {
>>   	int level;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->cache.flags & BQ27500_FLAG_FC)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		if (di->cache.flags & BQ27000_FLAG_FC)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
>> -		else if (di->cache.flags & BQ27500_FLAG_SOC1)
>> +		else if (di->cache.flags & BQ27000_FLAG_EDV1)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
>> -		else if (di->cache.flags & BQ27500_FLAG_SOCF)
>> +		else if (di->cache.flags & BQ27000_FLAG_EDVF)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>>   		else
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
>>   	} else {
>> -		if (di->cache.flags & BQ27000_FLAG_FC)
>> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
>> -		else if (di->cache.flags & BQ27000_FLAG_EDV1)
>> +		else if (di->cache.flags & BQ27XXX_FLAG_SOC1)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
>> -		else if (di->cache.flags & BQ27000_FLAG_EDVF)
>> +		else if (di->cache.flags & BQ27XXX_FLAG_SOCF)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>>   		else
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
>> @@ -658,7 +827,7 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
>>   {
>>   	int volt;
>>
>> -	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
>> +	volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);
>>   	if (volt < 0) {
>>   		dev_err(di->dev, "error reading voltage\n");
>>   		return volt;
>> @@ -719,7 +888,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>>   	case POWER_SUPPLY_PROP_TEMP:
>>   		ret = bq27xxx_simple_value(di->cache.temperature, val);
>>   		if (ret == 0)
>> -			val->intval -= 2731;
>> +			val->intval -= 2731; /* convert decidegree k to c */
>>   		break;
>>   	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
>>   		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
>> @@ -785,18 +954,27 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
>>
>>   	psy_desc->name = name;
>>   	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
>> -	if (di->chip == BQ27425) {
>> -		psy_desc->properties = bq27425_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props);
>> -	} else if (di->chip == BQ27742) {
>> -		psy_desc->properties = bq27742_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props);
>> -	} else if (di->chip == BQ27510) {
>> -		psy_desc->properties = bq27510_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props);
>> +	if (di->chip == BQ27000) {
>> +		psy_desc->properties = bq27000_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27000_battery_props);
>> +	} else if (di->chip == BQ27010) {
>> +		psy_desc->properties = bq27010_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27010_battery_props);
>> +	} else if (di->chip == BQ27500) {
>> +		psy_desc->properties = bq27500_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27500_battery_props);
>> +	} else if (di->chip == BQ27530) {
>> +		psy_desc->properties = bq27530_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27530_battery_props);
>> +	} else if (di->chip == BQ27541) {
>> +		psy_desc->properties = bq27541_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27541_battery_props);
>> +	} else if (di->chip == BQ27545) {
>> +		psy_desc->properties = bq27545_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27545_battery_props);
>>   	} else {
>> -		psy_desc->properties = bq27x00_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
>> +		psy_desc->properties = bq27421_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27421_battery_props);
>>   	}
>
> This if-else-if-else code is too long...
>
>>   	psy_desc->get_property = bq27xxx_battery_get_property;
>>   	psy_desc->external_power_changed = bq27xxx_external_power_changed;
>> @@ -911,10 +1089,32 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
>>   	di->chip = id->driver_data;
>>   	di->bus.read = &bq27xxx_battery_i2c_read;
>>
>> +	if (di->chip == BQ27000) {
>> +		di->regs = bq27000_regs;
>> +	} else if (di->chip == BQ27010) {
>> +		di->regs = bq27010_regs;
>> +	} else if (di->chip == BQ27500) {
>> +		di->regs = bq27500_regs;
>> +	} else if (di->chip == BQ27530) {
>> +		di->regs = bq27530_regs;
>> +	} else if (di->chip == BQ27541) {
>> +		di->regs = bq27541_regs;
>> +	} else if (di->chip == BQ27545) {
>> +		di->regs = bq27545_regs;
>> +	} else if (di->chip == BQ27421) {
>> +		di->regs = bq27421_regs;
>> +	} else {
>
> ... and this too.
>
> What about creating array indexed by chip enum which will contains
> pointers to _regs and _props? With something like this you could reduce
> code to just two assignments and separate battery properties into
> semantical array variable(s)...
>

That works, I'll do that.

>> +		dev_err(&client->dev, "Unexpected gas gauge: %d\n", di->chip);
>> +		di->regs = bq27000_regs;
>> +	}
>> +
>>   	retval = bq27xxx_powersupply_init(di, name);
>>   	if (retval)
>>   		goto batt_failed;
>>
>> +	/* Schedule a polling after about 1 min */
>> +	schedule_delayed_work(&di->work, 60 * HZ);
>> +
>>   	i2c_set_clientdata(client, di);
>>
>>   	return 0;
>> @@ -941,11 +1141,22 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
>>   }
>>
>>   static const struct i2c_device_id bq27xxx_id[] = {
>> -	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
>> +	{ "bq27200", BQ27000 },
>> +	{ "bq27210", BQ27010 },
>>   	{ "bq27500", BQ27500 },
>> -	{ "bq27425", BQ27425 },
>> -	{ "bq27742", BQ27742 },
>> -	{ "bq27510", BQ27510 },
>> +	{ "bq27510", BQ27500 },
>> +	{ "bq27520", BQ27500 },
>> +	{ "bq27530", BQ27530 },
>> +	{ "bq27531", BQ27530 },
>> +	{ "bq27541", BQ27541 },
>> +	{ "bq27542", BQ27541 },
>> +	{ "bq27546", BQ27541 },
>> +	{ "bq27742", BQ27541 },
>> +	{ "bq27545", BQ27545 },
>> +	{ "bq27421", BQ27421 },
>> +	{ "bq27425", BQ27421 },
>> +	{ "bq27441", BQ27421 },
>> +	{ "bq27621", BQ27421 },
>>   	{},
>>   };
>>   MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
>> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
>> index a4efb10..45f6a7b 100644
>> --- a/include/linux/power/bq27xxx_battery.h
>> +++ b/include/linux/power/bq27xxx_battery.h
>> @@ -12,7 +12,15 @@
>>    *	register to be read. The return value should either be the content of
>>    *	the passed register or an error value.
>>    */
>> -enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
>> +enum bq27xxx_chip {
>> +	BQ27000 = 1, /* bq27000, bq27200 */
>> +	BQ27010, /* bq27010, bq27210 */
>> +	BQ27500, /* bq27500, bq27510, bq27520 */
>> +	BQ27530, /* bq27530, bq27531 */
>> +	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
>> +	BQ27545, /* bq27545 */
>> +	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
>> +};
>>
>>   struct bq27xxx_platform_data {
>>   	const char *name;
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices
@ 2015-09-21 19:02       ` Andrew F. Davis
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew F. Davis @ 2015-09-21 19:02 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

On 09/21/2015 03:46 AM, Pali Rohár wrote:
> On Monday 14 September 2015 16:26:11 Andrew F. Davis wrote:
>> Add support for additional devices and register equivalent family devices
>> including the bq27010, bq27210, bq27500, bq27510, bq27520, bq27530,
>> bq27531, bq27541, bq27542, bq27546, bq27545, bq27441, bq27421, and the
>> bq27641.
>>
>> To facilitate this process the register mapings have been moved to tables
>> and other small cleanups have been made.
>>
>> Signed-off-by: Andrew F. Davis <afd@ti.com>
>> ---
>>   drivers/power/bq27xxx_battery.c       | 627 +++++++++++++++++++++++-----------
>>   include/linux/power/bq27xxx_battery.h |  10 +-
>>   2 files changed, 428 insertions(+), 209 deletions(-)
>>
>> diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
>> index 1ff88ad..3098609 100644
>> --- a/drivers/power/bq27xxx_battery.c
>> +++ b/drivers/power/bq27xxx_battery.c
>> @@ -17,11 +17,24 @@
>>    * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>>    *
>>    * Datasheets:
>> - * http://focus.ti.com/docs/prod/folders/print/bq27000.html
>> - * http://focus.ti.com/docs/prod/folders/print/bq27500.html
>> + * http://www.ti.com/product/bq27000
>> + * http://www.ti.com/product/bq27200
>> + * http://www.ti.com/product/bq27010
>> + * http://www.ti.com/product/bq27210
>> + * http://www.ti.com/product/bq27500
>> + * http://www.ti.com/product/bq27510-g3
>> + * http://www.ti.com/product/bq27520-g4
>> + * http://www.ti.com/product/bq27530-g1
>> + * http://www.ti.com/product/bq27531-g1
>> + * http://www.ti.com/product/bq27541-g1
>> + * http://www.ti.com/product/bq27542-g1
>> + * http://www.ti.com/product/bq27546-g1
>> + * http://www.ti.com/product/bq27742-g1
>> + * http://www.ti.com/product/bq27545-g1
>> + * http://www.ti.com/product/bq27421-g1
>>    * http://www.ti.com/product/bq27425-g1
>> - * http://www.ti.com/product/BQ27742-G1
>> - * http://www.ti.com/product/BQ27510-G3
>> + * http://www.ti.com/product/bq27411-g1
>> + * http://www.ti.com/product/bq27621-g1
>>    */
>>
>>   #include <linux/device.h>
>> @@ -43,54 +56,57 @@
>>
>>   #define BQ27XXX_MANUFACTURER	"Texas Instruments"
>>
>> -#define BQ27x00_REG_TEMP	0x06
>> -#define BQ27x00_REG_VOLT	0x08
>> -#define BQ27x00_REG_AI		0x14
>> -#define BQ27x00_REG_FLAGS	0x0A
>> -#define BQ27x00_REG_TTE		0x16
>> -#define BQ27x00_REG_TTF		0x18
>> -#define BQ27x00_REG_TTECP	0x26
>> -#define BQ27x00_REG_NAC		0x0C /* Nominal available capacity */
>> -#define BQ27x00_REG_LMD		0x12 /* Last measured discharge */
>> -#define BQ27x00_REG_CYCT	0x2A /* Cycle count total */
>> -#define BQ27x00_REG_AE		0x22 /* Available energy */
>> -#define BQ27x00_POWER_AVG	0x24
>> -
>> -#define BQ27000_REG_RSOC	0x0B /* Relative State-of-Charge */
>> -#define BQ27000_REG_ILMD	0x76 /* Initial last measured discharge */
>> +/* BQ27XXX Flags */
>> +#define BQ27XXX_FLAG_DSC	BIT(0)
>> +#define BQ27XXX_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
>> +#define BQ27XXX_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
>> +#define BQ27XXX_FLAG_FC		BIT(9)
>> +#define BQ27XXX_FLAG_OTD	BIT(14)
>> +#define BQ27XXX_FLAG_OTC	BIT(15)
>> +
>> +/* BQ27000 has different layout for Flags register */
>>   #define BQ27000_FLAG_EDVF	BIT(0) /* Final End-of-Discharge-Voltage flag */
>>   #define BQ27000_FLAG_EDV1	BIT(1) /* First End-of-Discharge-Voltage flag */
>>   #define BQ27000_FLAG_CI		BIT(4) /* Capacity Inaccurate flag */
>>   #define BQ27000_FLAG_FC		BIT(5)
>>   #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
>>
>> -#define BQ27500_REG_SOC		0x2C
>> -#define BQ27500_REG_DCAP	0x3C /* Design capacity */
>> -#define BQ27500_FLAG_DSC	BIT(0)
>> -#define BQ27500_FLAG_SOCF	BIT(1) /* State-of-Charge threshold final */
>> -#define BQ27500_FLAG_SOC1	BIT(2) /* State-of-Charge threshold 1 */
>> -#define BQ27500_FLAG_FC		BIT(9)
>> -#define BQ27500_FLAG_OTC	BIT(15)
>> -
>> -#define BQ27742_POWER_AVG	0x76
>> -
>> -#define BQ27510_REG_SOC		0x20
>> -#define BQ27510_REG_DCAP	0x2E /* Design capacity */
>> -#define BQ27510_REG_CYCT	0x1E /* Cycle count total */
>> -
>> -/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
>> -#define BQ27425_REG_OFFSET	0x04
>> -#define BQ27425_REG_SOC		(0x1C + BQ27425_REG_OFFSET)
>> -#define BQ27425_REG_DCAP	(0x3C + BQ27425_REG_OFFSET)
>> -
>> -#define BQ27XXX_RS			20 /* Resistor sense */
>> -#define BQ27XXX_POWER_CONSTANT		(256 * 29200 / 1000)
>> +#define BQ27XXX_RS			(20) /* Resistor sense mOhm */
>> +#define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
>> +#define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
>>
>>   struct bq27xxx_device_info;
>>   struct bq27xxx_access_methods {
>>   	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
>>   };
>>
>> +#define INVALID_REG_ADDR	0xff
>> +
>> +/*
>> + * bq27xxx_reg_index - Register names
>> + *
>> + * These are indexes into a device's register mapping array.
>> + */
>> +enum bq27xxx_reg_index {
>> +	BQ27XXX_REG_CTRL = 0,	/* Control */
>> +	BQ27XXX_REG_TEMP,	/* Temperature */
>> +	BQ27XXX_REG_INT_TEMP,	/* Internal Temperature */
>> +	BQ27XXX_REG_VOLT,	/* Voltage */
>> +	BQ27XXX_REG_AI,		/* Average Current */
>> +	BQ27XXX_REG_FLAGS,	/* Flags */
>> +	BQ27XXX_REG_TTE,	/* Time-to-Empty */
>> +	BQ27XXX_REG_TTF,	/* Time-to-Full */
>> +	BQ27XXX_REG_TTES,	/* Time-to-Empty Standby */
>> +	BQ27XXX_REG_TTECP,	/* Time-to-Empty at Constant Power */
>> +	BQ27XXX_REG_NAC,	/* Nominal Available Capacity */
>> +	BQ27XXX_REG_FCC,	/* Full Charge Capacity */
>> +	BQ27XXX_REG_CYCT,	/* Cycle Count */
>> +	BQ27XXX_REG_AE,		/* Available Energy */
>> +	BQ27XXX_REG_SOC,	/* State-of-Charge */
>> +	BQ27XXX_REG_DCAP,	/* Design Capacity */
>> +	BQ27XXX_REG_AP,		/* Average Power */
>> +};
>> +
>>   struct bq27xxx_reg_cache {
>>   	int temperature;
>>   	int time_to_empty;
>> @@ -121,9 +137,152 @@ struct bq27xxx_device_info {
>>   	struct bq27xxx_access_methods bus;
>>
>>   	struct mutex lock;
>> +
>> +	u8 *regs;
>> +};
>> +
>> +/* Register mappings */
>> +static u8 bq27000_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	0x18,	/* TTF		*/
>> +	0x1c,	/* TTES		*/
>> +	0x26,	/* TTECP	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	0x22,	/* AE		*/
>> +	0x0b,	/* SOC(RSOC)	*/
>> +	0x76,	/* DCAP(ILMD)	*/
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27010_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	INVALID_REG_ADDR,	/* INT TEMP - NA*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	0x18,	/* TTF		*/
>> +	0x1c,	/* TTES		*/
>> +	0x26,	/* TTECP	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x0b,	/* SOC(RSOC)	*/
>> +	0x76,	/* DCAP(ILMD)	*/
>> +	INVALID_REG_ADDR,	/* AP - NA	*/
>> +};
>> +
>> +static u8 bq27500_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	0x1a,	/* TTES		*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x1e,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x20,	/* SOC(RSOC)	*/
>> +	0x2e,	/* DCAP(ILMD)	*/
>> +	INVALID_REG_ADDR,	/* AP - NA	*/
>>   };
>>
>> -static enum power_supply_property bq27x00_battery_props[] = {
>> +static u8 bq27530_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x32,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	INVALID_REG_ADDR,	/* DCAP - NA	*/
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27541_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	0x3c,	/* DCAP		*/
>> +	0x76,	/* AP		*/
>> +};
>> +
>> +static u8 bq27545_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x06,	/* TEMP		*/
>> +	0x28,	/* INT TEMP	*/
>> +	0x08,	/* VOLT		*/
>> +	0x14,	/* AVG CURR	*/
>> +	0x0a,	/* FLAGS	*/
>> +	0x16,	/* TTE		*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x0c,	/* NAC		*/
>> +	0x12,	/* LMD(FCC)	*/
>> +	0x2a,	/* CYCT		*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x2c,	/* SOC(RSOC)	*/
>> +	INVALID_REG_ADDR,	/* DCAP - NA */
>> +	0x24,	/* AP		*/
>> +};
>> +
>> +static u8 bq27421_regs[] = {
>> +	0x00,	/* CONTROL	*/
>> +	0x02,	/* TEMP		*/
>> +	0x1e,	/* INT TEMP	*/
>> +	0x04,	/* VOLT		*/
>> +	0x10,	/* AVG CURR	*/
>> +	0x06,	/* FLAGS	*/
>> +	INVALID_REG_ADDR,	/* TTE - NA	*/
>> +	INVALID_REG_ADDR,	/* TTF - NA	*/
>> +	INVALID_REG_ADDR,	/* TTES - NA	*/
>> +	INVALID_REG_ADDR,	/* TTECP - NA	*/
>> +	0x08,	/* NAC		*/
>> +	0x0e,	/* FCC		*/
>> +	INVALID_REG_ADDR,	/* CYCT - NA	*/
>> +	INVALID_REG_ADDR,	/* AE - NA	*/
>> +	0x1c,	/* SOC		*/
>> +	0x3c,	/* DCAP		*/
>> +	0x18,	/* AP		*/
>> +};
>> +
>> +static enum power_supply_property bq27000_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -145,7 +304,7 @@ static enum power_supply_property bq27x00_battery_props[] = {
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27425_battery_props[] = {
>> +static enum power_supply_property bq27010_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -153,14 +312,19 @@ static enum power_supply_property bq27425_battery_props[] = {
>>   	POWER_SUPPLY_PROP_CAPACITY,
>>   	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>>   	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
>> +	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
>>   	POWER_SUPPLY_PROP_TECHNOLOGY,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL,
>>   	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_HEALTH,
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27742_battery_props[] = {
>> +static enum power_supply_property bq27500_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -174,12 +338,29 @@ static enum power_supply_property bq27742_battery_props[] = {
>>   	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>>   	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>> +static enum power_supply_property bq27530_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>>   	POWER_SUPPLY_PROP_POWER_AVG,
>>   	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> -static enum power_supply_property bq27510_battery_props[] = {
>> +static enum power_supply_property bq27541_battery_props[] = {
>>   	POWER_SUPPLY_PROP_STATUS,
>>   	POWER_SUPPLY_PROP_PRESENT,
>>   	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> @@ -198,6 +379,39 @@ static enum power_supply_property bq27510_battery_props[] = {
>>   	POWER_SUPPLY_PROP_MANUFACTURER,
>>   };
>>
>> +static enum power_supply_property bq27545_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>> +	POWER_SUPPLY_PROP_HEALTH,
>> +	POWER_SUPPLY_PROP_CYCLE_COUNT,
>> +	POWER_SUPPLY_PROP_POWER_AVG,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>> +static enum power_supply_property bq27421_battery_props[] = {
>> +	POWER_SUPPLY_PROP_STATUS,
>> +	POWER_SUPPLY_PROP_PRESENT,
>> +	POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>> +	POWER_SUPPLY_PROP_CAPACITY,
>> +	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
>> +	POWER_SUPPLY_PROP_TEMP,
>> +	POWER_SUPPLY_PROP_TECHNOLOGY,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL,
>> +	POWER_SUPPLY_PROP_CHARGE_NOW,
>> +	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
>> +	POWER_SUPPLY_PROP_MANUFACTURER,
>> +};
>> +
>>   static unsigned int poll_interval = 360;
>>   module_param(poll_interval, uint, 0644);
>>   MODULE_PARM_DESC(poll_interval,
>> @@ -207,25 +421,14 @@ MODULE_PARM_DESC(poll_interval,
>>    * Common code for BQ27xxx devices
>>    */
>>
>> -static inline int bq27xxx_read(struct bq27xxx_device_info *di, u8 reg,
>> +static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
>>   			       bool single)
>>   {
>> -	if (di->chip == BQ27425)
>> -		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
>> -	return di->bus.read(di, reg, single);
>> -}
>> +	/* Reports EINVAL for invalid/missing registers */
>> +	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
>> +		return -EINVAL;
>>
>> -/*
>> - * Higher versions of the chip like BQ27425 and BQ27500
>> - * differ from BQ27000 and BQ27200 in calculation of certain
>> - * parameters. Hence we need to check for the chip type.
>> - */
>> -static bool bq27xxx_is_chip_version_higher(struct bq27xxx_device_info *di)
>> -{
>> -	if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742
>> -	    || di->chip == BQ27510)
>> -		return true;
>> -	return false;
>> +	return di->bus.read(di, di->regs[reg_index], single);
>>   }
>>
>>   /*
>> @@ -236,14 +439,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
>>   {
>>   	int soc;
>>
>> -	if (di->chip == BQ27500 || di->chip == BQ27742)
>> -		soc = bq27xxx_read(di, BQ27500_REG_SOC, false);
>> -	else if (di->chip == BQ27510)
>> -		soc = bq27xxx_read(di, BQ27510_REG_SOC, false);
>> -	else if (di->chip == BQ27425)
>> -		soc = bq27xxx_read(di, BQ27425_REG_SOC, false);
>> -	else /* for the bq27000 we read the "relative" SoC register */
>> -		soc = bq27xxx_read(di, BQ27000_REG_RSOC, true);
>> +	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
>>
>>   	if (soc < 0)
>>   		dev_dbg(di->dev, "error reading State-of-Charge\n");
>> @@ -266,10 +462,10 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>>   		return charge;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di))
>> -		charge *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		charge = charge * 3570 / BQ27XXX_RS;
>> +		charge *= 1000;
>>
>>   	return charge;
>>   }
>> @@ -281,57 +477,46 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
>>   static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
>>   {
>>   	int flags;
>> -	bool is_bq27500 = di->chip == BQ27500;
>> -	bool is_bq27742 = di->chip == BQ27742;
>> -	bool is_higher = bq27xxx_is_chip_version_higher(di);
>> -	bool flags_1b = !(is_bq27500 || is_bq27742);
>>
>> -	flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
>> -	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
>> -		return -ENODATA;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
>> +		if (flags >= 0 && (flags & BQ27000_FLAG_CI))
>> +			return -ENODATA;
>> +	}
>>
>> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_NAC);
>> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
>>   }
>>
>>   /*
>> - * Return the battery Last measured discharge in µAh
>> + * Return the battery Full Charge Capacity in µAh
>>    * Or < 0 if something fails.
>>    */
>> -static inline int bq27xxx_battery_read_lmd(struct bq27xxx_device_info *di)
>> +static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di)
>>   {
>> -	return bq27xxx_battery_read_charge(di, BQ27x00_REG_LMD);
>> +	return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC);
>>   }
>>
>>   /*
>> - * Return the battery Initial last measured discharge in µAh
>> + * Return the Design Capacity in µAh
>>    * Or < 0 if something fails.
>>    */
>> -static int bq27xxx_battery_read_ilmd(struct bq27xxx_device_info *di)
>> +static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di)
>>   {
>> -	int ilmd;
>> +	int dcap;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->chip == BQ27425)
>> -			ilmd = bq27xxx_read(di, BQ27425_REG_DCAP, false);
>> -		else if (di->chip == BQ27510)
>> -			ilmd = bq27xxx_read(di, BQ27510_REG_DCAP, false);
>> -		else
>> -			ilmd = bq27xxx_read(di, BQ27500_REG_DCAP, false);
>> -	} else {
>> -		ilmd = bq27xxx_read(di, BQ27000_REG_ILMD, true);
>> -	}
>> +	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
>>
>> -	if (ilmd < 0) {
>> +	if (dcap < 0) {
>>   		dev_dbg(di->dev, "error reading initial last measured discharge\n");
>> -		return ilmd;
>> +		return dcap;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di))
>> -		ilmd *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		ilmd = ilmd * 256 * 3570 / BQ27XXX_RS;
>> +		dcap *= 1000;
>>
>> -	return ilmd;
>> +	return dcap;
>>   }
>>
>>   /*
>> @@ -342,16 +527,16 @@ static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di)
>>   {
>>   	int ae;
>>
>> -	ae = bq27xxx_read(di, BQ27x00_REG_AE, false);
>> +	ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);
>>   	if (ae < 0) {
>>   		dev_dbg(di->dev, "error reading available energy\n");
>>   		return ae;
>>   	}
>>
>> -	if (di->chip == BQ27500)
>> -		ae *= 1000;
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;
>>   	else
>> -		ae = ae * 29200 / BQ27XXX_RS;
>> +		ae *= 1000;
>>
>>   	return ae;
>>   }
>> @@ -364,13 +549,13 @@ static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di)
>>   {
>>   	int temp;
>>
>> -	temp = bq27xxx_read(di, BQ27x00_REG_TEMP, false);
>> +	temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);
>>   	if (temp < 0) {
>>   		dev_err(di->dev, "error reading temperature\n");
>>   		return temp;
>>   	}
>>
>> -	if (!bq27xxx_is_chip_version_higher(di))
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>>   		temp = 5 * temp / 2;
>>
>>   	return temp;
>> @@ -384,10 +569,7 @@ static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di)
>>   {
>>   	int cyct;
>>
>> -	if (di->chip == BQ27510)
>> -		cyct = bq27xxx_read(di, BQ27510_REG_CYCT, false);
>> -	else
>> -		cyct = bq27xxx_read(di, BQ27x00_REG_CYCT, false);
>> +	cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);
>>   	if (cyct < 0)
>>   		dev_err(di->dev, "error reading cycle count total\n");
>>
>> @@ -419,21 +601,32 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
>>    * Read an average power register.
>>    * Return < 0 if something fails.
>>    */
>> -static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
>> +static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
>>   {
>>   	int tval;
>>
>> -	tval = bq27xxx_read(di, reg, false);
>> +	tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
>>   	if (tval < 0) {
>> -		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
>> -			reg, tval);
>> +		dev_err(di->dev, "error reading average power register  %02x: %d\n",
>> +			BQ27XXX_REG_AP, tval);
>>   		return tval;
>>   	}
>>
>> -	if (di->chip == BQ27500)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010)
>> +		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
>> +	else
>>   		return tval;
>> +}
>> +
>> +/*
>> + * Returns true if a battery over temperature condition is detected
>> + */
>> +static int bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>> +{
>> +	if (di->chip == BQ27500 || di->chip == BQ27541)
>> +		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
>>   	else
>> -		return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
>> +		return flags & BQ27XXX_FLAG_OTC;
>>   }
>>
>>   /*
>> @@ -442,53 +635,43 @@ static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di, u8 reg)
>>    */
>>   static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
>>   {
>> -	int tval;
>> +	u16 tval;
>>
>> -	tval = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
>> +	tval = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>>   	if (tval < 0) {
>>   		dev_err(di->dev, "error reading flag register:%d\n", tval);
>>   		return tval;
>>   	}
>>
>> -	if (di->chip == BQ27500) {
>> -		if (tval & BQ27500_FLAG_SOCF)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		if (tval & BQ27000_FLAG_EDV1)
>>   			tval = POWER_SUPPLY_HEALTH_DEAD;
>> -		else if (tval & BQ27500_FLAG_OTC)
>> -			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>>   		else
>>   			tval = POWER_SUPPLY_HEALTH_GOOD;
>> -		return tval;
>> -	} else if (di->chip == BQ27510) {
>> -		if (tval & BQ27500_FLAG_OTC)
>> -			return POWER_SUPPLY_HEALTH_OVERHEAT;
>> -		return POWER_SUPPLY_HEALTH_GOOD;
>>   	} else {
>> -		if (tval & BQ27000_FLAG_EDV1)
>> +		if (tval & BQ27XXX_FLAG_SOCF)
>>   			tval = POWER_SUPPLY_HEALTH_DEAD;
>> +		else if (bq27xxx_battery_overtemp(di, tval))
>> +			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
>>   		else
>>   			tval = POWER_SUPPLY_HEALTH_GOOD;
>> -		return tval;
>>   	}
>>
>> -	return -1;
>> +	return tval;
>>   }
>>
>>   static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   {
>>   	struct bq27xxx_reg_cache cache = {0, };
>> -	bool is_bq27500 = di->chip == BQ27500;
>> -	bool is_bq27510 = di->chip == BQ27510;
>> -	bool is_bq27425 = di->chip == BQ27425;
>> -	bool is_bq27742 = di->chip == BQ27742;
>> -	bool flags_1b = !(is_bq27500 || is_bq27742);
>> +	bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
>> +	bool has_singe_flag = di->chip == BQ27000 || di->chip == BQ27010;
>>
>> -	cache.flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, flags_1b);
>> +	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
>>   	if ((cache.flags & 0xff) == 0xff)
>> -		/* read error */
>> -		cache.flags = -1;
>> +		cache.flags = -1; /* read error */
>>   	if (cache.flags >= 0) {
>> -		if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510
>> -				&& (cache.flags & BQ27000_FLAG_CI)) {
>> +		cache.temperature = bq27xxx_battery_read_temperature(di);
>> +		if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
>>   			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
>>   			cache.capacity = -ENODATA;
>>   			cache.energy = -ENODATA;
>> @@ -498,41 +681,26 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   			cache.charge_full = -ENODATA;
>>   			cache.health = -ENODATA;
>>   		} else {
>> +			if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
>> +				cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
>> +			if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
>> +				cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
>> +			if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
>> +				cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
>> +			cache.charge_full = bq27xxx_battery_read_fcc(di);
>>   			cache.capacity = bq27xxx_battery_read_soc(di);
>> -			if (is_bq27742 || is_bq27510)
>> -				cache.time_to_empty =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTE);
>> -			else if (!is_bq27425) {
>> +			if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
>>   				cache.energy = bq27xxx_battery_read_energy(di);
>> -				cache.time_to_empty =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTE);
>> -				cache.time_to_empty_avg =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTECP);
>> -				cache.time_to_full =
>> -					bq27xxx_battery_read_time(di,
>> -							BQ27x00_REG_TTF);
>> -			}
>> -			cache.charge_full = bq27xxx_battery_read_lmd(di);
>>   			cache.health = bq27xxx_battery_read_health(di);
>>   		}
>> -		cache.temperature = bq27xxx_battery_read_temperature(di);
>> -		if (!is_bq27425)
>> +		if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
>>   			cache.cycle_count = bq27xxx_battery_read_cyct(di);
>> -		if (is_bq27742)
>> -			cache.power_avg =
>> -				bq27xxx_battery_read_pwr_avg(di,
>> -						BQ27742_POWER_AVG);
>> -		else
>> -			cache.power_avg =
>> -				bq27xxx_battery_read_pwr_avg(di,
>> -						BQ27x00_POWER_AVG);
>> +		if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
>> +			cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
>>
>>   		/* We only have to read charge design full once */
>>   		if (di->charge_design_full <= 0)
>> -			di->charge_design_full = bq27xxx_battery_read_ilmd(di);
>> +			di->charge_design_full = bq27xxx_battery_read_dcap(di);
>>   	}
>>
>>   	if (di->cache.capacity != cache.capacity)
>> @@ -547,7 +715,8 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
>>   static void bq27xxx_battery_poll(struct work_struct *work)
>>   {
>>   	struct bq27xxx_device_info *di =
>> -		container_of(work, struct bq27xxx_device_info, work.work);
>> +			container_of(work, struct bq27xxx_device_info,
>> +				     work.work);
>>
>>   	bq27xxx_battery_update(di);
>>
>> @@ -569,23 +738,23 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
>>   	int curr;
>>   	int flags;
>>
>> -	curr = bq27xxx_read(di, BQ27x00_REG_AI, false);
>> +	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
>>   	if (curr < 0) {
>>   		dev_err(di->dev, "error reading current\n");
>>   		return curr;
>>   	}
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		/* bq27500 returns signed value */
>> -		val->intval = (int)((s16)curr) * 1000;
>> -	} else {
>> -		flags = bq27xxx_read(di, BQ27x00_REG_FLAGS, false);
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
>>   		if (flags & BQ27000_FLAG_CHGS) {
>>   			dev_dbg(di->dev, "negative current!\n");
>>   			curr = -curr;
>>   		}
>>
>> -		val->intval = curr * 3570 / BQ27XXX_RS;
>> +		val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
>> +	} else {
>> +		/* Other gauges return signed value */
>> +		val->intval = (int)((s16)curr) * 1000;
>>   	}
>>
>>   	return 0;
>> @@ -596,14 +765,7 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>>   {
>>   	int status;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->cache.flags & BQ27500_FLAG_FC)
>> -			status = POWER_SUPPLY_STATUS_FULL;
>> -		else if (di->cache.flags & BQ27500_FLAG_DSC)
>> -			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> -		else
>> -			status = POWER_SUPPLY_STATUS_CHARGING;
>> -	} else {
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>>   		if (di->cache.flags & BQ27000_FLAG_FC)
>>   			status = POWER_SUPPLY_STATUS_FULL;
>>   		else if (di->cache.flags & BQ27000_FLAG_CHGS)
>> @@ -612,6 +774,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
>>   			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
>>   		else
>>   			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> +	} else {
>> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
>> +			status = POWER_SUPPLY_STATUS_FULL;
>> +		else if (di->cache.flags & BQ27XXX_FLAG_DSC)
>> +			status = POWER_SUPPLY_STATUS_DISCHARGING;
>> +		else
>> +			status = POWER_SUPPLY_STATUS_CHARGING;
>>   	}
>>
>>   	val->intval = status;
>> @@ -624,21 +793,21 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
>>   {
>>   	int level;
>>
>> -	if (bq27xxx_is_chip_version_higher(di)) {
>> -		if (di->cache.flags & BQ27500_FLAG_FC)
>> +	if (di->chip == BQ27000 || di->chip == BQ27010) {
>> +		if (di->cache.flags & BQ27000_FLAG_FC)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
>> -		else if (di->cache.flags & BQ27500_FLAG_SOC1)
>> +		else if (di->cache.flags & BQ27000_FLAG_EDV1)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
>> -		else if (di->cache.flags & BQ27500_FLAG_SOCF)
>> +		else if (di->cache.flags & BQ27000_FLAG_EDVF)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>>   		else
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
>>   	} else {
>> -		if (di->cache.flags & BQ27000_FLAG_FC)
>> +		if (di->cache.flags & BQ27XXX_FLAG_FC)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
>> -		else if (di->cache.flags & BQ27000_FLAG_EDV1)
>> +		else if (di->cache.flags & BQ27XXX_FLAG_SOC1)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
>> -		else if (di->cache.flags & BQ27000_FLAG_EDVF)
>> +		else if (di->cache.flags & BQ27XXX_FLAG_SOCF)
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
>>   		else
>>   			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
>> @@ -658,7 +827,7 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,
>>   {
>>   	int volt;
>>
>> -	volt = bq27xxx_read(di, BQ27x00_REG_VOLT, false);
>> +	volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);
>>   	if (volt < 0) {
>>   		dev_err(di->dev, "error reading voltage\n");
>>   		return volt;
>> @@ -719,7 +888,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>>   	case POWER_SUPPLY_PROP_TEMP:
>>   		ret = bq27xxx_simple_value(di->cache.temperature, val);
>>   		if (ret == 0)
>> -			val->intval -= 2731;
>> +			val->intval -= 2731; /* convert decidegree k to c */
>>   		break;
>>   	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
>>   		ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
>> @@ -785,18 +954,27 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
>>
>>   	psy_desc->name = name;
>>   	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
>> -	if (di->chip == BQ27425) {
>> -		psy_desc->properties = bq27425_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props);
>> -	} else if (di->chip == BQ27742) {
>> -		psy_desc->properties = bq27742_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props);
>> -	} else if (di->chip == BQ27510) {
>> -		psy_desc->properties = bq27510_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props);
>> +	if (di->chip == BQ27000) {
>> +		psy_desc->properties = bq27000_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27000_battery_props);
>> +	} else if (di->chip == BQ27010) {
>> +		psy_desc->properties = bq27010_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27010_battery_props);
>> +	} else if (di->chip == BQ27500) {
>> +		psy_desc->properties = bq27500_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27500_battery_props);
>> +	} else if (di->chip == BQ27530) {
>> +		psy_desc->properties = bq27530_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27530_battery_props);
>> +	} else if (di->chip == BQ27541) {
>> +		psy_desc->properties = bq27541_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27541_battery_props);
>> +	} else if (di->chip == BQ27545) {
>> +		psy_desc->properties = bq27545_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27545_battery_props);
>>   	} else {
>> -		psy_desc->properties = bq27x00_battery_props;
>> -		psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props);
>> +		psy_desc->properties = bq27421_battery_props;
>> +		psy_desc->num_properties = ARRAY_SIZE(bq27421_battery_props);
>>   	}
>
> This if-else-if-else code is too long...
>
>>   	psy_desc->get_property = bq27xxx_battery_get_property;
>>   	psy_desc->external_power_changed = bq27xxx_external_power_changed;
>> @@ -911,10 +1089,32 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
>>   	di->chip = id->driver_data;
>>   	di->bus.read = &bq27xxx_battery_i2c_read;
>>
>> +	if (di->chip == BQ27000) {
>> +		di->regs = bq27000_regs;
>> +	} else if (di->chip == BQ27010) {
>> +		di->regs = bq27010_regs;
>> +	} else if (di->chip == BQ27500) {
>> +		di->regs = bq27500_regs;
>> +	} else if (di->chip == BQ27530) {
>> +		di->regs = bq27530_regs;
>> +	} else if (di->chip == BQ27541) {
>> +		di->regs = bq27541_regs;
>> +	} else if (di->chip == BQ27545) {
>> +		di->regs = bq27545_regs;
>> +	} else if (di->chip == BQ27421) {
>> +		di->regs = bq27421_regs;
>> +	} else {
>
> ... and this too.
>
> What about creating array indexed by chip enum which will contains
> pointers to _regs and _props? With something like this you could reduce
> code to just two assignments and separate battery properties into
> semantical array variable(s)...
>

That works, I'll do that.

>> +		dev_err(&client->dev, "Unexpected gas gauge: %d\n", di->chip);
>> +		di->regs = bq27000_regs;
>> +	}
>> +
>>   	retval = bq27xxx_powersupply_init(di, name);
>>   	if (retval)
>>   		goto batt_failed;
>>
>> +	/* Schedule a polling after about 1 min */
>> +	schedule_delayed_work(&di->work, 60 * HZ);
>> +
>>   	i2c_set_clientdata(client, di);
>>
>>   	return 0;
>> @@ -941,11 +1141,22 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
>>   }
>>
>>   static const struct i2c_device_id bq27xxx_id[] = {
>> -	{ "bq27200", BQ27000 },	/* bq27200 is same as bq27000, but with i2c */
>> +	{ "bq27200", BQ27000 },
>> +	{ "bq27210", BQ27010 },
>>   	{ "bq27500", BQ27500 },
>> -	{ "bq27425", BQ27425 },
>> -	{ "bq27742", BQ27742 },
>> -	{ "bq27510", BQ27510 },
>> +	{ "bq27510", BQ27500 },
>> +	{ "bq27520", BQ27500 },
>> +	{ "bq27530", BQ27530 },
>> +	{ "bq27531", BQ27530 },
>> +	{ "bq27541", BQ27541 },
>> +	{ "bq27542", BQ27541 },
>> +	{ "bq27546", BQ27541 },
>> +	{ "bq27742", BQ27541 },
>> +	{ "bq27545", BQ27545 },
>> +	{ "bq27421", BQ27421 },
>> +	{ "bq27425", BQ27421 },
>> +	{ "bq27441", BQ27421 },
>> +	{ "bq27621", BQ27421 },
>>   	{},
>>   };
>>   MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
>> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
>> index a4efb10..45f6a7b 100644
>> --- a/include/linux/power/bq27xxx_battery.h
>> +++ b/include/linux/power/bq27xxx_battery.h
>> @@ -12,7 +12,15 @@
>>    *	register to be read. The return value should either be the content of
>>    *	the passed register or an error value.
>>    */
>> -enum bq27xxx_chip { BQ27000 = 1, BQ27500, BQ27425, BQ27742, BQ27510 };
>> +enum bq27xxx_chip {
>> +	BQ27000 = 1, /* bq27000, bq27200 */
>> +	BQ27010, /* bq27010, bq27210 */
>> +	BQ27500, /* bq27500, bq27510, bq27520 */
>> +	BQ27530, /* bq27530, bq27531 */
>> +	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
>> +	BQ27545, /* bq27545 */
>> +	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
>> +};
>>
>>   struct bq27xxx_platform_data {
>>   	const char *name;
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 1/7] power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
  (?)
@ 2015-09-22 15:18   ` Sebastian Reichel
  -1 siblings, 0 replies; 31+ messages in thread
From: Sebastian Reichel @ 2015-09-22 15:18 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Pali Rohár, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 218 bytes --]

Hi,

On Mon, Sep 14, 2015 at 04:26:07PM -0500, Andrew F. Davis wrote:
> The MODULE_DEVICE_TABLE macro automatically adds all needed
> i2c MODULE_ALIASes so remove the extra MODULE_ALIAS.

Thanks, queued.

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency
  2015-09-14 21:26   ` Andrew F. Davis
  (?)
  (?)
@ 2015-09-22 16:10   ` Sebastian Reichel
  -1 siblings, 0 replies; 31+ messages in thread
From: Sebastian Reichel @ 2015-09-22 16:10 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Pali Rohár, Dmitry Eremin-Solenikov, David Woodhouse,
	Dan Murphy, linux-pm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

Hi,

On Mon, Sep 14, 2015 at 04:26:08PM -0500, Andrew F. Davis wrote:
> Rename functions that are used by multiple devices. New devices
> have been added and the function names and driver name are no longer
> general enough for the functionality they provide.

This patch does not apply to my next tree, please rebase the next
patchset version against this tree:

git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git (branch "next")

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2015-09-22 16:10 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-14 21:26 [PATCH v4 0/7] Add support for additional bq27xxx devices Andrew F. Davis
2015-09-14 21:26 ` Andrew F. Davis
2015-09-14 21:26 ` [PATCH v4 1/7] power: bq27x00_battery: Remove unneeded i2c MODULE_ALIAS Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-21  8:33   ` Pali Rohár
2015-09-22 15:18   ` Sebastian Reichel
2015-09-14 21:26 ` [PATCH v4 2/7] power: bq27x00_battery: Renaming for consistency Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-15  8:32   ` Laurentiu Palcu
2015-09-15 16:53     ` Andrew F. Davis
2015-09-22 16:10   ` Sebastian Reichel
2015-09-14 21:26 ` [PATCH v4 3/7] power: bq27xxx_battery: Platform initialization must declare a device Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-21  8:41   ` Pali Rohár
2015-09-21 18:40     ` Andrew F. Davis
2015-09-21 18:40       ` Andrew F. Davis
2015-09-14 21:26 ` [PATCH v4 4/7] power: bq27xxx_battery: Fix typos and change naming for state of charge functions Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-21  8:36   ` Pali Rohár
2015-09-14 21:26 ` [PATCH v4 5/7] power: bq27xxx_battery: Add support for additional bq27xxx family devices Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-21  8:46   ` Pali Rohár
2015-09-21 19:02     ` Andrew F. Davis
2015-09-21 19:02       ` Andrew F. Davis
2015-09-14 21:26 ` [PATCH v4 6/7] power: bq27xxx_battery: Cleanup health checking Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-21  8:35   ` Pali Rohár
2015-09-14 21:26 ` [PATCH v4 7/7] power: bq27xxx_battery: Add interrupt handling support Andrew F. Davis
2015-09-14 21:26   ` Andrew F. Davis
2015-09-15 18:47   ` Andreas Dannenberg
2015-09-15 20:53     ` Andrew F. Davis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.