Skip to contentSkip to conversation

devicetree simple-battery and client in bq27xxx_battery

PATCH In review Liam Breck 2 participants 25 messages Jun 7, 2017 – Jul 6, 2017

Subsystems (5)
lore
Share & tools
lore

Liam Breck

author
#0 lore raw

v14 cover devicetree simple-battery and client in bq27xxx_battery

Hi Sebastian, I think this is finally ready to go. I'll make a final test pass while awaiting any further comments. There's a lot here, so I'd appreciate it if you could look closely, as it's been a while since you had any feedback. Also note comment about Rob's ack in v13 change list.

Enric, Paul, Quentin, and I all have patchsets waiting on this one. Thanks!

Overview:
* new devicetree battery node specifies static battery data
* fuel gauge and charger nodes shall use monitored-battery=<&battery_node>
* new power_supply_get_battery_info() reads battery data from devicetree
* new struct power_supply_battery_info provides battery data to drivers
* drivers surface battery data in sysfs via related power_supply_prop_* fields
* bq27xxx driver calls the above and writes battery data to RAM/NVM for params essential to correct operation: energy-full-design-microwatt-hours, charge-full-design-microamp-hours, voltage-min-design-microvolt

Changes in v14:
Doc...bindings/power/supply/ & power_supply_core
* add constant-charge-{current,voltage}-max-* for Enric's patchset
bq27xxx_battery:

*   separate set_cfgupdate() and soft_reset() functions
*   module param dt_monitored_battery_updates_nvm visible even when disabled
*   real_chip & chip IDs combined in i2c_id_table[]
*   hide untested chip params behind ifdef DEBUG

Changes in v13:
Doc...bindings/power/supply/*

*   add fields in battery.txt, see below
*   caution about changing battery type in battery.txt
*   note: Rob acked v11 battery.txt containing URL to Linux header
*   more detail in bq27xxx.txt

power_supply_core:
* add battery_info fields precharge-current-microamp & charge-term-current-microamp
* new patch for power_supply_prop_precharge_current
bq27xxx_battery:

*   add copyright notice
*   for flash/NVM chips, emit warning instead of doing update
*   config_battery_bq27xxx_dt_updates_nvm enables update of flash/NVM
*   module param dt_monitored_battery_updates_nvm lets user disallow update
*   new patch to flag dupes in bq27xxx_regs[]
*   drop patch to clean up error reporting
*   polishing from Andrew's feedback
*   resolve checkpatch errors
*   refactor patchset
*   fix missing static keyword flagged by Colin

Changes in v12: (several partial series posts; see above)

Changes in v11:
power_supply_core:
* switch to compatible = "simple-battery"
* add docs to power_supply_class.txt
Documentation/devicetree/.../battery.txt:
* add description, drop refs to Linux, "simple-battery"
bq27xxx_battery:

*   reset flash chips after DM update
*   add bq27xxx_write/xfer()
*   polishing from Andrew's feedback
*   new patch to clean up error reporting
*   new patch to consolidate duplicate register/property arrays

Changes in v10:
bq27xxx_battery:

*   pass actual chip ID into _setup()
*   add di->unseal_key & di->dm_regs; drop static arrays
*   support bq27425, 441, 621

Changes in v9:
bq27xxx_battery:

*   fix set_cfgupdate()
*   support bq27500, 545, 421; defer others
*   drop print_dm_blocks() patch
*   minor polishing

Documentation/devicetree/.../battery.txt:
* describe rationale for enum power_supply_property names

Changes in v8:
bq27xxx_battery:

*   wait on flag after set_cfgupdate & soft_reset
*   drop print_config(), report status in update_dm_block()
*   clarify error messages
*   cleanup from Andrew's feedback; minor polishing

Changes in v7:
bq27xxx_battery:

*   support chips where terminate_voltage & design_* live in separate blocks
*   draft support for 421, 441, 621 chips
*   new patch to log chip memory fields
*   report bus I/O errors; return error code in bq27xxx_battery_i2c
*   verify checksum in read_dm_block()
*   use set_cfgupdate only if chip provides it, soft_reset on I/O error
*   block_data_control=0 only in write_dm_block()
*   note toxic code from TI bqtool in write_dm_block()
*   lots of functionally neutral polishing

Documentation/devicetree/.../battery.txt:
* mention power_supply_get_battery_info()

Changes in v6:
* Documentation/devictree/... fixes
* bq27xxx_battery: clarify names
* bq27xxx_battery: verify that selected registers are supported
* bq27xxx_battery: allocate NVM buffer on stack
* bq27xxx_battery_i2c: fix return code of bulk_read

Changes in v5:
* incorporate feedback into Documentation/devicetree/.../battery.txt
* use power_supply_prop_* names in devicetree and power_supply_battery_info
* default fields to -EINVAL in power_supply_battery_info
* power_supply_get_battery_info() always looks for "monitored-battery"
* power_supply_get_battery_info() emits a warning if !psy->of_node
* squash patches for power_supply_battery_info
* bq27xxx_battery: check power_supply_battery_info values
* bq27xxx_battery: note missing power_supply_prop_* features
* bq27xxx_battery: new patch for access methods

Changes in v4:
* add "fixed-battery" compatible field to be be more consistant with devicetree

Changes in v3:
* split i2c changes into respective patches
* add documentation for battery information for fuel gauge
* rebased documentation patches on change on the list
* abstracted the battery configuration for the state machine to an generic struct and platform data access function

Changes in v2:
* add documentation for uWh and uAh property units
* change devicetree entries to match new property units

Liam Breck (9):
dt-bindings: power: supply: Add battery.txt with simple-battery binding
power: supply: core: Add power_supply_battery_info and API
power: supply: core: Add power_supply_prop_precharge
dt-bindings: power: supply: bq27xxx: Add monitored-battery documentation
power: supply: bq27xxx: Add chip data memory read/write support
power: supply: bq27xxx: Add power_supply_battery_info support
power: supply: bq27xxx: Enable data memory update for certain chips
power: supply: bq27xxx: Flag identical register maps when in debug mode
power: supply: bq27xxx: Remove duplicate register arrays

Matt Ranostay (2):
devicetree: property-units: Add uWh and uAh units
power: supply: bq27xxx: Add bulk transfer bus methods

 .../devicetree/bindings/power/supply/battery.txt   |  57 ++
 .../devicetree/bindings/power/supply/bq27xxx.txt   |  31 +-
 .../devicetree/bindings/property-units.txt         |   2 +
 Documentation/power/power_supply_class.txt         |  31 +-
 drivers/power/supply/Kconfig                       |  11 +
 drivers/power/supply/bq27xxx_battery.c             | 752 +++++++++++++++++----
 drivers/power/supply/bq27xxx_battery_i2c.c         | 134 +++-
 drivers/power/supply/power_supply_core.c           |  57 ++
 drivers/power/supply/power_supply_sysfs.c          |   1 +
 include/linux/power/bq27xxx_battery.h              |  30 +-
 include/linux/power_supply.h                       |  25 +
 11 files changed, 955 insertions(+), 176 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
Signature · 1 line
2.13.0
author
#1 lore raw

PATCH v14 1/11 devicetree: property-units: Add uWh and uAh units

From: Matt Ranostay <[email protected]>

Add entries for microwatt-hours and microamp-hours.

---
 Documentation/devicetree/bindings/property-units.txt | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/property-units.txt +2 -0
index 12278d79..0849618a 100644
@@ -25,8 +25,10 @@ Distance
 Electricity
 ----------------------------------------
 -microamp	: micro amps
+-microamp-hours : micro amp-hours
 -ohms		: Ohms
 -micro-ohms	: micro Ohms
+-microwatt-hours: micro Watt-hours
 -microvolt	: micro volts
 
 Temperature
Signature · 1 line
2.13.0
author
#2 lore raw

PATCH v14 2/11 dt-bindings: power: supply: Add battery.txt with simple-battery binding

In reply to Liam Breck

From: Liam Breck <[email protected]>

Documentation of static battery characteristics that can be defined for batteries that do not embed this data, which are required by fuel-gauge and charger chips for proper handling of the battery.

The following properties are defined:
voltage-min-design-microvolt
charge-full-design-microamp-hours
energy-full-design-microwatt-hours
precharge-current-microamp
charge-term-current-microamp
constant-charge-current-max-microamp
constant-charge-voltage-max-microamp

Property names are derived from corresponding elements in enum power_supply_property from include/linux/power_supply.h
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/power_supply.h

---
 .../devicetree/bindings/power/supply/battery.txt   | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
Documentation/devicetree/bindings/power/supply/battery.txt new file +57 -0
new file mode 100644
index 00000000..f4d3b4a1
@@ -0,0 +1,57 @@
+Battery Characteristics
+
+The devicetree battery node provides static battery characteristics.
+In smart batteries, these are typically stored in non-volatile memory
+on a fuel gauge chip. The battery node should be used where there is
+no appropriate non-volatile memory, or it is unprogrammed/incorrect.
+
+Upstream dts files should not include battery nodes, unless the battery
+represented cannot easily be replaced in the system by one of a
+different type. This prevents unpredictable, potentially harmful,
+behavior should a replacement that changes the battery type occur
+without a corresponding update to the dtb.
+
+Required Properties:
+ - compatible: Must be "simple-battery"
+
+Optional Properties:
+ - voltage-min-design-microvolt: drained battery voltage
+ - energy-full-design-microwatt-hours: battery design energy
+ - charge-full-design-microamp-hours: battery design capacity
+ - precharge-current-microamp: current for pre-charge phase
+ - charge-term-current-microamp: current for charge termination phase
+ - constant-charge-current-max-microamp: maximum constant input current
+ - constant-charge-voltage-max-microvolt: maximum constant input voltage
+
+Battery properties are named, where possible, for the corresponding
+elements in enum power_supply_property, defined in
+https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/power_supply.h
+
+Batteries must be referenced by chargers and/or fuel-gauges
+using a phandle. The phandle's property should be named
+"monitored-battery".
+
+Example:
+
+	bat: battery {
+		compatible = "simple-battery";
+		voltage-min-design-microvolt = <3200000>;
+		energy-full-design-microwatt-hours = <5290000>;
+		charge-full-design-microamp-hours = <1430000>;
+		precharge-current-microamp = <256000>;
+		charge-term-current-microamp = <128000>;
+		constant-charge-current-max-microamp = <900000>;
+		constant-charge-voltage-max-microvolt = <4200000>;
+	};
+
+	charger: charger@11 {
+		....
+		monitored-battery = <&bat>;
+		...
+	};
+
+	fuel_gauge: fuel-gauge@22 {
+		....
+		monitored-battery = <&bat>;
+		...
+	};
Signature · 1 line
2.13.0
author
#3 lore raw

PATCH v14 3/11 power: supply: core: Add power_supply_battery_info and API

In reply to Liam Breck

From: Liam Breck <[email protected]>

power_supply_get_battery_info() reads battery data from devicetree. struct power_supply_battery_info provides battery data to drivers. Its fields correspond to elements in enum power_supply_property. Drivers may surface battery data in sysfs via corresponding POWER_SUPPLY_PROP_* fields.

---
 Documentation/power/power_supply_class.txt | 12 +++++++
 drivers/power/supply/power_supply_core.c   | 57 ++++++++++++++++++++++++++++++
 include/linux/power_supply.h               | 22 ++++++++++++
 3 files changed, 91 insertions(+)
Documentation/power/power_supply_class.txt +12 -0
index 0c72588b..01f00759 100644
@@ -174,6 +174,18 @@ issued by external power supply will notify supplicants via
 external_power_changed callback.
 
 
+Devicetree battery characteristics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Drivers should call power_supply_get_battery_info() to obtain battery
+characteristics from a devicetree battery node, defined in
+Documentation/devicetree/bindings/power/supply/battery.txt. This is
+implemented in drivers/power/supply/bq27xxx_battery.c.
+
+Properties in struct power_supply_battery_info and their counterparts in the
+battery node have names corresponding to elements in enum power_supply_property,
+for naming consistency between sysfs attributes and battery node properties.
+
+
 QA
 ~~
 Q: Where is POWER_SUPPLY_PROP_XYZ attribute?
drivers/power/supply/power_supply_core.c +57 -0

69 lines not on this page · raw message

include/linux/power_supply.h +22 -0
index 39655033..85853834 100644
@@ -288,6 +288,25 @@ struct power_supply_info {
 	int use_for_apm;
 };
 
+/*
+ * This is the recommended struct to manage static battery parameters,
+ * populated by power_supply_get_battery_info(). Most platform drivers should
+ * use these for consistency.
+ * Its field names must correspond to elements in enum power_supply_property.
+ * The default field value is -EINVAL.
+ * Power supply class itself doesn't use this.
+ */
+
+struct power_supply_battery_info {
+	int energy_full_design_uwh;	    /* microWatt-hours */
+	int charge_full_design_uah;	    /* microAmp-hours */
+	int voltage_min_design_uv;	    /* microVolts */
+	int precharge_current_ua;	    /* microAmps */
+	int charge_term_current_ua;	    /* microAmps */
+	int constant_charge_current_max_ua; /* microAmps */
+	int constant_charge_voltage_max_uv; /* microVolts */
+};
+
 extern struct atomic_notifier_head power_supply_notifier;
 extern int power_supply_reg_notifier(struct notifier_block *nb);
 extern void power_supply_unreg_notifier(struct notifier_block *nb);
@@ -306,6 +325,9 @@ static inline struct power_supply *
 devm_power_supply_get_by_phandle(struct device *dev, const char *property)
 { return NULL; }
 #endif /* CONFIG_OF */
+
+extern int power_supply_get_battery_info(struct power_supply *psy,
+					 struct power_supply_battery_info *info);
 extern void power_supply_changed(struct power_supply *psy);
 extern int power_supply_am_i_supplied(struct power_supply *psy);
 extern int power_supply_set_battery_charged(struct power_supply *psy);
Signature · 1 line
2.13.0
author
#4 lore raw

PATCH v14 4/11 power: supply: core: Add power_supply_prop_precharge

In reply to Liam Breck

From: Liam Breck <[email protected]>

Battery chargers use POWER_SUPPLY_PROP_PRECHARGE_CURRENT Clarify related item POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT

---
 Documentation/power/power_supply_class.txt | 19 ++++++++++++-------
 drivers/power/supply/power_supply_sysfs.c  |  1 +
 include/linux/power_supply.h               |  3 +++
 3 files changed, 16 insertions(+), 7 deletions(-)
Documentation/power/power_supply_class.txt +12 -7
index 01f00759..300d3789 100644
@@ -115,28 +115,33 @@ of charge when battery became full/empty". It also could mean "value of
 charge when battery considered full/empty at given conditions (temperature,
 age)". I.e. these attributes represents real thresholds, not design values.
 
+ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
+
 CHARGE_COUNTER - the current charge counter (in µAh).  This could easily
 be negative; there is no empty or full value.  It is only useful for
 relative, time-based measurements.
 
+PRECHARGE_CURRENT - the maximum charge current during precharge phase
+of charge cycle (typically 20% of battery capacity).
+CHARGE_TERM_CURRENT - Charge termination current. The charge cycle
+terminates when battery voltage is above recharge threshold, and charge
+current is below this setting (typically 10% of battery capacity).
+
 CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger.
 CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the
 power supply object.
-INPUT_CURRENT_LIMIT - input current limit programmed by charger. Indicates
-the current drawn from a charging source.
-CHARGE_TERM_CURRENT - Charge termination current used to detect the end of charge
-condition.
-
-CALIBRATE - battery or coulomb counter calibration status
 
 CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger.
 CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the
 power supply object.
 
+INPUT_CURRENT_LIMIT - input current limit programmed by charger. Indicates
+the current drawn from a charging source.
+
 CHARGE_CONTROL_LIMIT - current charge control limit setting
 CHARGE_CONTROL_LIMIT_MAX - maximum charge control limit setting
 
-ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
+CALIBRATE - battery or coulomb counter calibration status
 
 CAPACITY - capacity in percents.
 CAPACITY_ALERT_MIN - minimum capacity alert value in percents.
drivers/power/supply/power_supply_sysfs.c +1 -0
index bcde8d13..937b03c7 100644
@@ -196,6 +196,7 @@ static struct device_attribute power_supply_attrs[] = {
 	POWER_SUPPLY_ATTR(time_to_full_avg),
 	POWER_SUPPLY_ATTR(type),
 	POWER_SUPPLY_ATTR(scope),
+	POWER_SUPPLY_ATTR(precharge_current),
 	POWER_SUPPLY_ATTR(charge_term_current),
 	POWER_SUPPLY_ATTR(calibrate),
 	/* Properties of type `const char *' */
include/linux/power_supply.h +3 -0
index 85853834..31c4961b 100644
@@ -146,6 +146,7 @@ enum power_supply_property {
 	POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
 	POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
 	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
 	POWER_SUPPLY_PROP_CALIBRATE,
 	/* Properties of type `const char *' */
@@ -381,6 +382,8 @@ static inline bool power_supply_is_amp_property(enum power_supply_property psp)
 	case POWER_SUPPLY_PROP_CHARGE_NOW:
 	case POWER_SUPPLY_PROP_CHARGE_AVG:
 	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+	case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+	case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 	case POWER_SUPPLY_PROP_CURRENT_MAX:
Signature · 1 line
2.13.0
author
#5 lore raw

PATCH v14 5/11 dt-bindings: power: supply: bq27xxx: Add monitored-battery documentation

In reply to Liam Breck

From: Liam Breck <[email protected]>

Document monitored-battery = <&battery_node>

---
 .../devicetree/bindings/power/supply/bq27xxx.txt   | 31 +++++++++++++++++-----
 1 file changed, 24 insertions(+), 7 deletions(-)
Documentation/devicetree/bindings/power/supply/bq27xxx.txt +24 -7
index b0c95ef6..6858e1a8 100644
@@ -1,7 +1,7 @@
-Binding for TI BQ27XXX fuel gauge family
+TI BQ27XXX fuel gauge family
 
 Required properties:
-- compatible: Should contain one of the following:
+- compatible: contains one of the following:
  * "ti,bq27200" - BQ27200
  * "ti,bq27210" - BQ27210
  * "ti,bq27500" - deprecated, use revision specific property below
@@ -26,11 +26,28 @@ Required properties:
  * "ti,bq27425" - BQ27425
  * "ti,bq27441" - BQ27441
  * "ti,bq27621" - BQ27621
-- reg: integer, i2c address of the device.
+- reg: integer, I2C address of the fuel gauge.
+
+Optional properties:
+- monitored-battery: phandle of battery characteristics node
+    The fuel gauge uses the following battery properties:
+    + energy-full-design-microwatt-hours
+    + charge-full-design-microamp-hours
+    + voltage-min-design-microvolt
+  Both or neither of the *-full-design-*-hours properties must be set.
+  See Documentation/devicetree/bindings/power/supply/battery.txt
 
 Example:
 
-bq27510g3 {
-    compatible = "ti,bq27510g3";
-    reg = <0x55>;
-};
+	bat: battery {
+		compatible = "simple-battery";
+		voltage-min-design-microvolt = <3200000>;
+		energy-full-design-microwatt-hours = <5290000>;
+		charge-full-design-microamp-hours = <1430000>;
+	};
+
+	bq27510g3: fuel-gauge@55 {
+		compatible = "ti,bq27510g3";
+		reg = <0x55>;
+		monitored-battery = <&bat>;
+	};
Signature · 1 line
2.13.0
author
#6 lore raw

PATCH v14 6/11 power: supply: bq27xxx: Add bulk transfer bus methods

In reply to Liam Breck

From: Matt Ranostay <[email protected]>

Declare bus.write/read_bulk/write_bulk().
Add I2C write/read_bulk/write_bulk() to implement the above. Add bq27xxx_write/read_block/write_block() helpers to call the above.

---
 drivers/power/supply/bq27xxx_battery.c     | 67 +++++++++++++++++++++++-
 drivers/power/supply/bq27xxx_battery_i2c.c | 82 +++++++++++++++++++++++++++++-
 include/linux/power/bq27xxx_battery.h      |  3 ++
 3 files changed, 149 insertions(+), 3 deletions(-)
drivers/power/supply/bq27xxx_battery.c +65 -2
index 398801a2..a11dfad7 100644
@@ -794,11 +794,74 @@ MODULE_PARM_DESC(poll_interval,
 static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
 			       bool single)
 {
-	/* Reports EINVAL for invalid/missing registers */
+	int ret;
+
 	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
 		return -EINVAL;
 
-	return di->bus.read(di, di->regs[reg_index], single);
+	ret = di->bus.read(di, di->regs[reg_index], single);
+	if (ret < 0)
+		dev_dbg(di->dev, "failed to read register 0x%02x (index %d)\n",
+			di->regs[reg_index], reg_index);
+
+	return ret;
+}
+
+static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index,
+				u16 value, bool single)
+{
+	int ret;
+
+	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
+		return -EINVAL;
+
+	if (!di->bus.write)
+		return -EPERM;
+
+	ret = di->bus.write(di, di->regs[reg_index], value, single);
+	if (ret < 0)
+		dev_dbg(di->dev, "failed to write register 0x%02x (index %d)\n",
+			di->regs[reg_index], reg_index);
+
+	return ret;
+}
+
+static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_index,
+				     u8 *data, int len)
+{
+	int ret;
+
+	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
+		return -EINVAL;
+
+	if (!di->bus.read_bulk)
+		return -EPERM;
+
+	ret = di->bus.read_bulk(di, di->regs[reg_index], data, len);
+	if (ret < 0)
+		dev_dbg(di->dev, "failed to read_bulk register 0x%02x (index %d)\n",
+			di->regs[reg_index], reg_index);
+
+	return ret;
+}
+
+static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_index,
+				      u8 *data, int len)
+{
+	int ret;
+
+	if (!di || di->regs[reg_index] == INVALID_REG_ADDR)
+		return -EINVAL;
+
+	if (!di->bus.write_bulk)
+		return -EPERM;
+
+	ret = di->bus.write_bulk(di, di->regs[reg_index], data, len);
+	if (ret < 0)
+		dev_dbg(di->dev, "failed to write_bulk register 0x%02x (index %d)\n",
+			di->regs[reg_index], reg_index);
+
+	return ret;
 }
 
 /*
drivers/power/supply/bq27xxx_battery_i2c.c +81 -1

101 lines not on this page · raw message

include/linux/power/bq27xxx_battery.h +3 -0
index b312bcef..c3369fa6 100644
@@ -40,6 +40,9 @@ struct bq27xxx_platform_data {
 struct bq27xxx_device_info;
 struct bq27xxx_access_methods {
 	int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
+	int (*write)(struct bq27xxx_device_info *di, u8 reg, int value, bool single);
+	int (*read_bulk)(struct bq27xxx_device_info *di, u8 reg, u8 *data, int len);
+	int (*write_bulk)(struct bq27xxx_device_info *di, u8 reg, u8 *data, int len);
 };
 
 struct bq27xxx_reg_cache {
Signature · 1 line
2.13.0
author
#7 lore raw

PATCH v14 7/11 power: supply: bq27xxx: Add chip data memory read/write support

In reply to Liam Breck

From: Liam Breck <[email protected]>

Add these to enable read/write of chip data memory RAM/NVM/flash:
bq27xxx_battery_seal()
bq27xxx_battery_unseal() bq27xxx_battery_set_cfgupdate() bq27xxx_battery_soft_reset() bq27xxx_battery_read_dm_block() bq27xxx_battery_write_dm_block() bq27xxx_battery_checksum_dm_block()

---
 drivers/power/supply/bq27xxx_battery.c | 265 +++++++++++++++++++++++++++++++++
 include/linux/power/bq27xxx_battery.h  |   1 +
 2 files changed, 266 insertions(+)
drivers/power/supply/bq27xxx_battery.c +265 -0
index a11dfad7..6a4ac14c 100644
@@ -5,6 +5,7 @@
  * Copyright (C) 2008 Eurotech S.p.A. <[email protected]>
  * Copyright (C) 2010-2011 Lars-Peter Clausen <[email protected]>
  * Copyright (C) 2011 Pali Rohár <[email protected]>
+ * Copyright (C) 2017 Liam Breck <[email protected]>
  *
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
@@ -65,6 +66,7 @@
 #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_CFGUP	BIT(4)
 #define BQ27XXX_FLAG_FC		BIT(9)
 #define BQ27XXX_FLAG_OTD	BIT(14)
 #define BQ27XXX_FLAG_OTC	BIT(15)
@@ -78,6 +80,12 @@
 #define BQ27000_FLAG_FC		BIT(5)
 #define BQ27000_FLAG_CHGS	BIT(7) /* Charge state flag */
 
+/* control register params */
+#define BQ27XXX_SEALED			0x20
+#define BQ27XXX_SET_CFGUPDATE		0x13
+#define BQ27XXX_SOFT_RESET		0x42
+#define BQ27XXX_RESET			0x41
+
 #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 */
@@ -108,9 +116,21 @@ enum bq27xxx_reg_index {
 	BQ27XXX_REG_SOC,	/* State-of-Charge */
 	BQ27XXX_REG_DCAP,	/* Design Capacity */
 	BQ27XXX_REG_AP,		/* Average Power */
+	BQ27XXX_DM_CTRL,	/* Block Data Control */
+	BQ27XXX_DM_CLASS,	/* Data Class */
+	BQ27XXX_DM_BLOCK,	/* Data Block */
+	BQ27XXX_DM_DATA,	/* Block Data */
+	BQ27XXX_DM_CKSUM,	/* Block Data Checksum */
 	BQ27XXX_REG_MAX,	/* sentinel */
 };
 
+#define BQ27XXX_DM_REG_ROWS \
+	[BQ27XXX_DM_CTRL] = 0x61,  \
+	[BQ27XXX_DM_CLASS] = 0x3e, \
+	[BQ27XXX_DM_BLOCK] = 0x3f, \
+	[BQ27XXX_DM_DATA] = 0x40,  \
+	[BQ27XXX_DM_CKSUM] = 0x60
+
 /* Register mappings */
 static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 	[BQ27000] = {
@@ -131,6 +151,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x0b,
 		[BQ27XXX_REG_DCAP] = 0x76,
 		[BQ27XXX_REG_AP] = 0x24,
+		[BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
 	},
 	[BQ27010] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -150,6 +175,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x0b,
 		[BQ27XXX_REG_DCAP] = 0x76,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
 	},
 	[BQ2750X] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -169,6 +199,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ2751X] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -188,6 +219,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x20,
 		[BQ27XXX_REG_DCAP] = 0x2e,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27500] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -207,6 +239,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27510G1] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -226,6 +259,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27510G2] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -245,6 +279,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27510G3] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -264,6 +299,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x20,
 		[BQ27XXX_REG_DCAP] = 0x2e,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27520G1] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -283,6 +319,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27520G2] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -302,6 +339,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27520G3] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -321,6 +359,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27520G4] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -340,6 +379,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x20,
 		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27530] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -359,6 +399,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27541] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -378,6 +419,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27545] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -397,6 +439,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
 		[BQ27XXX_REG_AP] = 0x24,
+		BQ27XXX_DM_REG_ROWS,
 	},
 	[BQ27421] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -416,6 +459,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x1c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x18,
+		BQ27XXX_DM_REG_ROWS,
 	},
 };
 
@@ -757,6 +801,28 @@ static struct {
 static DEFINE_MUTEX(bq27xxx_list_lock);
 static LIST_HEAD(bq27xxx_battery_devices);
 
+#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
+
+#define BQ27XXX_DM_SZ	32
+
+/**
+ * struct bq27xxx_dm_buf - chip data memory buffer
+ * @class: data memory subclass_id
+ * @block: data memory block number
+ * @data: data from/for the block
+ * @has_data: true if data has been filled by read
+ * @dirty: true if data has changed since last read/write
+ *
+ * Encapsulates info required to manage chip data memory blocks.
+ */
+struct bq27xxx_dm_buf {
+	u8 class;
+	u8 block;
+	u8 data[BQ27XXX_DM_SZ];
+	bool has_data, dirty;
+};
+
+
 static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
 {
 	struct bq27xxx_device_info *di;
@@ -864,6 +930,205 @@ static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_in
 	return ret;
 }
 
+static int bq27xxx_battery_seal(struct bq27xxx_device_info *di)
+{
+	int ret;
+
+	ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, BQ27XXX_SEALED, false);
+	if (ret < 0) {
+		dev_err(di->dev, "bus error on seal: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int bq27xxx_battery_unseal(struct bq27xxx_device_info *di)
+{
+	int ret;
+
+	if (di->unseal_key == 0) {
+		dev_err(di->dev, "unseal failed due to missing key\n");
+		return -EINVAL;
+	}
+
+	ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, (u16)(di->unseal_key >> 16), false);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, (u16)di->unseal_key, false);
+	if (ret < 0)
+		goto out;
+
+	return 0;
+
+out:
+	dev_err(di->dev, "bus error on unseal: %d\n", ret);
+	return ret;
+}
+
+static u8 bq27xxx_battery_checksum_dm_block(struct bq27xxx_dm_buf *buf)
+{
+	u16 sum = 0;
+	int i;
+
+	for (i = 0; i < BQ27XXX_DM_SZ; i++)
+		sum += buf->data[i];
+	sum &= 0xff;
+
+	return 0xff - sum;
+}
+
+static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,
+					 struct bq27xxx_dm_buf *buf)
+{
+	int ret;
+
+	buf->has_data = false;
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_CLASS, buf->class, true);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_BLOCK, buf->block, true);
+	if (ret < 0)
+		goto out;
+
+	BQ27XXX_MSLEEP(1);
+
+	ret = bq27xxx_read_block(di, BQ27XXX_DM_DATA, buf->data, BQ27XXX_DM_SZ);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_read(di, BQ27XXX_DM_CKSUM, true);
+	if (ret < 0)
+		goto out;
+
+	if ((u8)ret != bq27xxx_battery_checksum_dm_block(buf)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	buf->has_data = true;
+	buf->dirty = false;
+
+	return 0;
+
+out:
+	dev_err(di->dev, "bus error reading chip memory: %d\n", ret);
+	return ret;
+}
+
+static int bq27xxx_battery_cfgupdate_priv(struct bq27xxx_device_info *di, bool active)
+{
+	const int limit = 100;
+	u16 cmd = active ? BQ27XXX_SET_CFGUPDATE : BQ27XXX_SOFT_RESET;
+	int ret, try = limit;
+
+	ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, cmd, false);
+	if (ret < 0)
+		return ret;
+
+	do {
+		BQ27XXX_MSLEEP(25);
+		ret = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);
+		if (ret < 0)
+			return ret;
+	} while (!!(ret & BQ27XXX_FLAG_CFGUP) != active && --try);
+
+	if (!try) {
+		dev_err(di->dev, "timed out waiting for cfgupdate flag %d\n", active);
+		return -EINVAL;
+	}
+
+	if (limit - try > 3)
+		dev_warn(di->dev, "cfgupdate %d, retries %d\n", active, limit - try);
+
+	return 0;
+}
+
+static inline int bq27xxx_battery_set_cfgupdate(struct bq27xxx_device_info *di)
+{
+	int ret = bq27xxx_battery_cfgupdate_priv(di, true);
+	if (ret < 0 && ret != -EINVAL)
+		dev_err(di->dev, "bus error on set_cfgupdate: %d\n", ret);
+
+	return ret;
+}
+
+static inline int bq27xxx_battery_soft_reset(struct bq27xxx_device_info *di)
+{
+	int ret = bq27xxx_battery_cfgupdate_priv(di, false);
+	if (ret < 0 && ret != -EINVAL)
+		dev_err(di->dev, "bus error on soft_reset: %d\n", ret);
+
+	return ret;
+}
+
+static int bq27xxx_battery_write_dm_block(struct bq27xxx_device_info *di,
+					  struct bq27xxx_dm_buf *buf)
+{
+	bool cfgup = di->chip == BQ27421; /* assume related chips need cfgupdate */
+	int ret;
+
+	if (!buf->dirty)
+		return 0;
+
+	if (cfgup) {
+		ret = bq27xxx_battery_set_cfgupdate(di);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_CTRL, 0, true);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_CLASS, buf->class, true);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_BLOCK, buf->block, true);
+	if (ret < 0)
+		goto out;
+
+	BQ27XXX_MSLEEP(1);
+
+	ret = bq27xxx_write_block(di, BQ27XXX_DM_DATA, buf->data, BQ27XXX_DM_SZ);
+	if (ret < 0)
+		goto out;
+
+	ret = bq27xxx_write(di, BQ27XXX_DM_CKSUM,
+			    bq27xxx_battery_checksum_dm_block(buf), true);
+	if (ret < 0)
+		goto out;
+
+	/* DO NOT read BQ27XXX_DM_CKSUM here to verify it! That may cause NVM
+	 * corruption on the '425 chip (and perhaps others), which can damage
+	 * the chip.
+	 */
+
+	if (cfgup) {
+		BQ27XXX_MSLEEP(1);
+		ret = bq27xxx_battery_soft_reset(di);
+		if (ret < 0)
+			return ret;
+	} else {
+		BQ27XXX_MSLEEP(100); /* flash DM updates in <100ms */
+	}
+
+	buf->dirty = false;
+
+	return 0;
+
+out:
+	if (cfgup)
+		bq27xxx_battery_soft_reset(di);
+
+	dev_err(di->dev, "bus error writing chip memory: %d\n", ret);
+	return ret;
+}
+
 /*
  * Return the battery State-of-Charge
  * Or < 0 if something fails.
include/linux/power/bq27xxx_battery.h +1 -0
index c3369fa6..b1defb86 100644
@@ -64,6 +64,7 @@ struct bq27xxx_device_info {
 	int id;
 	enum bq27xxx_chip chip;
 	const char *name;
+	u32 unseal_key;
 	struct bq27xxx_access_methods bus;
 	struct bq27xxx_reg_cache cache;
 	int charge_design_full;
Signature · 1 line
2.13.0
author
#8 lore raw

PATCH v14 8/11 power: supply: bq27xxx: Add power_supply_battery_info support

In reply to Liam Breck

From: Liam Breck <[email protected]>

Previously there was no way to configure these chips in the event that the defaults didn't match the battery in question.

For chips with RAM data memory (and also those with flash/NVM data memory if CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is defined and the user has not set module param dt_monitored_battery_updates_nvm=0) we now call power_supply_get_battery_info(), check its values, and write battery properties to chip data memory if there is a dm_regs table for the chip.

---
 drivers/power/supply/Kconfig           |  11 ++
 drivers/power/supply/bq27xxx_battery.c | 204 ++++++++++++++++++++++++++++++++-
 include/linux/power/bq27xxx_battery.h  |   2 +
 3 files changed, 216 insertions(+), 1 deletion(-)
drivers/power/supply/Kconfig +11 -0
index 76806a0b..38fae108 100644
@@ -178,6 +178,17 @@ config BATTERY_BQ27XXX_I2C
 	  Say Y here to enable support for batteries with BQ27xxx chips
 	  connected over an I2C bus.
 
+config BATTERY_BQ27XXX_DT_UPDATES_NVM
+	bool "BQ27xxx support for update of NVM/flash data memory"
+	depends on BATTERY_BQ27XXX_I2C
+	help
+	  Say Y here to enable devicetree monitored-battery config to update
+	  NVM/flash data memory. Only enable this option for devices with a
+	  fuel gauge mounted on the circuit board, and a battery that cannot
+	  easily be replaced with one of a different type. Not for
+	  general-purpose kernels, as this can cause misconfiguration of a
+	  smart battery with embedded NVM/flash.
+
 config BATTERY_DA9030
 	tristate "DA9030 battery driver"
 	depends on PMIC_DA903X
drivers/power/supply/bq27xxx_battery.c +203 -1

246 lines not on this page · raw message

include/linux/power/bq27xxx_battery.h +2 -0
index b1defb86..11e11685 100644
@@ -63,7 +63,9 @@ struct bq27xxx_device_info {
 	struct device *dev;
 	int id;
 	enum bq27xxx_chip chip;
+	bool ram_chip;
 	const char *name;
+	struct bq27xxx_dm_reg *dm_regs;
 	u32 unseal_key;
 	struct bq27xxx_access_methods bus;
 	struct bq27xxx_reg_cache cache;
Signature · 1 line
2.13.0
author
#9 lore raw

PATCH v14 9/11 power: supply: bq27xxx: Enable data memory update for certain chips

In reply to Liam Breck

From: Liam Breck <[email protected]>

Support data memory update on BQ27500, 545, 425, 421, 441, 621. With exception of BQ27425, these are only enabled #ifdef DEBUG, as they are not tested.

Create IDs for for previously unID'd chips, to index arrays for unseal keys and data memory register tables.

---
 drivers/power/supply/bq27xxx_battery.c     | 75 ++++++++++++++++++++++++++++--
 drivers/power/supply/bq27xxx_battery_i2c.c | 52 +++++++++++----------
 include/linux/power/bq27xxx_battery.h      | 14 ++++++
 3 files changed, 111 insertions(+), 30 deletions(-)
drivers/power/supply/bq27xxx_battery.c +70 -5
index ed44439d..a7014525 100644
@@ -58,7 +58,7 @@
 
 #include <linux/power/bq27xxx_battery.h>
 
-#define DRIVER_VERSION		"1.2.0"
+#define DRIVER_VERSION		"1.3.0"
 
 #define BQ27XXX_MANUFACTURER	"Texas Instruments"
 
@@ -132,7 +132,7 @@ enum bq27xxx_reg_index {
 	[BQ27XXX_DM_CKSUM] = 0x60
 
 /* Register mappings */
-static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
+static u8 bq27xxx_regs[BQ27MAX][BQ27XXX_REG_MAX] = {
 	[BQ27000] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
 		[BQ27XXX_REG_TEMP] = 0x06,
@@ -779,7 +779,7 @@ static enum power_supply_property bq27421_battery_props[] = {
 static struct {
 	enum power_supply_property *props;
 	size_t size;
-} bq27xxx_battery_props[] = {
+} bq27xxx_battery_props[BQ27MAX] = {
 	BQ27XXX_PROP(BQ27000, bq27000_battery_props),
 	BQ27XXX_PROP(BQ27010, bq27010_battery_props),
 	BQ27XXX_PROP(BQ2750X, bq2750x_battery_props),
@@ -856,6 +856,63 @@ static const char * const bq27xxx_dm_reg_name[] = {
 	[BQ27XXX_DM_TERMINATE_VOLTAGE] = "terminate-voltage",
 };
 
+static struct bq27xxx_dm_reg bq27425_dm_regs[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 82, 12, 2,    0, 32767 },
+	[BQ27XXX_DM_DESIGN_ENERGY]     = { 82, 14, 2,    0, 32767 },
+	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 18, 2, 2800,  3700 },
+};
+
+#ifdef DEBUG
+/* these have not been tested */
+
+static struct bq27xxx_dm_reg bq27500_dm_regs[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 48, 10, 2,    0, 65535 },
+	[BQ27XXX_DM_DESIGN_ENERGY]     = { }, /* missing on chip */
+	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 48, 2, 1000, 32767 },
+};
+
+static struct bq27xxx_dm_reg bq27545_dm_regs[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 48, 23, 2,    0, 32767 },
+	[BQ27XXX_DM_DESIGN_ENERGY]     = { 48, 25, 2,    0, 32767 },
+	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 67, 2, 2800,  3700 },
+};
+
+static struct bq27xxx_dm_reg bq27421_dm_regs[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 82, 10, 2,    0,  8000 },
+	[BQ27XXX_DM_DESIGN_ENERGY]     = { 82, 12, 2,    0, 32767 },
+	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2500,  3700 },
+};
+
+static struct bq27xxx_dm_reg bq27621_dm_regs[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY]   = { 82, 3, 2,    0,  8000 },
+	[BQ27XXX_DM_DESIGN_ENERGY]     = { 82, 5, 2,    0, 32767 },
+	[BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 9, 2, 2500,  3700 },
+};
+
+#endif
+
+static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
+	[BQ27425] = bq27425_dm_regs,
+#ifdef DEBUG
+	[BQ27500] = bq27500_dm_regs,
+	[BQ27545] = bq27545_dm_regs,
+	[BQ27421] = bq27421_dm_regs,
+	[BQ27441] = bq27421_dm_regs,
+	[BQ27621] = bq27621_dm_regs,
+#else
+	[BQ27621] = 0 /* must have highest ID */
+#endif
+};
+
+static u32 bq27xxx_unseal_keys[] = {
+	[BQ27500] = 0x04143672,
+	[BQ27545] = 0x04143672,
+	[BQ27421] = 0x80008000,
+	[BQ27425] = 0x04143672,
+	[BQ27441] = 0x80008000,
+	[BQ27621] = 0x80008000,
+};
+
 
 static bool bq27xxx_dt_to_nvm = true;
 module_param_named(dt_monitored_battery_updates_nvm, bq27xxx_dt_to_nvm, bool, 0444);
@@ -1882,9 +1939,17 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 		.drv_data = di,
 	};
 
+	di->ram_chip = di->real_chip == BQ27421 ||
+		       di->real_chip == BQ27441 ||
+		       di->real_chip == BQ27621;
+
+	di->unseal_key = bq27xxx_unseal_keys[di->real_chip];
+	di->dm_regs = bq27xxx_dm_regs[di->real_chip];
+
+	di->regs = bq27xxx_regs[di->chip];
+
 	INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
 	mutex_init(&di->lock);
-	di->regs = bq27xxx_regs[di->chip];
 
 	psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
 	if (!psy_desc)
@@ -1999,7 +2064,7 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, di);
 
 	di->dev = &pdev->dev;
-	di->chip = pdata->chip;
+	di->chip = di->real_chip = pdata->chip;
 	di->name = pdata->name ?: dev_name(&pdev->dev);
 	di->bus.read = bq27xxx_battery_platform_read;
 
drivers/power/supply/bq27xxx_battery_i2c.c +27 -25

64 lines not on this page · raw message

include/linux/power/bq27xxx_battery.h +14 -0
index 11e11685..bec13b7a 100644
@@ -2,6 +2,9 @@
 #define __LINUX_BQ27X00_BATTERY_H__
 
 enum bq27xxx_chip {
+	/* all index bq27xxx_unseal_keys[] & bq27xxx_dm_regs[] */
+
+	/* these index bq27xxx_regs[] & bq27xxx_battery_props[] */
 	BQ27000 = 1, /* bq27000, bq27200 */
 	BQ27010, /* bq27010, bq27210 */
 	BQ2750X, /* bq27500 deprecated alias */
@@ -18,6 +21,16 @@ enum bq27xxx_chip {
 	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
 	BQ27545, /* bq27545 */
 	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+	BQ27MAX,
+
+	BQ2752X, /* deprecated alias */
+	BQ27531,
+	BQ27542,
+	BQ27546,
+	BQ27742,
+	BQ27425,
+	BQ27441,
+	BQ27621,
 };
 
 /**
@@ -62,6 +75,7 @@ struct bq27xxx_reg_cache {
 struct bq27xxx_device_info {
 	struct device *dev;
 	int id;
+	enum bq27xxx_chip real_chip;
 	enum bq27xxx_chip chip;
 	bool ram_chip;
 	const char *name;
Signature · 1 line
2.13.0
#10 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi,

Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-	{ "bq27200", BQ27000 },
-	{ "bq27210", BQ27010 },
-	{ "bq27500", BQ2750X },
-	{ "bq27510", BQ2751X },
-	{ "bq27520", BQ2751X },
-	{ "bq27500-1", BQ27500 },
-	{ "bq27510g1", BQ27510G1 },
-	{ "bq27510g2", BQ27510G2 },
-	{ "bq27510g3", BQ27510G3 },
-	{ "bq27520g1", BQ27520G1 },
-	{ "bq27520g2", BQ27520G2 },
-	{ "bq27520g3", BQ27520G3 },
-	{ "bq27520g4", BQ27520G4 },
-	{ "bq27530", BQ27530 },
-	{ "bq27531", BQ27530 },
-	{ "bq27541", BQ27541 },
-	{ "bq27542", BQ27541 },
-	{ "bq27546", BQ27541 },
-	{ "bq27742", BQ27541 },
-	{ "bq27545", BQ27545 },
-	{ "bq27421", BQ27421 },
-	{ "bq27425", BQ27421 },
-	{ "bq27441", BQ27421 },
-	{ "bq27621", BQ27421 },
+	/* dest.    di->real_chip       di->chip      */
+	{ "bq27200",   (BQ27000   << 16) |  BQ27000   },
+	{ "bq27210",   (BQ27010   << 16) |  BQ27010   },
+	{ "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+	{ "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+	{ "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+	{ "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+	{ "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+	{ "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+	{ "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+	{ "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+	{ "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+	{ "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+	{ "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+	{ "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+	{ "bq27531",   (BQ27531   << 16) |  BQ27530   },
+	{ "bq27541",   (BQ27541   << 16) |  BQ27541   },
+	{ "bq27542",   (BQ27542   << 16) |  BQ27541   },
+	{ "bq27546",   (BQ27546   << 16) |  BQ27541   },
+	{ "bq27742",   (BQ27742   << 16) |  BQ27541   },
+	{ "bq27545",   (BQ27545   << 16) |  BQ27545   },
+	{ "bq27421",   (BQ27421   << 16) |  BQ27421   },
+	{ "bq27425",   (BQ27425   << 16) |  BQ27421   },
+	{ "bq27441",   (BQ27441   << 16) |  BQ27421   },
+	{ "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

-- Sebastian

author
#11 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian,

Quoted 69 lines · Sebastian Reichel

Hi,

Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-     { "bq27200", BQ27000 },
-     { "bq27210", BQ27010 },
-     { "bq27500", BQ2750X },
-     { "bq27510", BQ2751X },
-     { "bq27520", BQ2751X },
-     { "bq27500-1", BQ27500 },
-     { "bq27510g1", BQ27510G1 },
-     { "bq27510g2", BQ27510G2 },
-     { "bq27510g3", BQ27510G3 },
-     { "bq27520g1", BQ27520G1 },
-     { "bq27520g2", BQ27520G2 },
-     { "bq27520g3", BQ27520G3 },
-     { "bq27520g4", BQ27520G4 },
-     { "bq27530", BQ27530 },
-     { "bq27531", BQ27530 },
-     { "bq27541", BQ27541 },
-     { "bq27542", BQ27541 },
-     { "bq27546", BQ27541 },
-     { "bq27742", BQ27541 },
-     { "bq27545", BQ27545 },
-     { "bq27421", BQ27421 },
-     { "bq27425", BQ27421 },
-     { "bq27441", BQ27421 },
-     { "bq27621", BQ27421 },
+     /* dest.    di->real_chip       di->chip      */
+     { "bq27200",   (BQ27000   << 16) |  BQ27000   },
+     { "bq27210",   (BQ27010   << 16) |  BQ27010   },
+     { "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+     { "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+     { "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+     { "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+     { "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+     { "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+     { "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+     { "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+     { "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+     { "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+     { "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+     { "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+     { "bq27531",   (BQ27531   << 16) |  BQ27530   },
+     { "bq27541",   (BQ27541   << 16) |  BQ27541   },
+     { "bq27542",   (BQ27542   << 16) |  BQ27541   },
+     { "bq27546",   (BQ27546   << 16) |  BQ27541   },
+     { "bq27742",   (BQ27742   << 16) |  BQ27541   },
+     { "bq27545",   (BQ27545   << 16) |  BQ27545   },
+     { "bq27421",   (BQ27421   << 16) |  BQ27421   },
+     { "bq27425",   (BQ27425   << 16) |  BQ27421   },
+     { "bq27441",   (BQ27441   << 16) |  BQ27421   },
+     { "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

.

#12 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Liam,

Quoted 80 lines · Liam Breck
Quoted 67 lines · Sebastian Reichel
Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-     { "bq27200", BQ27000 },
-     { "bq27210", BQ27010 },
-     { "bq27500", BQ2750X },
-     { "bq27510", BQ2751X },
-     { "bq27520", BQ2751X },
-     { "bq27500-1", BQ27500 },
-     { "bq27510g1", BQ27510G1 },
-     { "bq27510g2", BQ27510G2 },
-     { "bq27510g3", BQ27510G3 },
-     { "bq27520g1", BQ27520G1 },
-     { "bq27520g2", BQ27520G2 },
-     { "bq27520g3", BQ27520G3 },
-     { "bq27520g4", BQ27520G4 },
-     { "bq27530", BQ27530 },
-     { "bq27531", BQ27530 },
-     { "bq27541", BQ27541 },
-     { "bq27542", BQ27541 },
-     { "bq27546", BQ27541 },
-     { "bq27742", BQ27541 },
-     { "bq27545", BQ27545 },
-     { "bq27421", BQ27421 },
-     { "bq27425", BQ27421 },
-     { "bq27441", BQ27421 },
-     { "bq27621", BQ27421 },
+     /* dest.    di->real_chip       di->chip      */
+     { "bq27200",   (BQ27000   << 16) |  BQ27000   },
+     { "bq27210",   (BQ27010   << 16) |  BQ27010   },
+     { "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+     { "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+     { "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+     { "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+     { "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+     { "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+     { "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+     { "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+     { "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+     { "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+     { "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+     { "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+     { "bq27531",   (BQ27531   << 16) |  BQ27530   },
+     { "bq27541",   (BQ27541   << 16) |  BQ27541   },
+     { "bq27542",   (BQ27542   << 16) |  BQ27541   },
+     { "bq27546",   (BQ27546   << 16) |  BQ27541   },
+     { "bq27742",   (BQ27742   << 16) |  BQ27541   },
+     { "bq27545",   (BQ27545   << 16) |  BQ27545   },
+     { "bq27421",   (BQ27421   << 16) |  BQ27421   },
+     { "bq27425",   (BQ27425   << 16) |  BQ27421   },
+     { "bq27441",   (BQ27441   << 16) |  BQ27421   },
+     { "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

Quoted 8 lines

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

That's better, but let's get rid of real_chip. Just add the required information directly to the above struct (e.g. seal_key, ramtype).

-- Sebastian

author
#13 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian,

Quoted 88 lines · Sebastian Reichel

Hi Liam,

Quoted 85 lines · Liam Breck
Quoted 67 lines · Sebastian Reichel
Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-     { "bq27200", BQ27000 },
-     { "bq27210", BQ27010 },
-     { "bq27500", BQ2750X },
-     { "bq27510", BQ2751X },
-     { "bq27520", BQ2751X },
-     { "bq27500-1", BQ27500 },
-     { "bq27510g1", BQ27510G1 },
-     { "bq27510g2", BQ27510G2 },
-     { "bq27510g3", BQ27510G3 },
-     { "bq27520g1", BQ27520G1 },
-     { "bq27520g2", BQ27520G2 },
-     { "bq27520g3", BQ27520G3 },
-     { "bq27520g4", BQ27520G4 },
-     { "bq27530", BQ27530 },
-     { "bq27531", BQ27530 },
-     { "bq27541", BQ27541 },
-     { "bq27542", BQ27541 },
-     { "bq27546", BQ27541 },
-     { "bq27742", BQ27541 },
-     { "bq27545", BQ27545 },
-     { "bq27421", BQ27421 },
-     { "bq27425", BQ27421 },
-     { "bq27441", BQ27421 },
-     { "bq27621", BQ27421 },
+     /* dest.    di->real_chip       di->chip      */
+     { "bq27200",   (BQ27000   << 16) |  BQ27000   },
+     { "bq27210",   (BQ27010   << 16) |  BQ27010   },
+     { "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+     { "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+     { "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+     { "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+     { "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+     { "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+     { "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+     { "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+     { "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+     { "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+     { "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+     { "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+     { "bq27531",   (BQ27531   << 16) |  BQ27530   },
+     { "bq27541",   (BQ27541   << 16) |  BQ27541   },
+     { "bq27542",   (BQ27542   << 16) |  BQ27541   },
+     { "bq27546",   (BQ27546   << 16) |  BQ27541   },
+     { "bq27742",   (BQ27742   << 16) |  BQ27541   },
+     { "bq27545",   (BQ27545   << 16) |  BQ27545   },
+     { "bq27421",   (BQ27421   << 16) |  BQ27421   },
+     { "bq27425",   (BQ27425   << 16) |  BQ27421   },
+     { "bq27441",   (BQ27441   << 16) |  BQ27421   },
+     { "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

Quoted 6 lines
Quoted 3 lines

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

That's better, but let's get rid of real_chip. Just add the required information directly to the above struct (e.g. seal_key, ramtype).

I don't think the new chip data belongs in bq27*_i2c.c. All the (extensive) existing chip data is in the main file.

A later patch could rework the chip data scheme; I was trying to minimize changes in this one. The original i2c table did a real_chip -> chip mapping. Now we're just carrying real_chip forward.

The easiest fix would be to define a macro which does << and |

{ "bq27621", BQ27XXX_ID_PAIR(BQ27621, BQ27421) },

author
#14 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian, can we resolve the two outstanding issues this week? I sent comments on both last week...

Quoted 110 lines · Liam Breck

Hi Sebastian,

Quoted 88 lines · Sebastian Reichel

Hi Liam,

Quoted 85 lines · Liam Breck
Quoted 67 lines · Sebastian Reichel
Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-     { "bq27200", BQ27000 },
-     { "bq27210", BQ27010 },
-     { "bq27500", BQ2750X },
-     { "bq27510", BQ2751X },
-     { "bq27520", BQ2751X },
-     { "bq27500-1", BQ27500 },
-     { "bq27510g1", BQ27510G1 },
-     { "bq27510g2", BQ27510G2 },
-     { "bq27510g3", BQ27510G3 },
-     { "bq27520g1", BQ27520G1 },
-     { "bq27520g2", BQ27520G2 },
-     { "bq27520g3", BQ27520G3 },
-     { "bq27520g4", BQ27520G4 },
-     { "bq27530", BQ27530 },
-     { "bq27531", BQ27530 },
-     { "bq27541", BQ27541 },
-     { "bq27542", BQ27541 },
-     { "bq27546", BQ27541 },
-     { "bq27742", BQ27541 },
-     { "bq27545", BQ27545 },
-     { "bq27421", BQ27421 },
-     { "bq27425", BQ27421 },
-     { "bq27441", BQ27421 },
-     { "bq27621", BQ27421 },
+     /* dest.    di->real_chip       di->chip      */
+     { "bq27200",   (BQ27000   << 16) |  BQ27000   },
+     { "bq27210",   (BQ27010   << 16) |  BQ27010   },
+     { "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+     { "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+     { "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+     { "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+     { "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+     { "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+     { "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+     { "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+     { "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+     { "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+     { "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+     { "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+     { "bq27531",   (BQ27531   << 16) |  BQ27530   },
+     { "bq27541",   (BQ27541   << 16) |  BQ27541   },
+     { "bq27542",   (BQ27542   << 16) |  BQ27541   },
+     { "bq27546",   (BQ27546   << 16) |  BQ27541   },
+     { "bq27742",   (BQ27742   << 16) |  BQ27541   },
+     { "bq27545",   (BQ27545   << 16) |  BQ27545   },
+     { "bq27421",   (BQ27421   << 16) |  BQ27421   },
+     { "bq27425",   (BQ27425   << 16) |  BQ27421   },
+     { "bq27441",   (BQ27441   << 16) |  BQ27421   },
+     { "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

Quoted 6 lines
Quoted 3 lines

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

That's better, but let's get rid of real_chip. Just add the required information directly to the above struct (e.g. seal_key, ramtype).

I don't think the new chip data belongs in bq27*_i2c.c. All the (extensive) existing chip data is in the main file.

A later patch could rework the chip data scheme; I was trying to minimize changes in this one. The original i2c table did a real_chip -> chip mapping. Now we're just carrying real_chip forward.

The easiest fix would be to define a macro which does << and |

{ "bq27621", BQ27XXX_ID_PAIR(BQ27621, BQ27421) },

#15 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

In reply to Liam Breck

Hi,

Quoted 94 lines · Liam Breck
Quoted 92 lines · Sebastian Reichel

Hi Liam,

Quoted 88 lines · Liam Breck
Quoted 67 lines · Sebastian Reichel
Quoted 40 lines · Liam Breck

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {

drivers/power/supply/bq27xxx_battery_i2c.c +15 -24
-     { "bq27200", BQ27000 },
-     { "bq27210", BQ27010 },
-     { "bq27500", BQ2750X },
-     { "bq27510", BQ2751X },
-     { "bq27520", BQ2751X },
-     { "bq27500-1", BQ27500 },
-     { "bq27510g1", BQ27510G1 },
-     { "bq27510g2", BQ27510G2 },
-     { "bq27510g3", BQ27510G3 },
-     { "bq27520g1", BQ27520G1 },
-     { "bq27520g2", BQ27520G2 },
-     { "bq27520g3", BQ27520G3 },
-     { "bq27520g4", BQ27520G4 },
-     { "bq27530", BQ27530 },
-     { "bq27531", BQ27530 },
-     { "bq27541", BQ27541 },
-     { "bq27542", BQ27541 },
-     { "bq27546", BQ27541 },
-     { "bq27742", BQ27541 },
-     { "bq27545", BQ27545 },
-     { "bq27421", BQ27421 },
-     { "bq27425", BQ27421 },
-     { "bq27441", BQ27421 },
-     { "bq27621", BQ27421 },
+     /* dest.    di->real_chip       di->chip      */
+     { "bq27200",   (BQ27000   << 16) |  BQ27000   },
+     { "bq27210",   (BQ27010   << 16) |  BQ27010   },
+     { "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
+     { "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
+     { "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+     { "bq27500-1", (BQ27500   << 16) |  BQ27500   },
+     { "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
+     { "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+     { "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
+     { "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
+     { "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
+     { "bq27520g3", (BQ27520G3 << 16) |  BQ27520G3 },
+     { "bq27520g4", (BQ27520G4 << 16) |  BQ27520G4 },
+     { "bq27530",   (BQ27530   << 16) |  BQ27530   },

drivers/power/supply/bq27xxx_battery_i2c.c static int bq27xxx_battery_i2c_remove(struct i2c_client *client) · line 254

Quoted 10 lines
drivers/power/supply/bq27xxx_battery_i2c.c +10 -0
+     { "bq27531",   (BQ27531   << 16) |  BQ27530   },
+     { "bq27541",   (BQ27541   << 16) |  BQ27541   },
+     { "bq27542",   (BQ27542   << 16) |  BQ27541   },
+     { "bq27546",   (BQ27546   << 16) |  BQ27541   },
+     { "bq27742",   (BQ27742   << 16) |  BQ27541   },
+     { "bq27545",   (BQ27545   << 16) |  BQ27545   },
+     { "bq27421",   (BQ27421   << 16) |  BQ27421   },
+     { "bq27425",   (BQ27425   << 16) |  BQ27421   },
+     { "bq27441",   (BQ27441   << 16) |  BQ27421   },
+     { "bq27621",   (BQ27621   << 16) |  BQ27421   },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

Quoted 5 lines
Quoted 2 lines

That's better, but let's get rid of real_chip. Just add the required information directly to the above struct (e.g. seal_key, ramtype).

I don't think the new chip data belongs in bq27*_i2c.c. All the (extensive) existing chip data is in the main file.

Obviously. That's how it works when you supply a chip_id instead of a pointer to the chip_info. bq27xxx outgrew being simple enough to just provide a chip_id.

Quoted 2 lines

A later patch could rework the chip data scheme; I was trying to minimize changes in this one.

Trying to generate small changes is appreciated, creating hacks is not.

Quoted 6 lines

The original i2c table did a real_chip
-> chip mapping. Now we're just carrying real_chip forward.

The easiest fix would be to define a macro which does << and |

{ "bq27621", BQ27XXX_ID_PAIR(BQ27621, BQ27421) },

We do not want the easiest hack adding support, but a clean solution acceptable for the mainline kernel. I consider the real_chip stuff not very readable^W^W^W a huge mess.

-- Sebastian

author
#16 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian,

Quoted 57 lines · Sebastian Reichel

...

Quoted 37 lines
Quoted 37 lines
Quoted 36 lines
Quoted 17 lines
Quoted 1 line

+ { "bq27621", (BQ27621 << 16) | BQ27421 },

This is ugly. The proper way to do this is by providing a pointer to a structure with all required information. E.g.:

static const struct bq27xxx_pdata chip_info_bq27530 {
    .reg_layout = &reg_info_bq27530,
    .feature = false,
    /* more stuff */
};
static const struct bq27xxx_pdata chip_info_bq27531 {
    .reg_layout = &reg_info_bq27530,
    .feature = true,
    /* more stuff */
};
Quoted 8 lines

/* ... */

static const struct i2c_device_id bq27xxx_i2c_id_table[] = { /* ... */
{ "bq27530", &chip_info_bq27530 },
{ "bq27531", &chip_info_bq27531 },
/* ... */
}

How's this...

static const struct bq27xxx_chip_ids[] = {
[BQ27425] = { .chip = BQ27421, .real_chip = BQ27425 },
...
}

static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27425", &bq27xxx_chip_ids[BQ27425] },
...

Quoted 5 lines
Quoted 2 lines

That's better, but let's get rid of real_chip. Just add the required information directly to the above struct (e.g. seal_key, ramtype).

I don't think the new chip data belongs in bq27*_i2c.c. All the (extensive) existing chip data is in the main file.

Obviously. That's how it works when you supply a chip_id instead of a pointer to the chip_info. bq27xxx outgrew being simple enough to just provide a chip_id.

Quoted 2 lines

A later patch could rework the chip data scheme; I was trying to minimize changes in this one.

Trying to generate small changes is appreciated, creating hacks is not.

Quoted 3 lines

The original i2c table did a real_chip
-> chip mapping. Now we're just carrying real_chip forward.

Quoted 7 lines
Quoted 3 lines

The easiest fix would be to define a macro which does << and |

{ "bq27621", BQ27XXX_ID_PAIR(BQ27621, BQ27421) },

We do not want the easiest hack adding support, but a clean solution acceptable for the mainline kernel. I consider the real_chip stuff not very readable^W^W^W a huge mess.

OK, below is a minimal change to bq27xxx_battery.c creating a single data table for all chips. It can easily be extended with new fields for my patchset.

This is probably safe to upstream without testing on all the chips, as it was mostly search/replace. However various conditionals test the chip ID, so when adding the rest of the IDs (previously only in real_chip) in the next patch, I'd have to touch that code, but I have no way of testing all the affected parts. I could use .acts_like = OTHER_ID in the data table to minimize that risk. Thoughts?

From: Liam Breck <[email protected]>
Subject: [PATCH] power: supply: bq27xxx: create single chip data table

Unify data previously in bq27xxx_regs & bq27xxx_battery_props into a single table.
There is no functional change to the driver.

---
 drivers/power/supply/bq27xxx_battery.c | 121 ++++++++++++++++-----------------
 1 file changed, 60 insertions(+), 61 deletions(-)
(quoted diff) +0 -0

b/drivers/power/supply/bq27xxx_battery.c
index ed44439d0112c..db42e4961c68f 100644

drivers/power/supply/bq27xxx_battery.c +19 -20
@@ -132,8 +132,8 @@ enum bq27xxx_reg_index {
     [BQ27XXX_DM_CKSUM] = 0x60
 
 /* Register mappings */
-static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
-    [BQ27000] = {
+static u8
+    bq27000_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -157,7 +157,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ27010] = {
+    bq27010_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -181,7 +181,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ2750X] = {
+    bq2750x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -201,7 +201,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ2751X] = {
+    bq2751x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -221,7 +221,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27500] = {
+    bq27500_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -241,7 +241,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G1] = {
+    bq27510g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -261,7 +261,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G2] = {
+    bq27510g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -281,7 +281,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G3] = {
+    bq27510g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -301,7 +301,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G1] = {
+    bq27520g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -321,7 +321,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G2] = {
+    bq27520g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -341,7 +341,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G3] = {
+    bq27520g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -361,7 +361,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G4] = {
+    bq27520g4_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -381,7 +381,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27530] = {
+    bq27530_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x32,
@@ -401,7 +401,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27541] = {
+    bq27541_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -421,7 +421,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27545] = {
+    bq27545_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -441,7 +441,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27421] = {
+    bq27421_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x02,
         [BQ27XXX_REG_INT_TEMP] = 0x1e,
@@ -460,10 +460,9 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_DCAP] = 0x3c,
         [BQ27XXX_REG_AP] = 0x18,
         BQ27XXX_DM_REG_ROWS,
-    },
-};
+    };
 
-static enum power_supply_property bq27000_battery_props[] = {
+static enum power_supply_property bq27000_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,
     POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -485,7 +484,7 @@ static enum power_supply_property

bq27000_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27010_battery_props[] = { +static enum power_supply_property bq27010_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -505,7 +504,7 @@ static enum power_supply_property bq27010_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq2750x_battery_props[] = { +static enum power_supply_property bq2750x_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -523,7 +522,7 @@ static enum power_supply_property bq2750x_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq2751x_battery_props[] = { +static enum power_supply_property bq2751x_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -541,7 +540,7 @@ static enum power_supply_property bq2751x_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27500_battery_props[] = { +static enum power_supply_property bq27500_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -562,7 +561,7 @@ static enum power_supply_property bq27500_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27510g1_battery_props[] = { +static enum power_supply_property bq27510g1_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -583,7 +582,7 @@ static enum power_supply_property bq27510g1_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27510g2_battery_props[] = { +static enum power_supply_property bq27510g2_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -604,7 +603,7 @@ static enum power_supply_property bq27510g2_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27510g3_battery_props[] = { +static enum power_supply_property bq27510g3_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -622,7 +621,7 @@ static enum power_supply_property bq27510g3_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27520g1_battery_props[] = { +static enum power_supply_property bq27520g1_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -642,7 +641,7 @@ static enum power_supply_property bq27520g1_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27520g2_battery_props[] = { +static enum power_supply_property bq27520g2_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -663,7 +662,7 @@ static enum power_supply_property bq27520g2_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27520g3_battery_props[] = { +static enum power_supply_property bq27520g3_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -683,7 +682,7 @@ static enum power_supply_property bq27520g3_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27520g4_battery_props[] = { +static enum power_supply_property bq27520g4_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -700,7 +699,7 @@ static enum power_supply_property bq27520g4_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27530_battery_props[] = { +static enum power_supply_property bq27530_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -718,7 +717,7 @@ static enum power_supply_property bq27530_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27541_battery_props[] = { +static enum power_supply_property bq27541_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -737,7 +736,7 @@ static enum power_supply_property bq27541_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27545_battery_props[] = { +static enum power_supply_property bq27545_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -755,7 +754,7 @@ static enum power_supply_property bq27545_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-static enum power_supply_property bq27421_battery_props[] = { +static enum power_supply_property bq27421_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -770,32 +769,32 @@ static enum power_supply_property bq27421_battery_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
};

-#define BQ27XXX_PROP(_id, _prop) \
- [_id] = { \
- .props = _prop, \
- .size = ARRAY_SIZE(_prop), \
- }
+#define BQ27XXX_DATA(ref) { \

+    .regs  = ref##_regs,            \
+    .props = ref##_props,            \
+    .props_size = ARRAY_SIZE(ref##_props), }

static struct {

+    u8 *regs;
     enum power_supply_property *props;
-    size_t size;
-} bq27xxx_battery_props[] = {
-    BQ27XXX_PROP(BQ27000, bq27000_battery_props),
-    BQ27XXX_PROP(BQ27010, bq27010_battery_props),
-    BQ27XXX_PROP(BQ2750X, bq2750x_battery_props),
-    BQ27XXX_PROP(BQ2751X, bq2751x_battery_props),
-    BQ27XXX_PROP(BQ27500, bq27500_battery_props),
-    BQ27XXX_PROP(BQ27510G1, bq27510g1_battery_props),
-    BQ27XXX_PROP(BQ27510G2, bq27510g2_battery_props),
-    BQ27XXX_PROP(BQ27510G3, bq27510g3_battery_props),
-    BQ27XXX_PROP(BQ27520G1, bq27520g1_battery_props),
-    BQ27XXX_PROP(BQ27520G2, bq27520g2_battery_props),
-    BQ27XXX_PROP(BQ27520G3, bq27520g3_battery_props),
-    BQ27XXX_PROP(BQ27520G4, bq27520g4_battery_props),
-    BQ27XXX_PROP(BQ27530, bq27530_battery_props),
-    BQ27XXX_PROP(BQ27541, bq27541_battery_props),
-    BQ27XXX_PROP(BQ27545, bq27545_battery_props),
-    BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+    size_t props_size;
+} bq27xxx_battery_data[] = {
+    [BQ27000]   = BQ27XXX_DATA(bq27000),
+    [BQ27010]   = BQ27XXX_DATA(bq27010),
+    [BQ2750X]   = BQ27XXX_DATA(bq2750x),
+    [BQ2751X]   = BQ27XXX_DATA(bq2751x),
+    [BQ27500]   = BQ27XXX_DATA(bq27500),
+    [BQ27510G1] = BQ27XXX_DATA(bq27510g1),
+    [BQ27510G2] = BQ27XXX_DATA(bq27510g2),
+    [BQ27510G3] = BQ27XXX_DATA(bq27510g3),
+    [BQ27520G1] = BQ27XXX_DATA(bq27520g1),
+    [BQ27520G2] = BQ27XXX_DATA(bq27520g2),
+    [BQ27520G3] = BQ27XXX_DATA(bq27520g3),
+    [BQ27520G4] = BQ27XXX_DATA(bq27520g4),
+    [BQ27530]   = BQ27XXX_DATA(bq27530),
+    [BQ27541]   = BQ27XXX_DATA(bq27541),
+    [BQ27545]   = BQ27XXX_DATA(bq27545),
+    [BQ27421]   = BQ27XXX_DATA(bq27421),

};

static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -1884,7 +1883,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)

     INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
     mutex_init(&di->lock);

- di->regs = bq27xxx_regs[di->chip];
+ di->regs = bq27xxx_battery_data[di->chip].regs;

     psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
     if (!psy_desc)

@@ -1892,8 +1891,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)

     psy_desc->name = di->name;
     psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
-    psy_desc->properties = bq27xxx_battery_props[di->chip].props;
-    psy_desc->num_properties = bq27xxx_battery_props[di->chip].size;
+    psy_desc->properties = bq27xxx_battery_data[di->chip].props;
+    psy_desc->num_properties = bq27xxx_battery_data[di->chip].props_size;
     psy_desc->get_property = bq27xxx_battery_get_property;
     psy_desc->external_power_changed = bq27xxx_external_power_changed;
#17 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi,

Quoted 3 lines · Liam Breck

OK, below is a minimal change to bq27xxx_battery.c creating a single data table for all chips. It can easily be extended with new fields for my patchset.

Patch looks good.

Quoted 6 lines

This is probably safe to upstream without testing on all the chips, as it was mostly search/replace. However various conditionals test the chip ID, so when adding the rest of the IDs (previously only in real_chip) in the next patch, I'd have to touch that code, but I have no way of testing all the affected parts. I could use .acts_like = OTHER_ID in the data table to minimize that risk. Thoughts?

As far as I can see there are only a couple of different things di->chip is used for:

di->chip == BQ27421 => flag_cfgupdate,

di->chip == BQ27000 || di->chip == BQ27010 => flag_single,
di->chip == BQ27530 || di->chip == BQ27421 => flag_temp_ot_ut,

If we add those flags to bq27xxx_battery_data we do not need to check di->chip in the driver at all.

-- Sebastian

Quoted 401 lines

From: Liam Breck <[email protected]>
Subject: [PATCH] power: supply: bq27xxx: create single chip data table

Unify data previously in bq27xxx_regs & bq27xxx_battery_props into a single table.
There is no functional change to the driver.

---
 drivers/power/supply/bq27xxx_battery.c | 121 ++++++++++++++++-----------------
 1 file changed, 60 insertions(+), 61 deletions(-)
drivers/power/supply/bq27xxx_battery.c +20 -21
index ed44439d0112c..db42e4961c68f 100644
@@ -132,8 +132,8 @@ enum bq27xxx_reg_index {
     [BQ27XXX_DM_CKSUM] = 0x60
 
 /* Register mappings */
-static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
-    [BQ27000] = {
+static u8
+    bq27000_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -157,7 +157,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ27010] = {
+    bq27010_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -181,7 +181,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ2750X] = {
+    bq2750x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -201,7 +201,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ2751X] = {
+    bq2751x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -221,7 +221,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27500] = {
+    bq27500_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -241,7 +241,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G1] = {
+    bq27510g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -261,7 +261,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G2] = {
+    bq27510g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -281,7 +281,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G3] = {
+    bq27510g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -301,7 +301,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G1] = {
+    bq27520g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -321,7 +321,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G2] = {
+    bq27520g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -341,7 +341,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G3] = {
+    bq27520g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -361,7 +361,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G4] = {
+    bq27520g4_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -381,7 +381,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27530] = {
+    bq27530_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x32,
@@ -401,7 +401,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27541] = {
+    bq27541_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -421,7 +421,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27545] = {
+    bq27545_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -441,7 +441,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27421] = {
+    bq27421_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x02,
         [BQ27XXX_REG_INT_TEMP] = 0x1e,
@@ -460,10 +460,9 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_DCAP] = 0x3c,
         [BQ27XXX_REG_AP] = 0x18,
         BQ27XXX_DM_REG_ROWS,
-    },
-};
+    };
 
-static enum power_supply_property bq27000_battery_props[] = {
+static enum power_supply_property bq27000_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,
     POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -485,7 +484,7 @@ static enum power_supply_property
 bq27000_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27010_battery_props[] = {
+static enum power_supply_property bq27010_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -505,7 +504,7 @@ static enum power_supply_property
 bq27010_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq2750x_battery_props[] = {
+static enum power_supply_property bq2750x_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -523,7 +522,7 @@ static enum power_supply_property
 bq2750x_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq2751x_battery_props[] = {
+static enum power_supply_property bq2751x_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -541,7 +540,7 @@ static enum power_supply_property
 bq2751x_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27500_battery_props[] = {
+static enum power_supply_property bq27500_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -562,7 +561,7 @@ static enum power_supply_property
 bq27500_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g1_battery_props[] = {
+static enum power_supply_property bq27510g1_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -583,7 +582,7 @@ static enum power_supply_property
 bq27510g1_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g2_battery_props[] = {
+static enum power_supply_property bq27510g2_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -604,7 +603,7 @@ static enum power_supply_property
 bq27510g2_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g3_battery_props[] = {
+static enum power_supply_property bq27510g3_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -622,7 +621,7 @@ static enum power_supply_property
 bq27510g3_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g1_battery_props[] = {
+static enum power_supply_property bq27520g1_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -642,7 +641,7 @@ static enum power_supply_property
 bq27520g1_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g2_battery_props[] = {
+static enum power_supply_property bq27520g2_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -663,7 +662,7 @@ static enum power_supply_property
 bq27520g2_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g3_battery_props[] = {
+static enum power_supply_property bq27520g3_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -683,7 +682,7 @@ static enum power_supply_property
 bq27520g3_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g4_battery_props[] = {
+static enum power_supply_property bq27520g4_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -700,7 +699,7 @@ static enum power_supply_property
 bq27520g4_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27530_battery_props[] = {
+static enum power_supply_property bq27530_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -718,7 +717,7 @@ static enum power_supply_property
 bq27530_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27541_battery_props[] = {
+static enum power_supply_property bq27541_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -737,7 +736,7 @@ static enum power_supply_property
 bq27541_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27545_battery_props[] = {
+static enum power_supply_property bq27545_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -755,7 +754,7 @@ static enum power_supply_property
 bq27545_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27421_battery_props[] = {
+static enum power_supply_property bq27421_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +23 -23
@@ -770,32 +769,32 @@ static enum power_supply_property
 bq27421_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-#define BQ27XXX_PROP(_id, _prop)        \
-    [_id] = {                \
-        .props = _prop,            \
-        .size = ARRAY_SIZE(_prop),    \
-    }
+#define BQ27XXX_DATA(ref) {            \
+    .regs  = ref##_regs,            \
+    .props = ref##_props,            \
+    .props_size = ARRAY_SIZE(ref##_props), }
 
 static struct {
+    u8 *regs;
     enum power_supply_property *props;
-    size_t size;
-} bq27xxx_battery_props[] = {
-    BQ27XXX_PROP(BQ27000, bq27000_battery_props),
-    BQ27XXX_PROP(BQ27010, bq27010_battery_props),
-    BQ27XXX_PROP(BQ2750X, bq2750x_battery_props),
-    BQ27XXX_PROP(BQ2751X, bq2751x_battery_props),
-    BQ27XXX_PROP(BQ27500, bq27500_battery_props),
-    BQ27XXX_PROP(BQ27510G1, bq27510g1_battery_props),
-    BQ27XXX_PROP(BQ27510G2, bq27510g2_battery_props),
-    BQ27XXX_PROP(BQ27510G3, bq27510g3_battery_props),
-    BQ27XXX_PROP(BQ27520G1, bq27520g1_battery_props),
-    BQ27XXX_PROP(BQ27520G2, bq27520g2_battery_props),
-    BQ27XXX_PROP(BQ27520G3, bq27520g3_battery_props),
-    BQ27XXX_PROP(BQ27520G4, bq27520g4_battery_props),
-    BQ27XXX_PROP(BQ27530, bq27530_battery_props),
-    BQ27XXX_PROP(BQ27541, bq27541_battery_props),
-    BQ27XXX_PROP(BQ27545, bq27545_battery_props),
-    BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+    size_t props_size;
+} bq27xxx_battery_data[] = {
+    [BQ27000]   = BQ27XXX_DATA(bq27000),
+    [BQ27010]   = BQ27XXX_DATA(bq27010),
+    [BQ2750X]   = BQ27XXX_DATA(bq2750x),
+    [BQ2751X]   = BQ27XXX_DATA(bq2751x),
+    [BQ27500]   = BQ27XXX_DATA(bq27500),
+    [BQ27510G1] = BQ27XXX_DATA(bq27510g1),
+    [BQ27510G2] = BQ27XXX_DATA(bq27510g2),
+    [BQ27510G3] = BQ27XXX_DATA(bq27510g3),
+    [BQ27520G1] = BQ27XXX_DATA(bq27520g1),
+    [BQ27520G2] = BQ27XXX_DATA(bq27520g2),
+    [BQ27520G3] = BQ27XXX_DATA(bq27520g3),
+    [BQ27520G4] = BQ27XXX_DATA(bq27520g4),
+    [BQ27530]   = BQ27XXX_DATA(bq27530),
+    [BQ27541]   = BQ27XXX_DATA(bq27541),
+    [BQ27545]   = BQ27XXX_DATA(bq27545),
+    [BQ27421]   = BQ27XXX_DATA(bq27421),
 };
 

static DEFINE_MUTEX(bq27xxx_list_lock);

drivers/power/supply/bq27xxx_battery.c +3 -3
@@ -1884,7 +1883,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 
     INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
     mutex_init(&di->lock);
-    di->regs = bq27xxx_regs[di->chip];
+    di->regs = bq27xxx_battery_data[di->chip].regs;
 
     psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
     if (!psy_desc)
@@ -1892,8 +1891,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 
     psy_desc->name = di->name;
     psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
-    psy_desc->properties = bq27xxx_battery_props[di->chip].props;
-    psy_desc->num_properties = bq27xxx_battery_props[di->chip].size;
+    psy_desc->properties = bq27xxx_battery_data[di->chip].props;
+    psy_desc->num_properties = bq27xxx_battery_data[di->chip].props_size;
     psy_desc->get_property = bq27xxx_battery_get_property;
     psy_desc->external_power_changed = bq27xxx_external_power_changed;
author
#18 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian,

Quoted 16 lines · Sebastian Reichel

Hi,

Quoted 3 lines · Liam Breck

OK, below is a minimal change to bq27xxx_battery.c creating a single data table for all chips. It can easily be extended with new fields for my patchset.

Patch looks good.

Quoted 6 lines

This is probably safe to upstream without testing on all the chips, as it was mostly search/replace. However various conditionals test the chip ID, so when adding the rest of the IDs (previously only in real_chip) in the next patch, I'd have to touch that code, but I have no way of testing all the affected parts. I could use .acts_like = OTHER_ID in the data table to minimize that risk. Thoughts?

Quoted 6 lines

As far as I can see there are only a couple of different things di->chip is used for:

di->chip == BQ27421 => flag_cfgupdate,

di->chip == BQ27000 || di->chip == BQ27010 => flag_single,
di->chip == BQ27530 || di->chip == BQ27421 => flag_temp_ot_ut,

There are two more cases. Also there's a lot more which could be added to the driver down the road. Therefore I'd suggest a single u32 field and bitwise flags. Then the table has:

[BQ27421] = BQ27XXX_DATA(bq27421, BQ27OPT_CFGUP | BQ27OPT_OTUT | BQ27OPT_RAM)

Quoted 2 lines

If we add those flags to bq27xxx_battery_data we do not need to check di->chip in the driver at all.

I can define .opts in the table, and constants for the two cases I'm responsible for. Outside of those, this idea has me changing a LOT of logic for chips I cannot test, which isn't fail-safe. I would like to leave that logic as-is and do the following after setup() is done with bq27xxx_battery_data[di->chip].*

di->chip = bq27xxx_battery_data[di->chip].acts_like
//todo migrate this and other di->chip uses to di->opts

Quoted 401 lines
Quoted 401 lines

From: Liam Breck <[email protected]>
Subject: [PATCH] power: supply: bq27xxx: create single chip data table

Unify data previously in bq27xxx_regs & bq27xxx_battery_props into a single table.
There is no functional change to the driver.

---
 drivers/power/supply/bq27xxx_battery.c | 121 ++++++++++++++++-----------------
 1 file changed, 60 insertions(+), 61 deletions(-)
drivers/power/supply/bq27xxx_battery.c +20 -21
index ed44439d0112c..db42e4961c68f 100644
@@ -132,8 +132,8 @@ enum bq27xxx_reg_index {
     [BQ27XXX_DM_CKSUM] = 0x60
 
 /* Register mappings */
-static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
-    [BQ27000] = {
+static u8
+    bq27000_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -157,7 +157,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ27010] = {
+    bq27010_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -181,7 +181,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,
         [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,
     },
-    [BQ2750X] = {
+    bq2750x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -201,7 +201,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ2751X] = {
+    bq2751x_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -221,7 +221,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27500] = {
+    bq27500_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -241,7 +241,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G1] = {
+    bq27510g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -261,7 +261,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G2] = {
+    bq27510g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -281,7 +281,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27510G3] = {
+    bq27510g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -301,7 +301,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G1] = {
+    bq27520g1_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
@@ -321,7 +321,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G2] = {
+    bq27520g2_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -341,7 +341,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G3] = {
+    bq27520g3_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x36,
@@ -361,7 +361,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27520G4] = {
+    bq27520g4_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -381,7 +381,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27530] = {
+    bq27530_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x32,
@@ -401,7 +401,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27541] = {
+    bq27541_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -421,7 +421,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27545] = {
+    bq27545_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x06,
         [BQ27XXX_REG_INT_TEMP] = 0x28,
@@ -441,7 +441,7 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_AP] = 0x24,
         BQ27XXX_DM_REG_ROWS,
     },
-    [BQ27421] = {
+    bq27421_regs[BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_CTRL] = 0x00,
         [BQ27XXX_REG_TEMP] = 0x02,
         [BQ27XXX_REG_INT_TEMP] = 0x1e,
@@ -460,10 +460,9 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
         [BQ27XXX_REG_DCAP] = 0x3c,
         [BQ27XXX_REG_AP] = 0x18,
         BQ27XXX_DM_REG_ROWS,
-    },
-};
+    };
 
-static enum power_supply_property bq27000_battery_props[] = {
+static enum power_supply_property bq27000_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,
     POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -485,7 +484,7 @@ static enum power_supply_property
 bq27000_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27010_battery_props[] = {
+static enum power_supply_property bq27010_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -505,7 +504,7 @@ static enum power_supply_property
 bq27010_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq2750x_battery_props[] = {
+static enum power_supply_property bq2750x_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -523,7 +522,7 @@ static enum power_supply_property
 bq2750x_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq2751x_battery_props[] = {
+static enum power_supply_property bq2751x_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -541,7 +540,7 @@ static enum power_supply_property
 bq2751x_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27500_battery_props[] = {
+static enum power_supply_property bq27500_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -562,7 +561,7 @@ static enum power_supply_property
 bq27500_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g1_battery_props[] = {
+static enum power_supply_property bq27510g1_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -583,7 +582,7 @@ static enum power_supply_property
 bq27510g1_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g2_battery_props[] = {
+static enum power_supply_property bq27510g2_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -604,7 +603,7 @@ static enum power_supply_property
 bq27510g2_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g3_battery_props[] = {
+static enum power_supply_property bq27510g3_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -622,7 +621,7 @@ static enum power_supply_property
 bq27510g3_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g1_battery_props[] = {
+static enum power_supply_property bq27520g1_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -642,7 +641,7 @@ static enum power_supply_property
 bq27520g1_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g2_battery_props[] = {
+static enum power_supply_property bq27520g2_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -663,7 +662,7 @@ static enum power_supply_property
 bq27520g2_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g3_battery_props[] = {
+static enum power_supply_property bq27520g3_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -683,7 +682,7 @@ static enum power_supply_property
 bq27520g3_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27520g4_battery_props[] = {
+static enum power_supply_property bq27520g4_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -700,7 +699,7 @@ static enum power_supply_property
 bq27520g4_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27530_battery_props[] = {
+static enum power_supply_property bq27530_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -718,7 +717,7 @@ static enum power_supply_property
 bq27530_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27541_battery_props[] = {
+static enum power_supply_property bq27541_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -737,7 +736,7 @@ static enum power_supply_property
 bq27541_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27545_battery_props[] = {
+static enum power_supply_property bq27545_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +1 -1
@@ -755,7 +754,7 @@ static enum power_supply_property
 bq27545_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27421_battery_props[] = {
+static enum power_supply_property bq27421_props[] = {
     POWER_SUPPLY_PROP_STATUS,
     POWER_SUPPLY_PROP_PRESENT,

POWER_SUPPLY_PROP_VOLTAGE_NOW,

drivers/power/supply/bq27xxx_battery.c +23 -23
@@ -770,32 +769,32 @@ static enum power_supply_property
 bq27421_battery_props[] = {
     POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-#define BQ27XXX_PROP(_id, _prop)        \
-    [_id] = {                \
-        .props = _prop,            \
-        .size = ARRAY_SIZE(_prop),    \
-    }
+#define BQ27XXX_DATA(ref) {            \
+    .regs  = ref##_regs,            \
+    .props = ref##_props,            \
+    .props_size = ARRAY_SIZE(ref##_props), }
 
 static struct {
+    u8 *regs;
     enum power_supply_property *props;
-    size_t size;
-} bq27xxx_battery_props[] = {
-    BQ27XXX_PROP(BQ27000, bq27000_battery_props),
-    BQ27XXX_PROP(BQ27010, bq27010_battery_props),
-    BQ27XXX_PROP(BQ2750X, bq2750x_battery_props),
-    BQ27XXX_PROP(BQ2751X, bq2751x_battery_props),
-    BQ27XXX_PROP(BQ27500, bq27500_battery_props),
-    BQ27XXX_PROP(BQ27510G1, bq27510g1_battery_props),
-    BQ27XXX_PROP(BQ27510G2, bq27510g2_battery_props),
-    BQ27XXX_PROP(BQ27510G3, bq27510g3_battery_props),
-    BQ27XXX_PROP(BQ27520G1, bq27520g1_battery_props),
-    BQ27XXX_PROP(BQ27520G2, bq27520g2_battery_props),
-    BQ27XXX_PROP(BQ27520G3, bq27520g3_battery_props),
-    BQ27XXX_PROP(BQ27520G4, bq27520g4_battery_props),
-    BQ27XXX_PROP(BQ27530, bq27530_battery_props),
-    BQ27XXX_PROP(BQ27541, bq27541_battery_props),
-    BQ27XXX_PROP(BQ27545, bq27545_battery_props),
-    BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+    size_t props_size;
+} bq27xxx_battery_data[] = {
+    [BQ27000]   = BQ27XXX_DATA(bq27000),
+    [BQ27010]   = BQ27XXX_DATA(bq27010),
+    [BQ2750X]   = BQ27XXX_DATA(bq2750x),
+    [BQ2751X]   = BQ27XXX_DATA(bq2751x),
+    [BQ27500]   = BQ27XXX_DATA(bq27500),
+    [BQ27510G1] = BQ27XXX_DATA(bq27510g1),
+    [BQ27510G2] = BQ27XXX_DATA(bq27510g2),
+    [BQ27510G3] = BQ27XXX_DATA(bq27510g3),
+    [BQ27520G1] = BQ27XXX_DATA(bq27520g1),
+    [BQ27520G2] = BQ27XXX_DATA(bq27520g2),
+    [BQ27520G3] = BQ27XXX_DATA(bq27520g3),
+    [BQ27520G4] = BQ27XXX_DATA(bq27520g4),
+    [BQ27530]   = BQ27XXX_DATA(bq27530),
+    [BQ27541]   = BQ27XXX_DATA(bq27541),
+    [BQ27545]   = BQ27XXX_DATA(bq27545),
+    [BQ27421]   = BQ27XXX_DATA(bq27421),
 };
 

static DEFINE_MUTEX(bq27xxx_list_lock);

drivers/power/supply/bq27xxx_battery.c +3 -3
@@ -1884,7 +1883,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 
     INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
     mutex_init(&di->lock);
-    di->regs = bq27xxx_regs[di->chip];
+    di->regs = bq27xxx_battery_data[di->chip].regs;
 
     psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
     if (!psy_desc)
@@ -1892,8 +1891,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 
     psy_desc->name = di->name;
     psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
-    psy_desc->properties = bq27xxx_battery_props[di->chip].props;
-    psy_desc->num_properties = bq27xxx_battery_props[di->chip].size;
+    psy_desc->properties = bq27xxx_battery_data[di->chip].props;
+    psy_desc->num_properties = bq27xxx_battery_data[di->chip].props_size;
     psy_desc->get_property = bq27xxx_battery_get_property;
     psy_desc->external_power_changed = bq27xxx_external_power_changed;
author
#19 lore raw

Re: [PATCH v14 09/11] power: supply: bq27xxx: Enable data memory update for certain chips

Hi Sebastian,

Quoted 36 lines · Liam Breck

Hi Sebastian,

Quoted 16 lines · Sebastian Reichel

Hi,

Quoted 3 lines · Liam Breck

OK, below is a minimal change to bq27xxx_battery.c creating a single data table for all chips. It can easily be extended with new fields for my patchset.

Patch looks good.

Quoted 6 lines

This is probably safe to upstream without testing on all the chips, as it was mostly search/replace. However various conditionals test the chip ID, so when adding the rest of the IDs (previously only in real_chip) in the next patch, I'd have to touch that code, but I have no way of testing all the affected parts. I could use .acts_like = OTHER_ID in the data table to minimize that risk. Thoughts?

Quoted 6 lines

As far as I can see there are only a couple of different things di->chip is used for:

di->chip == BQ27421 => flag_cfgupdate,

di->chip == BQ27000 || di->chip == BQ27010 => flag_single,
di->chip == BQ27530 || di->chip == BQ27421 => flag_temp_ot_ut,

There are two more cases. Also there's a lot more which could be added to the driver down the road. Therefore I'd suggest a single u32 field and bitwise flags. Then the table has:

[BQ27421] = BQ27XXX_DATA(bq27421, BQ27OPT_CFGUP | BQ27OPT_OTUT | BQ27OPT_RAM)

Quoted 2 lines

If we add those flags to bq27xxx_battery_data we do not need to check di->chip in the driver at all.

Quoted 8 lines

I can define .opts in the table, and constants for the two cases I'm responsible for. Outside of those, this idea has me changing a LOT of logic for chips I cannot test, which isn't fail-safe. I would like to leave that logic as-is and do the following after setup() is done with bq27xxx_battery_data[di->chip].*

di->chip = bq27xxx_battery_data[di->chip].acts_like
//todo migrate this and other di->chip uses to di->opts

Below is a second patch which adds the missing IDs and enables the .opts field in table. Specific opts would be defined in subsequent patches.

Re the defines at the top of the patch, I first tried pointers to the referenced arrays, but C rejects that in a static initializer.

From: Liam Breck <[email protected]>

power: supply: bq27xxx: add chip IDs for previously unlisted supported chips

No functional change to the driver.

---
 drivers/power/supply/bq27xxx_battery.c     | 65 ++++++++++++++++++++++--------
 drivers/power/supply/bq27xxx_battery_i2c.c | 16 ++++----
 include/linux/power/bq27xxx_battery.h      |  9 +++++
 3 files changed, 65 insertions(+), 25 deletions(-)
(quoted diff) +0 -0

b/drivers/power/supply/bq27xxx_battery.c
index 9769a83cd2db9..c7039d4ba6d07 100644

drivers/power/supply/bq27xxx_battery.c +48 -17

129 lines not on this page · raw message

(quoted diff) +0 -0

b/drivers/power/supply/bq27xxx_battery_i2c.c
index a5972214f0742..0b11ed472f338 100644

drivers/power/supply/bq27xxx_battery_i2c.c +1 -1
@@ -230,7 +230,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
     { "bq27210", BQ27010 },
     { "bq27500", BQ2750X },
     { "bq27510", BQ2751X },
-    { "bq27520", BQ2751X },
+    { "bq27520", BQ2752X },
     { "bq27500-1", BQ27500 },
     { "bq27510g1", BQ27510G1 },
     { "bq27510g2", BQ27510G2 },
@@ -240,16 +240,16 @@ static const struct i2c_device_id
bq27xxx_i2c_id_table[] = {
     { "bq27520g3", BQ27520G3 },
     { "bq27520g4", BQ27520G4 },
     { "bq27530", BQ27530 },
-    { "bq27531", BQ27530 },
+    { "bq27531", BQ27531 },
     { "bq27541", BQ27541 },
-    { "bq27542", BQ27541 },
-    { "bq27546", BQ27541 },
-    { "bq27742", BQ27541 },
+    { "bq27542", BQ27542 },
+    { "bq27546", BQ27546 },
+    { "bq27742", BQ27742 },
     { "bq27545", BQ27545 },
     { "bq27421", BQ27421 },
-    { "bq27425", BQ27421 },
-    { "bq27441", BQ27421 },
-    { "bq27621", BQ27421 },
+    { "bq27425", BQ27425 },
+    { "bq27441", BQ27441 },
+    { "bq27621", BQ27621 },
     {},

};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);

(quoted diff) +0 -0

b/include/linux/power/bq27xxx_battery.h
index 11e11685dd1d5..77fe94f1d5f25 100644

include/linux/power/bq27xxx_battery.h +9 -0
@@ -6,6 +6,7 @@ enum bq27xxx_chip {
     BQ27010, /* bq27010, bq27210 */
     BQ2750X, /* bq27500 deprecated alias */
     BQ2751X, /* bq27510, bq27520 deprecated alias */
+    BQ2752X,
     BQ27500, /* bq27500/1 */
     BQ27510G1, /* bq27510G1 */
     BQ27510G2, /* bq27510G2 */
@@ -15,9 +16,16 @@ enum bq27xxx_chip {
     BQ27520G3, /* bq27520G3 */
     BQ27520G4, /* bq27520G4 */
     BQ27530, /* bq27530, bq27531 */
+    BQ27531,
     BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
+    BQ27542,
+    BQ27546,
+    BQ27742,
     BQ27545, /* bq27545 */
     BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+    BQ27425,
+    BQ27441,
+    BQ27621,
 };
 
 /**
@@ -64,6 +72,7 @@ struct bq27xxx_device_info {
     int id;
     enum bq27xxx_chip chip;
     bool ram_chip;
+    u32 opts;
     const char *name;
     struct bq27xxx_dm_reg *dm_regs;
     u32 unseal_key;
author
#20 lore raw

PATCH v14 10/11 power: supply: bq27xxx: Flag identical register maps when in debug mode

In reply to Liam Breck

From: Liam Breck <[email protected]>

We tie multiple chips to unique register maps. When supporting a new chip, it's easy to add a duplicate map by mistake.

In debug mode we now scan the register maps for duplicates.

---
 drivers/power/supply/bq27xxx_battery.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
drivers/power/supply/bq27xxx_battery.c +21 -0
index a7014525..f4449aba 100644
@@ -1931,6 +1931,25 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
 	schedule_delayed_work(&di->work, 0);
 }
 
+#ifdef DEBUG
+static void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di)
+{
+	const size_t max = ARRAY_SIZE(bq27xxx_regs);
+	int a, b;
+
+	for (a = 1; a < max-1; a++) {
+		for (b = a+1; b < max; b++) {
+			if (!memcmp(bq27xxx_regs[a], bq27xxx_regs[b],
+				    sizeof(bq27xxx_regs[0])))
+				dev_warn(di->dev,
+					"bq27xxx_regs[%d] & [%d] are identical\n", a, b);
+		}
+	}
+}
+#else
+static inline void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di) {}
+#endif
+
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 {
 	struct power_supply_desc *psy_desc;
@@ -1939,6 +1958,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 		.drv_data = di,
 	};
 
+	bq27xxx_battery_dbg_regs_dupes(di);
+
 	di->ram_chip = di->real_chip == BQ27421 ||
 		       di->real_chip == BQ27441 ||
 		       di->real_chip == BQ27621;
Signature · 1 line
2.13.0
#21 lore raw

Re: [PATCH v14 10/11] power: supply: bq27xxx: Flag identical register maps when in debug mode

Hi,

Quoted 8 lines · Liam Breck

From: Liam Breck <[email protected]>

We tie multiple chips to unique register maps. When supporting a new chip, it's easy to add a duplicate map by mistake.

In debug mode we now scan the register maps for duplicates.

This does not belong into the kernel, but into some static analyzer tool.

-- Sebastian

Quoted 45 lines
 drivers/power/supply/bq27xxx_battery.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
drivers/power/supply/bq27xxx_battery.c +21 -0
index a7014525..f4449aba 100644
@@ -1931,6 +1931,25 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
 	schedule_delayed_work(&di->work, 0);
 }
 
+#ifdef DEBUG
+static void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di)
+{
+	const size_t max = ARRAY_SIZE(bq27xxx_regs);
+	int a, b;
+
+	for (a = 1; a < max-1; a++) {
+		for (b = a+1; b < max; b++) {
+			if (!memcmp(bq27xxx_regs[a], bq27xxx_regs[b],
+				    sizeof(bq27xxx_regs[0])))
+				dev_warn(di->dev,
+					"bq27xxx_regs[%d] & [%d] are identical\n", a, b);
+		}
+	}
+}
+#else
+static inline void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di) {}
+#endif
+
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 {
 	struct power_supply_desc *psy_desc;
@@ -1939,6 +1958,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 		.drv_data = di,
 	};
 
+	bq27xxx_battery_dbg_regs_dupes(di);
+
 	di->ram_chip = di->real_chip == BQ27421 ||
 		       di->real_chip == BQ27441 ||
 		       di->real_chip == BQ27621;
Signature · 1 line
2.13.0
author
#22 lore raw

Re: [PATCH v14 10/11] power: supply: bq27xxx: Flag identical register maps when in debug mode

Hi Sebastian,

Quoted 8 lines · Sebastian Reichel

Hi,

Quoted 5 lines · Liam Breck

From: Liam Breck <[email protected]>

We tie multiple chips to unique register maps. When supporting a new chip, it's easy to add a duplicate map by mistake.

Quoted 6 lines
Quoted 3 lines

In debug mode we now scan the register maps for duplicates.

This does not belong into the kernel, but into some static analyzer tool.

More than a dozen chip definitions are in this driver, spanning 300 lines. We need these 18 lines to manage them; I think this would be overlooked in an external utility.

I put this code behind ifdef DEBUG; if that's not OK, could we put it behind a kernel option or other define?

Quoted 45 lines
Quoted 45 lines
 drivers/power/supply/bq27xxx_battery.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
drivers/power/supply/bq27xxx_battery.c +21 -1
index a7014525..f4449aba 100644
@@ -1931,6 +1931,25 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
      schedule_delayed_work(&di->work, 0);
 }
 
+#ifdef DEBUG
+static void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di)
+{
+     const size_t max = ARRAY_SIZE(bq27xxx_regs);
+     int a, b;
+
+     for (a = 1; a < max-1; a++) {
+             for (b = a+1; b < max; b++) {
+                     if (!memcmp(bq27xxx_regs[a], bq27xxx_regs[b],
+                                 sizeof(bq27xxx_regs[0])))
+                             dev_warn(di->dev,
+                                     "bq27xxx_regs[%d] & [%d] are identical\n", a, b);
+             }
+     }
+}
+#else
+static inline void bq27xxx_battery_dbg_regs_dupes(struct bq27xxx_device_info *di) {}
+#endif
+
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 {
      struct power_supply_desc *psy_desc;
@@ -1939,6 +1958,8 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
              .drv_data = di,
      };
 
+     bq27xxx_battery_dbg_regs_dupes(di);
+
      di->ram_chip = di->real_chip == BQ27421 ||
                     di->real_chip == BQ27441 ||
                     di->real_chip == BQ27621;
--

2.13.0

author
#23 lore raw

PATCH v14 11/11 power: supply: bq27xxx: Remove duplicate register arrays

In reply to Liam Breck

From: Liam Breck <[email protected]>

BQ2751X & BQ27510G3 are identical. BQ27500 & BQ27510G1 & BQ27510G2 are identical. Make BQ2751X & BQ27510G1/2 aliases. Remove the duplicate arrays, etc.

---
 drivers/power/supply/bq27xxx_battery.c     | 126 -----------------------------
 drivers/power/supply/bq27xxx_battery_i2c.c |   8 +-
 include/linux/power/bq27xxx_battery.h      |  12 +--
 3 files changed, 10 insertions(+), 136 deletions(-)
drivers/power/supply/bq27xxx_battery.c +0 -126
index f4449aba..b81f986d 100644
@@ -201,26 +201,6 @@ static u8 bq27xxx_regs[BQ27MAX][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
 		BQ27XXX_DM_REG_ROWS,
 	},
-	[BQ2751X] = {
-		[BQ27XXX_REG_CTRL] = 0x00,
-		[BQ27XXX_REG_TEMP] = 0x06,
-		[BQ27XXX_REG_INT_TEMP] = 0x28,
-		[BQ27XXX_REG_VOLT] = 0x08,
-		[BQ27XXX_REG_AI] = 0x14,
-		[BQ27XXX_REG_FLAGS] = 0x0a,
-		[BQ27XXX_REG_TTE] = 0x16,
-		[BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
-		[BQ27XXX_REG_TTES] = 0x1a,
-		[BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
-		[BQ27XXX_REG_NAC] = 0x0c,
-		[BQ27XXX_REG_FCC] = 0x12,
-		[BQ27XXX_REG_CYCT] = 0x1e,
-		[BQ27XXX_REG_AE] = INVALID_REG_ADDR,
-		[BQ27XXX_REG_SOC] = 0x20,
-		[BQ27XXX_REG_DCAP] = 0x2e,
-		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
-		BQ27XXX_DM_REG_ROWS,
-	},
 	[BQ27500] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
 		[BQ27XXX_REG_TEMP] = 0x06,
@@ -241,46 +221,6 @@ static u8 bq27xxx_regs[BQ27MAX][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_AP] = 0x24,
 		BQ27XXX_DM_REG_ROWS,
 	},
-	[BQ27510G1] = {
-		[BQ27XXX_REG_CTRL] = 0x00,
-		[BQ27XXX_REG_TEMP] = 0x06,
-		[BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
-		[BQ27XXX_REG_VOLT] = 0x08,
-		[BQ27XXX_REG_AI] = 0x14,
-		[BQ27XXX_REG_FLAGS] = 0x0a,
-		[BQ27XXX_REG_TTE] = 0x16,
-		[BQ27XXX_REG_TTF] = 0x18,
-		[BQ27XXX_REG_TTES] = 0x1c,
-		[BQ27XXX_REG_TTECP] = 0x26,
-		[BQ27XXX_REG_NAC] = 0x0c,
-		[BQ27XXX_REG_FCC] = 0x12,
-		[BQ27XXX_REG_CYCT] = 0x2a,
-		[BQ27XXX_REG_AE] = 0x22,
-		[BQ27XXX_REG_SOC] = 0x2c,
-		[BQ27XXX_REG_DCAP] = 0x3c,
-		[BQ27XXX_REG_AP] = 0x24,
-		BQ27XXX_DM_REG_ROWS,
-	},
-	[BQ27510G2] = {
-		[BQ27XXX_REG_CTRL] = 0x00,
-		[BQ27XXX_REG_TEMP] = 0x06,
-		[BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
-		[BQ27XXX_REG_VOLT] = 0x08,
-		[BQ27XXX_REG_AI] = 0x14,
-		[BQ27XXX_REG_FLAGS] = 0x0a,
-		[BQ27XXX_REG_TTE] = 0x16,
-		[BQ27XXX_REG_TTF] = 0x18,
-		[BQ27XXX_REG_TTES] = 0x1c,
-		[BQ27XXX_REG_TTECP] = 0x26,
-		[BQ27XXX_REG_NAC] = 0x0c,
-		[BQ27XXX_REG_FCC] = 0x12,
-		[BQ27XXX_REG_CYCT] = 0x2a,
-		[BQ27XXX_REG_AE] = 0x22,
-		[BQ27XXX_REG_SOC] = 0x2c,
-		[BQ27XXX_REG_DCAP] = 0x3c,
-		[BQ27XXX_REG_AP] = 0x24,
-		BQ27XXX_DM_REG_ROWS,
-	},
 	[BQ27510G3] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
 		[BQ27XXX_REG_TEMP] = 0x06,
@@ -523,24 +463,6 @@ static enum power_supply_property bq2750x_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq2751x_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_CHARGE_FULL_DESIGN,
-	POWER_SUPPLY_PROP_CYCLE_COUNT,
-	POWER_SUPPLY_PROP_HEALTH,
-	POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
 static enum power_supply_property bq27500_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
@@ -562,48 +484,6 @@ static enum power_supply_property bq27500_battery_props[] = {
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
 
-static enum power_supply_property bq27510g1_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_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_ENERGY_NOW,
-	POWER_SUPPLY_PROP_POWER_AVG,
-	POWER_SUPPLY_PROP_HEALTH,
-	POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
-static enum power_supply_property bq27510g2_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_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_ENERGY_NOW,
-	POWER_SUPPLY_PROP_POWER_AVG,
-	POWER_SUPPLY_PROP_HEALTH,
-	POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
 static enum power_supply_property bq27510g3_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
@@ -783,10 +663,7 @@ static struct {
 	BQ27XXX_PROP(BQ27000, bq27000_battery_props),
 	BQ27XXX_PROP(BQ27010, bq27010_battery_props),
 	BQ27XXX_PROP(BQ2750X, bq2750x_battery_props),
-	BQ27XXX_PROP(BQ2751X, bq2751x_battery_props),
 	BQ27XXX_PROP(BQ27500, bq27500_battery_props),
-	BQ27XXX_PROP(BQ27510G1, bq27510g1_battery_props),
-	BQ27XXX_PROP(BQ27510G2, bq27510g2_battery_props),
 	BQ27XXX_PROP(BQ27510G3, bq27510g3_battery_props),
 	BQ27XXX_PROP(BQ27520G1, bq27520g1_battery_props),
 	BQ27XXX_PROP(BQ27520G2, bq27520g2_battery_props),
@@ -1577,10 +1454,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
 {
 	switch (di->chip) {
 	case BQ2750X:
-	case BQ2751X:
 	case BQ27500:
-	case BQ27510G1:
-	case BQ27510G2:
 	case BQ27510G3:
 	case BQ27520G1:
 	case BQ27520G2:
drivers/power/supply/bq27xxx_battery_i2c.c +4 -4
index a3656508..0ef0fca3 100644
@@ -231,11 +231,11 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
 	{ "bq27200",   (BQ27000   << 16) |  BQ27000   },
 	{ "bq27210",   (BQ27010   << 16) |  BQ27010   },
 	{ "bq27500",   (BQ2750X   << 16) |  BQ2750X   },
-	{ "bq27510",   (BQ2751X   << 16) |  BQ2751X   },
-	{ "bq27520",   (BQ2752X   << 16) |  BQ2751X   },
+	{ "bq27510",   (BQ2751X   << 16) |  BQ27510G3 },
+	{ "bq27520",   (BQ2752X   << 16) |  BQ27510G3 },
 	{ "bq27500-1", (BQ27500   << 16) |  BQ27500   },
-	{ "bq27510g1", (BQ27510G1 << 16) |  BQ27510G1 },
-	{ "bq27510g2", (BQ27510G2 << 16) |  BQ27510G2 },
+	{ "bq27510g1", (BQ27510G1 << 16) |  BQ27500   },
+	{ "bq27510g2", (BQ27510G2 << 16) |  BQ27500   },
 	{ "bq27510g3", (BQ27510G3 << 16) |  BQ27510G3 },
 	{ "bq27520g1", (BQ27520G1 << 16) |  BQ27520G1 },
 	{ "bq27520g2", (BQ27520G2 << 16) |  BQ27520G2 },
include/linux/power/bq27xxx_battery.h +6 -6
index bec13b7a..acbe52e6 100644
@@ -8,11 +8,8 @@ enum bq27xxx_chip {
 	BQ27000 = 1, /* bq27000, bq27200 */
 	BQ27010, /* bq27010, bq27210 */
 	BQ2750X, /* bq27500 deprecated alias */
-	BQ2751X, /* bq27510, bq27520 deprecated alias */
-	BQ27500, /* bq27500/1 */
-	BQ27510G1, /* bq27510G1 */
-	BQ27510G2, /* bq27510G2 */
-	BQ27510G3, /* bq27510G3 */
+	BQ27500, /* bq27500/1, bq27510G1, bq27510G2 */
+	BQ27510G3, /* bq27510G3, bq27510, bq27520 */
 	BQ27520G1, /* bq27520G1 */
 	BQ27520G2, /* bq27520G2 */
 	BQ27520G3, /* bq27520G3 */
@@ -23,7 +20,10 @@ enum bq27xxx_chip {
 	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
 	BQ27MAX,
 
-	BQ2752X, /* deprecated alias */
+	BQ2751X, /* bq27510 deprecated alias */
+	BQ2752X, /* bq27520 deprecated alias */
+	BQ27510G1,
+	BQ27510G2,
 	BQ27531,
 	BQ27542,
 	BQ27546,
Signature · 1 line
2.13.0
#24 lore raw
In reply to Liam Breck

Hi,

Quoted 4 lines · Liam Breck

Hi Sebastian, I think this is finally ready to go. I'll make a final test pass while awaiting any further comments. There's a lot here, so I'd appreciate it if you could look closely, as it's been a while since you had any feedback. Also note comment about Rob's ack in v13 change list.

Ok, I had some hours for reviewing stuff today and finished and queued everything up to patch 8, which looked fine to me. I will have a look at the remaining 3 sometime this week.

Quoted 2 lines

Enric, Paul, Quentin, and I all have patchsets waiting on this one. Thanks!

I also queued some of those, so that stuff can be properly tested in linux-next. Thanks for your work.

Also: If any issues come up for the patches I want follow-up patches instead of replacing them.

-- Sebastian

Quoted 156 lines

Overview:
* new devicetree battery node specifies static battery data
* fuel gauge and charger nodes shall use monitored-battery=<&battery_node>
* new power_supply_get_battery_info() reads battery data from devicetree
* new struct power_supply_battery_info provides battery data to drivers
* drivers surface battery data in sysfs via related power_supply_prop_* fields
* bq27xxx driver calls the above and writes battery data to RAM/NVM for params essential to correct operation: energy-full-design-microwatt-hours, charge-full-design-microamp-hours, voltage-min-design-microvolt

Changes in v14:
Doc...bindings/power/supply/ & power_supply_core
* add constant-charge-{current,voltage}-max-* for Enric's patchset
bq27xxx_battery:

*   separate set_cfgupdate() and soft_reset() functions
*   module param dt_monitored_battery_updates_nvm visible even when disabled
*   real_chip & chip IDs combined in i2c_id_table[]
*   hide untested chip params behind ifdef DEBUG

Changes in v13:
Doc...bindings/power/supply/*

*   add fields in battery.txt, see below
*   caution about changing battery type in battery.txt
*   note: Rob acked v11 battery.txt containing URL to Linux header
*   more detail in bq27xxx.txt

power_supply_core:
* add battery_info fields precharge-current-microamp & charge-term-current-microamp
* new patch for power_supply_prop_precharge_current
bq27xxx_battery:

*   add copyright notice
*   for flash/NVM chips, emit warning instead of doing update
*   config_battery_bq27xxx_dt_updates_nvm enables update of flash/NVM
*   module param dt_monitored_battery_updates_nvm lets user disallow update
*   new patch to flag dupes in bq27xxx_regs[]
*   drop patch to clean up error reporting
*   polishing from Andrew's feedback
*   resolve checkpatch errors
*   refactor patchset
*   fix missing static keyword flagged by Colin

Changes in v12: (several partial series posts; see above)

Changes in v11:
power_supply_core:
* switch to compatible = "simple-battery"
* add docs to power_supply_class.txt
Documentation/devicetree/.../battery.txt:
* add description, drop refs to Linux, "simple-battery"
bq27xxx_battery:

*   reset flash chips after DM update
*   add bq27xxx_write/xfer()
*   polishing from Andrew's feedback
*   new patch to clean up error reporting
*   new patch to consolidate duplicate register/property arrays

Changes in v10:
bq27xxx_battery:

*   pass actual chip ID into _setup()
*   add di->unseal_key & di->dm_regs; drop static arrays
*   support bq27425, 441, 621

Changes in v9:
bq27xxx_battery:

*   fix set_cfgupdate()
*   support bq27500, 545, 421; defer others
*   drop print_dm_blocks() patch
*   minor polishing

Documentation/devicetree/.../battery.txt:
* describe rationale for enum power_supply_property names

Changes in v8:
bq27xxx_battery:

*   wait on flag after set_cfgupdate & soft_reset
*   drop print_config(), report status in update_dm_block()
*   clarify error messages
*   cleanup from Andrew's feedback; minor polishing

Changes in v7:
bq27xxx_battery:

*   support chips where terminate_voltage & design_* live in separate blocks
*   draft support for 421, 441, 621 chips
*   new patch to log chip memory fields
*   report bus I/O errors; return error code in bq27xxx_battery_i2c
*   verify checksum in read_dm_block()
*   use set_cfgupdate only if chip provides it, soft_reset on I/O error
*   block_data_control=0 only in write_dm_block()
*   note toxic code from TI bqtool in write_dm_block()
*   lots of functionally neutral polishing

Documentation/devicetree/.../battery.txt:
* mention power_supply_get_battery_info()

Changes in v6:
* Documentation/devictree/... fixes
* bq27xxx_battery: clarify names
* bq27xxx_battery: verify that selected registers are supported
* bq27xxx_battery: allocate NVM buffer on stack
* bq27xxx_battery_i2c: fix return code of bulk_read

Changes in v5:
* incorporate feedback into Documentation/devicetree/.../battery.txt
* use power_supply_prop_* names in devicetree and power_supply_battery_info
* default fields to -EINVAL in power_supply_battery_info
* power_supply_get_battery_info() always looks for "monitored-battery"
* power_supply_get_battery_info() emits a warning if !psy->of_node
* squash patches for power_supply_battery_info
* bq27xxx_battery: check power_supply_battery_info values
* bq27xxx_battery: note missing power_supply_prop_* features
* bq27xxx_battery: new patch for access methods

Changes in v4:
* add "fixed-battery" compatible field to be be more consistant with devicetree

Changes in v3:
* split i2c changes into respective patches
* add documentation for battery information for fuel gauge
* rebased documentation patches on change on the list
* abstracted the battery configuration for the state machine to an generic struct and platform data access function

Changes in v2:
* add documentation for uWh and uAh property units
* change devicetree entries to match new property units

Liam Breck (9):
dt-bindings: power: supply: Add battery.txt with simple-battery binding
power: supply: core: Add power_supply_battery_info and API
power: supply: core: Add power_supply_prop_precharge
dt-bindings: power: supply: bq27xxx: Add monitored-battery documentation
power: supply: bq27xxx: Add chip data memory read/write support
power: supply: bq27xxx: Add power_supply_battery_info support
power: supply: bq27xxx: Enable data memory update for certain chips
power: supply: bq27xxx: Flag identical register maps when in debug mode
power: supply: bq27xxx: Remove duplicate register arrays

Matt Ranostay (2):
devicetree: property-units: Add uWh and uAh units
power: supply: bq27xxx: Add bulk transfer bus methods

 .../devicetree/bindings/power/supply/battery.txt   |  57 ++
 .../devicetree/bindings/power/supply/bq27xxx.txt   |  31 +-
 .../devicetree/bindings/property-units.txt         |   2 +
 Documentation/power/power_supply_class.txt         |  31 +-
 drivers/power/supply/Kconfig                       |  11 +
 drivers/power/supply/bq27xxx_battery.c             | 752 +++++++++++++++++----
 drivers/power/supply/bq27xxx_battery_i2c.c         | 134 +++-
 drivers/power/supply/power_supply_core.c           |  57 ++
 drivers/power/supply/power_supply_sysfs.c          |   1 +
 include/linux/power/bq27xxx_battery.h              |  30 +-
 include/linux/power_supply.h                       |  25 +
 11 files changed, 955 insertions(+), 176 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
Signature · 1 line
2.13.0