All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery
@ 2017-02-27  7:11 Liam Breck
  2017-02-27  7:11 ` [PATCH v8 2/9] devicetree: property-units: Add uWh and uAh units Liam Breck
                   ` (7 more replies)
  0 siblings, 8 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay

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 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 (5):
  devicetree: power: Add battery.txt
  devicetree: power: bq27xxx: Add monitored-battery documentation
  power: power_supply: Add power_supply_battery_info and API
  power: bq27xxx_battery: Add power_supply_battery_info support
  power: bq27xxx_battery: Add print_dm_blocks() to log chip memory

Matt Ranostay (4):
  devicetree: property-units: Add uWh and uAh units
  power: bq27xxx_battery: Define access methods to write chip registers
  power: bq27xxx_battery: Add BQ27425 chip id
  power: bq27xxx_battery_i2c: Add I2C bulk read/write functions

 .../devicetree/bindings/power/supply/battery.txt   |  42 ++
 .../devicetree/bindings/power/supply/bq27xxx.txt   |  11 +-
 .../devicetree/bindings/property-units.txt         |   2 +
 drivers/power/supply/bq27xxx_battery.c             | 551 ++++++++++++++++++++-
 drivers/power/supply/bq27xxx_battery_i2c.c         |  84 +++-
 drivers/power/supply/power_supply_core.c           |  40 ++
 include/linux/power/bq27xxx_battery.h              |   6 +-
 include/linux/power_supply.h                       |  18 +
 8 files changed, 747 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt

-- 
2.9.3

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

* [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found] ` <20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
@ 2017-02-27  7:11   ` Liam Breck
       [not found]     ` <20170227071117.18934-2-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
  2017-02-27  7:11   ` [PATCH v8 3/9] devicetree: power: bq27xxx: Add monitored-battery documentation Liam Breck
  1 sibling, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Andrew F. Davis, linux-pm-u79uwXL29TY76Z2rM5mHXA, Matt Ranostay,
	Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>

Documentation of static battery characteristics that can be defined
for batteries which cannot self-identify. This information is required
by fuel-gauge and charger chips for proper handling of the battery.

Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
---
 .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt

diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
new file mode 100644
index 0000000..3d916bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/battery.txt
@@ -0,0 +1,42 @@
+Battery Characteristics
+
+Required Properties:
+ - compatible: Must be "fixed-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
+
+Future Properties must be named for the corresponding elements in
+enum power_supply_property, defined in 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".
+
+Driver code should call power_supply_get_battery_info() to obtain
+battery properties via monitored-battery. For details see:
+  drivers/power/supply/power_supply_core.c
+  drivers/power/supply/bq27xxx_battery.c
+
+Example:
+
+	bat: battery {
+		compatible = "fixed-battery";
+		voltage-min-design-microvolt = <3200000>;
+		energy-full-design-microwatt-hours = <5290000>;
+		charge-full-design-microamp-hours = <1430000>;
+	};
+
+	charger: charger@11 {
+		....
+		monitored-battery = <&bat>;
+		...
+	};
+
+	fuel_gauge: fuel-gauge@22 {
+		....
+		monitored-battery = <&bat>;
+		...
+	};
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 2/9] devicetree: property-units: Add uWh and uAh units
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
       [not found] ` <20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Rob Herring,
	Mark Rutland, devicetree, linux-kernel, Liam Breck

From: Matt Ranostay <matt@ranostay.consulting>

Add entries for microwatt-hours and microamp-hours.

Cc: Rob Herring <robh@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
Acked-by: Sebastian Reichel <sre@kernel.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/property-units.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/property-units.txt b/Documentation/devicetree/bindings/property-units.txt
index 12278d7..0849618 100644
--- a/Documentation/devicetree/bindings/property-units.txt
+++ b/Documentation/devicetree/bindings/property-units.txt
@@ -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
-- 
2.9.3

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

* [PATCH v8 3/9] devicetree: power: bq27xxx: Add monitored-battery documentation
       [not found] ` <20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
  2017-02-27  7:11   ` [PATCH v8 1/9] devicetree: power: Add battery.txt Liam Breck
@ 2017-02-27  7:11   ` Liam Breck
       [not found]     ` <20170227071117.18934-4-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
  1 sibling, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Andrew F. Davis, linux-pm-u79uwXL29TY76Z2rM5mHXA, Matt Ranostay,
	Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>

Document monitored-battery = <&battery_node>

Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
---
 Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
index b0c95ef..cf83371 100644
--- a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
+++ b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
@@ -28,9 +28,18 @@ Required properties:
  * "ti,bq27621" - BQ27621
 - reg: integer, i2c address of the device.
 
+Optional properties:
+- monitored-battery: phandle of battery information devicetree node
+
+  See Documentation/devicetree/bindings/power/supply/battery.txt
+  If either of the referenced battery's *-full-design-*-hours properties are set,
+  then both must be.
+
 Example:
 
-bq27510g3 {
+bq27510g3 : fuel-gauge@55 {
     compatible = "ti,bq27510g3";
     reg = <0x55>;
+
+    monitored-battery = <&bat>;
 };
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 4/9] power: power_supply: Add power_supply_battery_info and API
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
  2017-02-27  7:11 ` [PATCH v8 2/9] devicetree: property-units: Add uWh and uAh units Liam Breck
       [not found] ` <20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
@ 2017-02-27  7:11 ` Liam Breck
  2017-02-27  7:11 ` [PATCH v8 5/9] power: bq27xxx_battery: Define access methods to write chip registers Liam Breck
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Liam Breck <kernel@networkimprov.net>

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

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 drivers/power/supply/power_supply_core.c | 40 ++++++++++++++++++++++++++++++++
 include/linux/power_supply.h             | 18 ++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index a74d8ca..c121931 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/power_supply.h>
 #include <linux/thermal.h>
 #include "power_supply.h"
@@ -487,6 +488,45 @@ struct power_supply *devm_power_supply_get_by_phandle(struct device *dev,
 EXPORT_SYMBOL_GPL(devm_power_supply_get_by_phandle);
 #endif /* CONFIG_OF */
 
+int power_supply_get_battery_info(struct power_supply *psy,
+				  struct power_supply_battery_info *info)
+{
+	struct device_node *battery_np;
+	const char *value;
+	int err;
+
+	info->energy_full_design_uwh = -EINVAL;
+	info->charge_full_design_uah = -EINVAL;
+	info->voltage_min_design_uv  = -EINVAL;
+
+	if (!psy->of_node) {
+		dev_warn(&psy->dev, "%s currently only supports devicetree\n",
+			 __func__);
+		return -ENXIO;
+	}
+
+	battery_np = of_parse_phandle(psy->of_node, "monitored-battery", 0);
+	if (!battery_np)
+		return -ENODEV;
+
+	err = of_property_read_string(battery_np, "compatible", &value);
+	if (err)
+		return err;
+
+	if (strcmp("fixed-battery", value))
+		return -ENODEV;
+
+	of_property_read_u32(battery_np, "energy-full-design-microwatt-hours",
+			     &info->energy_full_design_uwh);
+	of_property_read_u32(battery_np, "charge-full-design-microamp-hours",
+			     &info->charge_full_design_uah);
+	of_property_read_u32(battery_np, "voltage-min-design-microvolt",
+			     &info->voltage_min_design_uv);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(power_supply_get_battery_info);
+
 int power_supply_get_property(struct power_supply *psy,
 			    enum power_supply_property psp,
 			    union power_supply_propval *val)
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 3965503..e84f1d3 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -288,6 +288,21 @@ 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 */
+};
+
 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 +321,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);
-- 
2.9.3

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

* [PATCH v8 5/9] power: bq27xxx_battery: Define access methods to write chip registers
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
                   ` (2 preceding siblings ...)
  2017-02-27  7:11 ` [PATCH v8 4/9] power: power_supply: Add power_supply_battery_info and API Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
  2017-02-27  7:11 ` [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id Liam Breck
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Matt Ranostay <matt@ranostay.consulting>

write(), read_bulk(), write_bulk() support setting chip registers,
e.g. with data obtained from power_supply_battery_info.

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 include/linux/power/bq27xxx_battery.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index bed9557..92df553 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -32,6 +32,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 {
-- 
2.9.3

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

* [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
                   ` (3 preceding siblings ...)
  2017-02-27  7:11 ` [PATCH v8 5/9] power: bq27xxx_battery: Define access methods to write chip registers Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
  2017-02-27 16:28   ` Andrew F. Davis
  2017-02-27  7:11 ` [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support Liam Breck
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Matt Ranostay <matt@ranostay.consulting>

This patch does not alter the function of the driver.
This chip ID is referenced in the devicetree code.

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 drivers/power/supply/bq27xxx_battery.c     | 23 ++++++++++++++++++++++-
 drivers/power/supply/bq27xxx_battery_i2c.c |  2 +-
 include/linux/power/bq27xxx_battery.h      |  3 ++-
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 7272d1e..7475a5f 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -259,6 +259,25 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x18,
 	},
+	[BQ27425] = {
+		[BQ27XXX_REG_CTRL] = 0x00,
+		[BQ27XXX_REG_TEMP] = 0x02,
+		[BQ27XXX_REG_INT_TEMP] = 0x1e,
+		[BQ27XXX_REG_VOLT] = 0x04,
+		[BQ27XXX_REG_AI] = 0x10,
+		[BQ27XXX_REG_FLAGS] = 0x06,
+		[BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_NAC] = 0x08,
+		[BQ27XXX_REG_FCC] = 0x0e,
+		[BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+		[BQ27XXX_REG_SOC] = 0x1c,
+		[BQ27XXX_REG_DCAP] = 0x3c,
+		[BQ27XXX_REG_AP] = 0x18,
+	},
 };
 
 static enum power_supply_property bq27000_battery_props[] = {
@@ -427,6 +446,7 @@ static struct {
 	BQ27XXX_PROP(BQ27541, bq27541_battery_props),
 	BQ27XXX_PROP(BQ27545, bq27545_battery_props),
 	BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+	BQ27XXX_PROP(BQ27425, bq27421_battery_props),
 };
 
 static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -682,6 +702,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
 		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
 	case BQ27530:
 	case BQ27421:
+	case BQ27425:
 		return flags & BQ27XXX_FLAG_OT;
 	default:
 		return false;
@@ -693,7 +714,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
  */
 static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
 {
-	if (di->chip == BQ27530 || di->chip == BQ27421)
+	if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
 		return flags & BQ27XXX_FLAG_UT;
 
 	return false;
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 5c5c3a6..d7da535 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -159,7 +159,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
 	{ "bq27742", BQ27541 },
 	{ "bq27545", BQ27545 },
 	{ "bq27421", BQ27421 },
-	{ "bq27425", BQ27421 },
+	{ "bq27425", BQ27425 },
 	{ "bq27441", BQ27421 },
 	{ "bq27621", BQ27421 },
 	{},
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index 92df553..4925478 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -9,7 +9,8 @@ enum bq27xxx_chip {
 	BQ27530, /* bq27530, bq27531 */
 	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
 	BQ27545, /* bq27545 */
-	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+	BQ27421, /* bq27421, bq27441, bq27621 */
+	BQ27425, /* bq27425 */
 };
 
 /**
-- 
2.9.3

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

* [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
                   ` (4 preceding siblings ...)
  2017-02-27  7:11 ` [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
  2017-02-27 18:06   ` Andrew F. Davis
  2017-03-03 21:36   ` Liam Breck
  2017-02-27  7:11 ` [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory Liam Breck
  2017-02-27  7:11 ` [PATCH v8 9/9] power: bq27xxx_battery_i2c: Add I2C bulk read/write functions Liam Breck
  7 siblings, 2 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Liam Breck <kernel@networkimprov.net>

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

BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
and writes battery data to chip RAM or non-volatile memory.

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
 1 file changed, 456 insertions(+), 2 deletions(-)

diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 7475a5f..41d4ce7 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -51,7 +51,7 @@
 
 #include <linux/power/bq27xxx_battery.h>
 
-#define DRIVER_VERSION		"1.2.0"
+#define DRIVER_VERSION		"1.3.0"
 
 #define BQ27XXX_MANUFACTURER	"Texas Instruments"
 
@@ -59,6 +59,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(5)
 #define BQ27XXX_FLAG_FC		BIT(9)
 #define BQ27XXX_FLAG_OTD	BIT(14)
 #define BQ27XXX_FLAG_OTC	BIT(15)
@@ -72,6 +73,11 @@
 #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_RS			(20) /* Resistor sense mOhm */
 #define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
 #define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
@@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
 	BQ27XXX_REG_SOC,	/* State-of-Charge */
 	BQ27XXX_REG_DCAP,	/* Design Capacity */
 	BQ27XXX_REG_AP,		/* Average Power */
+	BQ27XXX_DM_CTRL,	/* BlockDataControl() */
+	BQ27XXX_DM_CLASS,	/* DataClass() */
+	BQ27XXX_DM_BLOCK,	/* DataBlock() */
+	BQ27XXX_DM_DATA,	/* BlockData() */
+	BQ27XXX_DM_CKSUM,	/* BlockDataChecksum() */
 	BQ27XXX_REG_MAX,	/* sentinel */
 };
 
@@ -125,6 +136,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,
@@ -144,6 +160,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,
 	},
 	[BQ27500] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27510] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x20,
 		[BQ27XXX_REG_DCAP] = 0x2e,
 		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27530] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
 		[BQ27XXX_REG_AP] = 0x24,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27541] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x24,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27545] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x2c,
 		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
 		[BQ27XXX_REG_AP] = 0x24,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27421] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x1c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x18,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 	[BQ27425] = {
 		[BQ27XXX_REG_CTRL] = 0x00,
@@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
 		[BQ27XXX_REG_SOC] = 0x1c,
 		[BQ27XXX_REG_DCAP] = 0x3c,
 		[BQ27XXX_REG_AP] = 0x18,
+		[BQ27XXX_DM_CTRL] = 0x61,
+		[BQ27XXX_DM_CLASS] = 0x3e,
+		[BQ27XXX_DM_BLOCK] = 0x3f,
+		[BQ27XXX_DM_DATA] = 0x40,
+		[BQ27XXX_DM_CKSUM] = 0x60,
 	},
 };
 
@@ -452,6 +508,81 @@ static struct {
 static DEFINE_MUTEX(bq27xxx_list_lock);
 static LIST_HEAD(bq27xxx_battery_devices);
 
+#define BQ27XXX_DM_SZ			32
+
+#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
+
+struct bq27xxx_dm_reg {
+	u8 subclass_id;
+	u8 offset;
+	u8 bytes;
+	u16 min, max;
+};
+
+struct bq27xxx_dm_buf {
+	u8 class;
+	u8 block;
+	u8 a[BQ27XXX_DM_SZ];
+	bool full, updt;
+};
+
+#define BQ27XXX_DM_BUF(di, i) { \
+	.class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
+	.block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
+}
+
+static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
+				      struct bq27xxx_dm_reg *reg) {
+	if (buf->class == reg->subclass_id
+	 && buf->block == reg->offset / BQ27XXX_DM_SZ)
+		return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
+
+	return NULL;
+}
+
+enum bq27xxx_dm_reg_id {
+	BQ27XXX_DM_DESIGN_CAPACITY = 0,
+	BQ27XXX_DM_DESIGN_ENERGY,
+	BQ27XXX_DM_TERMINATE_VOLTAGE,
+};
+
+static const char* bq27xxx_dm_reg_name[] = {
+	[BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
+	[BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
+	[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 },
+};
+
+static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
+	[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[] = { /* not tested */
+//	[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 },
+//};
+
+static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
+	[BQ27421] = bq27421_dm_regs, /* and BQ27441 */
+	[BQ27425] = bq27425_dm_regs,
+//	[BQ27621] = bq27621_dm_regs,
+};
+
+static u32 bq27xxx_unseal_keys[] = {
+	[BQ27421] = 0x80008000, /* and BQ27441 */
+	[BQ27425] = 0x04143672,
+//	[BQ27621] = 0x80008000,
+};
+
+
 static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
 {
 	struct bq27xxx_device_info *di;
@@ -496,6 +627,318 @@ static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
 	return di->bus.read(di, di->regs[reg_index], single);
 }
 
+static int bq27xxx_battery_set_seal_state(struct bq27xxx_device_info *di,
+					  bool state)
+{
+	int ret;
+
+	if (state) {
+		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], BQ27XXX_SEALED, false);
+		if (ret < 0)
+			goto out;
+	} else {
+		u32 key = bq27xxx_unseal_keys[di->chip];
+
+		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], (u16)(key >> 16), false);
+		if (ret < 0)
+			goto out;
+
+		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], (u16)key, false);
+		if (ret < 0)
+			goto out;
+	}
+	return 0;
+
+out:
+	dev_err(di->dev, "bus error on %s: %d\n", state ? "seal" : "unseal", ret);
+	return ret;
+}
+
+static u8 bq27xxx_battery_checksum(struct bq27xxx_dm_buf *buf)
+{
+	u16 sum = 0;
+	int i;
+
+	for (i = 0; i < BQ27XXX_DM_SZ; i++)
+		sum += buf->a[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;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CLASS], buf->class, true);
+	if (ret < 0)
+		goto out;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_BLOCK], buf->block, true);
+	if (ret < 0)
+		goto out;
+
+	BQ27XXX_MSLEEP(1);
+
+	ret = di->bus.read_bulk(di, di->regs[BQ27XXX_DM_DATA], buf->a, BQ27XXX_DM_SZ);
+	if (ret < 0)
+		goto out;
+
+	ret = di->bus.read(di, di->regs[BQ27XXX_DM_CKSUM], true);
+	if (ret < 0)
+		goto out;
+
+	if ((u8)ret != bq27xxx_battery_checksum(buf)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	buf->full = true;
+	buf->updt = false;
+	return 0;
+
+out:
+	dev_err(di->dev, "bus error reading chip memory: %d\n", ret);
+	return ret;
+}
+
+static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,
+					    struct bq27xxx_dm_buf *buf,
+					    enum bq27xxx_dm_reg_id reg_id,
+					    unsigned int val)
+{
+	struct bq27xxx_dm_reg *reg = &bq27xxx_dm_regs[di->chip][reg_id];
+	const char* str = bq27xxx_dm_reg_name[reg_id];
+	u16 *prev = bq27xxx_dm_buf_ptr(buf, reg);
+
+	if (prev == NULL) {
+		dev_warn(di->dev, "buffer does not match %s dm spec\n", str);
+		return;
+	}
+
+	if (reg->bytes != 2) {
+		dev_warn(di->dev, "%s dm spec has unsupported byte size\n", str);
+		return;
+	}
+
+	if (!buf->full)
+		return;
+
+	if (be16_to_cpup(prev) == val) {
+		dev_info(di->dev, "%s has %u\n", str, val);
+		return;
+	}
+
+	dev_info(di->dev, "update %s to %u\n", str, val);
+
+	*prev = cpu_to_be16(val);
+	buf->updt = true;
+}
+
+static int bq27xxx_battery_set_cfgupdate(struct bq27xxx_device_info *di,
+					 bool state)
+{
+	int ret, try=100;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL],
+			    state ? BQ27XXX_SET_CFGUPDATE : BQ27XXX_SOFT_RESET,
+			    false);
+	if (ret < 0)
+		goto out;
+
+	if (di->chip == BQ27425) /* chip fails to set/clear flag */
+		return 0;
+
+	do {
+		BQ27XXX_MSLEEP(5);
+		ret = di->bus.read(di, di->regs[BQ27XXX_REG_FLAGS], false);
+		if (ret < 0)
+			goto out;
+	} while (!(ret & BQ27XXX_FLAG_CFGUP) == state && --try);
+
+	if (100-try) /* remove after other cfgupdate parts are tested */
+		dev_info(di->dev, "cfgupdate %d, retries %d\n", state, 100-try);
+
+	if (try)
+		return 0;
+
+	dev_err(di->dev, "timed out waiting for cfgupdate flag %d\n", state);
+	return -EINVAL;
+
+out:
+	dev_err(di->dev, "bus error on %s: %d\n", state ? "set_cfgupdate" : "soft_reset", ret);
+	return ret;
+}
+
+static int bq27xxx_battery_write_dm_block(struct bq27xxx_device_info *di,
+					  struct bq27xxx_dm_buf *buf)
+{
+	bool cfgup = di->chip == BQ27425 || di->chip == BQ27421; /* || BQ27441 || BQ27621 */
+	int ret;
+
+	if (!buf->updt)
+		return 0;
+
+	if (cfgup) {
+		ret = bq27xxx_battery_set_cfgupdate(di, true);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CTRL], 0, true);
+	if (ret < 0)
+		goto out;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CLASS], buf->class, true);
+	if (ret < 0)
+		goto out;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_BLOCK], buf->block, true);
+	if (ret < 0)
+		goto out;
+
+	BQ27XXX_MSLEEP(1);
+
+	ret = di->bus.write_bulk(di, di->regs[BQ27XXX_DM_DATA], buf->a, BQ27XXX_DM_SZ);
+	if (ret < 0)
+		goto out;
+
+	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CKSUM],
+			    bq27xxx_battery_checksum(buf), true);
+	if (ret < 0)
+		goto out;
+
+	/* THE FOLLOWING SEQUENCE IS TOXIC. DO NOT USE!
+	 * If the 'time' delay is insufficient, NVM corruption results on
+	 * the '425 chip (and perhaps others), which could damage the chip.
+	 * It was suggested in this TI tool:
+	 *   http://git.ti.com/bms-linux/bqtool/blobs/master/gauge.c#line328
+	 *
+	 * 1. sleep 'time' after above write(BQ27XXX_DM_CKSUM, ...)
+	 * 2. write(BQ27XXX_DM_BLOCK, buf->block)
+	 * 3. sum = read(BQ27XXX_DM_CKSUM)
+	 * 4. if (sum != bq27xxx_battery_checksum(buf))
+	 *      error
+	 */
+
+	if (cfgup) {
+		BQ27XXX_MSLEEP(1);
+		ret = bq27xxx_battery_set_cfgupdate(di, false);
+		if (ret < 0)
+			return ret;
+	}
+
+	buf->updt = false;
+	return 0;
+
+out:
+	if (cfgup)
+		bq27xxx_battery_set_cfgupdate(di, false);
+
+	dev_err(di->dev, "bus error writing chip memory: %d\n", ret);
+	return ret;
+}
+
+static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
+				       struct power_supply_battery_info *info)
+{
+	struct bq27xxx_dm_buf bd = BQ27XXX_DM_BUF(di, BQ27XXX_DM_DESIGN_ENERGY);
+	struct bq27xxx_dm_buf bt = BQ27XXX_DM_BUF(di, BQ27XXX_DM_TERMINATE_VOLTAGE);
+
+	if (info->charge_full_design_uah != -EINVAL
+	 && info->energy_full_design_uwh != -EINVAL) {
+		bq27xxx_battery_read_dm_block(di, &bd);
+		/* assume design energy & capacity are in same block */
+		bq27xxx_battery_update_dm_block(di, &bd,
+					BQ27XXX_DM_DESIGN_CAPACITY,
+					info->charge_full_design_uah / 1000);
+		bq27xxx_battery_update_dm_block(di, &bd,
+					BQ27XXX_DM_DESIGN_ENERGY,
+					info->energy_full_design_uwh / 1000);
+	}
+
+	if (info->voltage_min_design_uv != -EINVAL) {
+		bool same = bd.class == bt.class && bd.block == bt.block;
+		if (!same)
+			bq27xxx_battery_read_dm_block(di, &bt);
+		bq27xxx_battery_update_dm_block(di, same ? &bd : &bt,
+					BQ27XXX_DM_TERMINATE_VOLTAGE,
+					info->voltage_min_design_uv / 1000);
+	}
+
+	bq27xxx_battery_write_dm_block(di, &bd);
+	bq27xxx_battery_write_dm_block(di, &bt);
+}
+
+void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
+{
+	struct power_supply_battery_info info = {};
+	unsigned int min, max;
+
+	/* functions don't exist for writing data so abort */
+	if (!di->bus.write || !di->bus.write_bulk)
+		return;
+
+	/* no settings to be set for this chipset so abort */
+	if (!bq27xxx_dm_regs[di->chip])
+		return;
+
+	if (bq27xxx_battery_set_seal_state(di, false) < 0)
+		return;
+
+	if (power_supply_get_battery_info(di->bat, &info) < 0)
+		goto out;
+
+	if (info.energy_full_design_uwh != info.charge_full_design_uah) {
+		if (info.energy_full_design_uwh == -EINVAL)
+			dev_warn(di->dev,
+				"missing battery:energy-full-design-microwatt-hours\n");
+		else if (info.charge_full_design_uah == -EINVAL)
+			dev_warn(di->dev,
+				"missing battery:charge-full-design-microamp-hours\n");
+	}
+
+	/* assume min == 0 */
+	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_DESIGN_ENERGY].max;
+	if (info.energy_full_design_uwh > max * 1000) {
+		dev_err(di->dev,
+		       "invalid battery:energy-full-design-microwatt-hours %d\n",
+			info.energy_full_design_uwh);
+		info.energy_full_design_uwh = -EINVAL;
+	}
+
+	/* assume min == 0 */
+	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_DESIGN_CAPACITY].max;
+	if (info.charge_full_design_uah > max * 1000) {
+		dev_err(di->dev,
+		       "invalid battery:charge-full-design-microamp-hours %d\n",
+			info.charge_full_design_uah);
+		info.charge_full_design_uah = -EINVAL;
+	}
+
+	min = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_TERMINATE_VOLTAGE].min;
+	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_TERMINATE_VOLTAGE].max;
+	if ((info.voltage_min_design_uv < min * 1000
+	  || info.voltage_min_design_uv > max * 1000)
+	  && info.voltage_min_design_uv != -EINVAL) {
+		dev_err(di->dev,
+		       "invalid battery:voltage-min-design-microvolt %d\n",
+			info.voltage_min_design_uv);
+		info.voltage_min_design_uv = -EINVAL;
+	}
+
+	if ((info.energy_full_design_uwh == -EINVAL
+	  || info.charge_full_design_uah == -EINVAL)
+	  && info.voltage_min_design_uv  == -EINVAL)
+		goto out;
+
+	bq27xxx_battery_set_config(di, &info);
+
+out:
+	bq27xxx_battery_set_seal_state(di, true);
+}
+
 /*
  * Return the battery State-of-Charge
  * Or < 0 if something fails.
@@ -1006,6 +1449,13 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 		ret = bq27xxx_simple_value(di->charge_design_full, val);
 		break;
+	/*
+	 * TODO: Implement these to make registers set from
+	 * power_supply_battery_info visible in sysfs.
+	 */
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		return -EINVAL;
 	case POWER_SUPPLY_PROP_CYCLE_COUNT:
 		ret = bq27xxx_simple_value(di->cache.cycle_count, val);
 		break;
@@ -1039,7 +1489,10 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 {
 	struct power_supply_desc *psy_desc;
-	struct power_supply_config psy_cfg = { .drv_data = di, };
+	struct power_supply_config psy_cfg = {
+		.of_node = di->dev->of_node,
+		.drv_data = di,
+	};
 
 	INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
 	mutex_init(&di->lock);
@@ -1064,6 +1517,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
 
 	dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
 
+	bq27xxx_battery_settings(di);
 	bq27xxx_battery_update(di);
 
 	mutex_lock(&bq27xxx_list_lock);
-- 
2.9.3

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

* [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
                   ` (5 preceding siblings ...)
  2017-02-27  7:11 ` [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
  2017-02-27 18:07   ` Andrew F. Davis
  2017-02-27  7:11 ` [PATCH v8 9/9] power: bq27xxx_battery_i2c: Add I2C bulk read/write functions Liam Breck
  7 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Liam Breck <kernel@networkimprov.net>

Enable listing of chip RAM and/or NVM at startup, for debugging use.
Intially supports BQ27425. Support for other chips may be added.

Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 drivers/power/supply/bq27xxx_battery.c | 70 ++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 41d4ce7..8ba0568 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -703,6 +703,74 @@ static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,
 	return ret;
 }
 
+/* Translate F4 floating point values to/from hexadecimal:
+ *   perl -e 'printf("%08x\n", unpack("I", pack("f", 3.93e-4   )))' # 39ce0b91
+ *   perl -e 'printf("%f\n"  , unpack("f", pack("I", 0x39ce0b91)))' # 0.000393
+ */
+
+#define BQ27XXX_DM_INFO(f,o,v) dev_info(di->dev, "offset %d, " f "\n", o, v)
+
+static void bq27xxx_battery_print_dm_blocks(struct bq27xxx_device_info *di) {
+	enum { H1, H2, H4, I1, I2, U1, F4 };
+
+	struct dm_reg { int offset, type; }
+		/* each array row describes one data block */
+		c425_s82[][10] = {
+			{ { 2,H1},{ 3,I2},{ 5,H2},{12,I2},{14,I2},{18,I2},{22,I2},{29,U1},{30,I2},{99,0} },
+			{ {32,I2},{34,I2},{36,I2},{38,U1},{39,U1},{40,F4},{99,0} },
+		},
+		c425_s104[][10] = {
+			{ { 0,I2},{ 2,I1},{ 3,I1},{ 4,I1},{99,0} },
+		},
+		c425_s105[][10] = {
+			{ { 0,F4},{ 4,I2},{99,0} },
+		};
+		/* add more subclass maps here */
+
+	struct dm_class { int id, blocks; struct dm_reg (*reg)[10]; }
+		c425[] = {
+			{ .id =  82, .blocks = 2, .reg = c425_s82  },
+			{ .id = 104, .blocks = 1, .reg = c425_s104 },
+			{ .id = 105, .blocks = 1, .reg = c425_s105 },
+			{ .reg = NULL }
+		};
+		/* add more chip maps here */
+
+	struct dm_class *chip = c425; /* set to your chip */
+
+	struct bq27xxx_dm_buf buf = { };
+	int c, b, r;
+
+	for (c=0; chip[c].reg != NULL; ++c) {
+		buf.class = chip[c].id;
+		dev_info(di->dev, "subclass %d registers...\n", chip[c].id);
+
+		for (b=0; b < chip[c].blocks; ++b) {
+			buf.block = b;
+			if (bq27xxx_battery_read_dm_block(di, &buf) < 0)
+				continue;
+
+			for (r=0; chip[c].reg[b][r].offset != 99; ++r) {
+				int o = chip[c].reg[b][r].offset;
+				u8* p = &buf.a[o % BQ27XXX_DM_SZ];
+
+				switch (chip[c].reg[b][r].type) {
+				case H1: BQ27XXX_DM_INFO("%02x", o,   *p); break;
+				case I1: BQ27XXX_DM_INFO("%d", o, (s8)*p); break;
+				case U1: BQ27XXX_DM_INFO("%u", o,     *p); break;
+				case H2: BQ27XXX_DM_INFO("%04x", o,
+						   be16_to_cpup((u16*)p)); break;
+				case I2: BQ27XXX_DM_INFO("%d", o,
+					      (s16)be16_to_cpup((u16*)p)); break;
+				case H4:
+				case F4: BQ27XXX_DM_INFO("%08x", o,
+						   be32_to_cpup((u32*)p)); break;
+				}
+			}
+		}
+	}
+}
+
 static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,
 					    struct bq27xxx_dm_buf *buf,
 					    enum bq27xxx_dm_reg_id reg_id,
@@ -936,6 +1004,8 @@ void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
 	bq27xxx_battery_set_config(di, &info);
 
 out:
+	/* bq27xxx_battery_print_dm_blocks(di); uncomment for debugging */
+	(void)bq27xxx_battery_print_dm_blocks; /* prevent compiler warning */
 	bq27xxx_battery_set_seal_state(di, true);
 }
 
-- 
2.9.3

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

* [PATCH v8 9/9] power: bq27xxx_battery_i2c: Add I2C bulk read/write functions
  2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
                   ` (6 preceding siblings ...)
  2017-02-27  7:11 ` [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory Liam Breck
@ 2017-02-27  7:11 ` Liam Breck
  7 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-02-27  7:11 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

From: Matt Ranostay <matt@ranostay.consulting>

write(), read_bulk(), write_bulk() are required by bq27xxx_battery
devicetree code.

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
---
 drivers/power/supply/bq27xxx_battery_i2c.c | 82 +++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index d7da535..0414573 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -38,7 +38,7 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
 {
 	struct i2c_client *client = to_i2c_client(di->dev);
 	struct i2c_msg msg[2];
-	unsigned char data[2];
+	u8 data[2];
 	int ret;
 
 	if (!client->adapter)
@@ -68,6 +68,82 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
 	return ret;
 }
 
+static int bq27xxx_battery_i2c_write(struct bq27xxx_device_info *di, u8 reg,
+				     int value, bool single)
+{
+	struct i2c_client *client = to_i2c_client(di->dev);
+	struct i2c_msg msg;
+	u8 data[4];
+	int ret;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	data[0] = reg;
+	if (single) {
+		data[1] = (u8) value;
+		msg.len = 2;
+	} else {
+		put_unaligned_le16(value, &data[1]);
+		msg.len = 3;
+	}
+
+	msg.buf = data;
+	msg.addr = client->addr;
+	msg.flags = 0;
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		return ret;
+	if (ret != 1)
+		return -EINVAL;
+	return 0;
+}
+
+static int bq27xxx_battery_i2c_bulk_read(struct bq27xxx_device_info *di, u8 reg,
+					 u8 *data, int len)
+{
+	struct i2c_client *client = to_i2c_client(di->dev);
+	int ret;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	ret = i2c_smbus_read_i2c_block_data(client, reg, len, data);
+	if (ret < 0)
+		return ret;
+	if (ret != len)
+		return -EINVAL;
+	return 0;
+}
+
+static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
+					  u8 reg, u8 *data, int len)
+{
+	struct i2c_client *client = to_i2c_client(di->dev);
+	struct i2c_msg msg;
+	u8 buf[33];
+	int ret;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	buf[0] = reg;
+	memcpy(&buf[1], data, len);
+
+	msg.buf = buf;
+	msg.addr = client->addr;
+	msg.flags = 0;
+	msg.len = len + 1;
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		return ret;
+	if (ret != 1)
+		return -EINVAL;
+	return 0;
+}
+
 static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 				     const struct i2c_device_id *id)
 {
@@ -95,7 +171,11 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 	di->dev = &client->dev;
 	di->chip = id->driver_data;
 	di->name = name;
+
 	di->bus.read = bq27xxx_battery_i2c_read;
+	di->bus.write = bq27xxx_battery_i2c_write;
+	di->bus.read_bulk = bq27xxx_battery_i2c_bulk_read;
+	di->bus.write_bulk = bq27xxx_battery_i2c_bulk_write;
 
 	ret = bq27xxx_battery_setup(di);
 	if (ret)
-- 
2.9.3

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

* Re: [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id
  2017-02-27  7:11 ` [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id Liam Breck
@ 2017-02-27 16:28   ` Andrew F. Davis
  0 siblings, 0 replies; 37+ messages in thread
From: Andrew F. Davis @ 2017-02-27 16:28 UTC (permalink / raw)
  To: Liam Breck, Sebastian Reichel; +Cc: linux-pm, Matt Ranostay, Liam Breck

On 02/27/2017 01:11 AM, Liam Breck wrote:
> From: Matt Ranostay <matt@ranostay.consulting>
> 
> This patch does not alter the function of the driver.
> This chip ID is referenced in the devicetree code.
> 
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> Signed-off-by: Liam Breck <kernel@networkimprov.net>

I think I already acked this one..

Acked-by: Andrew F. Davis <afd@ti.com>

> ---
>  drivers/power/supply/bq27xxx_battery.c     | 23 ++++++++++++++++++++++-
>  drivers/power/supply/bq27xxx_battery_i2c.c |  2 +-
>  include/linux/power/bq27xxx_battery.h      |  3 ++-
>  3 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 7272d1e..7475a5f 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c
> @@ -259,6 +259,25 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_DCAP] = 0x3c,
>  		[BQ27XXX_REG_AP] = 0x18,
>  	},
> +	[BQ27425] = {
> +		[BQ27XXX_REG_CTRL] = 0x00,
> +		[BQ27XXX_REG_TEMP] = 0x02,
> +		[BQ27XXX_REG_INT_TEMP] = 0x1e,
> +		[BQ27XXX_REG_VOLT] = 0x04,
> +		[BQ27XXX_REG_AI] = 0x10,
> +		[BQ27XXX_REG_FLAGS] = 0x06,
> +		[BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_NAC] = 0x08,
> +		[BQ27XXX_REG_FCC] = 0x0e,
> +		[BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_AE] = INVALID_REG_ADDR,
> +		[BQ27XXX_REG_SOC] = 0x1c,
> +		[BQ27XXX_REG_DCAP] = 0x3c,
> +		[BQ27XXX_REG_AP] = 0x18,
> +	},
>  };
>  
>  static enum power_supply_property bq27000_battery_props[] = {
> @@ -427,6 +446,7 @@ static struct {
>  	BQ27XXX_PROP(BQ27541, bq27541_battery_props),
>  	BQ27XXX_PROP(BQ27545, bq27545_battery_props),
>  	BQ27XXX_PROP(BQ27421, bq27421_battery_props),
> +	BQ27XXX_PROP(BQ27425, bq27421_battery_props),
>  };
>  
>  static DEFINE_MUTEX(bq27xxx_list_lock);
> @@ -682,6 +702,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>  		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
>  	case BQ27530:
>  	case BQ27421:
> +	case BQ27425:
>  		return flags & BQ27XXX_FLAG_OT;
>  	default:
>  		return false;
> @@ -693,7 +714,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
>   */
>  static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
>  {
> -	if (di->chip == BQ27530 || di->chip == BQ27421)
> +	if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
>  		return flags & BQ27XXX_FLAG_UT;
>  
>  	return false;
> diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
> index 5c5c3a6..d7da535 100644
> --- a/drivers/power/supply/bq27xxx_battery_i2c.c
> +++ b/drivers/power/supply/bq27xxx_battery_i2c.c
> @@ -159,7 +159,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
>  	{ "bq27742", BQ27541 },
>  	{ "bq27545", BQ27545 },
>  	{ "bq27421", BQ27421 },
> -	{ "bq27425", BQ27421 },
> +	{ "bq27425", BQ27425 },
>  	{ "bq27441", BQ27421 },
>  	{ "bq27621", BQ27421 },
>  	{},
> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
> index 92df553..4925478 100644
> --- a/include/linux/power/bq27xxx_battery.h
> +++ b/include/linux/power/bq27xxx_battery.h
> @@ -9,7 +9,8 @@ enum bq27xxx_chip {
>  	BQ27530, /* bq27530, bq27531 */
>  	BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
>  	BQ27545, /* bq27545 */
> -	BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
> +	BQ27421, /* bq27421, bq27441, bq27621 */
> +	BQ27425, /* bq27425 */
>  };
>  
>  /**
> 

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27  7:11 ` [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support Liam Breck
@ 2017-02-27 18:06   ` Andrew F. Davis
  2017-02-27 20:05     ` Liam Breck
  2017-03-03 21:36   ` Liam Breck
  1 sibling, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-02-27 18:06 UTC (permalink / raw)
  To: Liam Breck, Sebastian Reichel; +Cc: linux-pm, Matt Ranostay, Liam Breck

On 02/27/2017 01:11 AM, Liam Breck wrote:
> From: Liam Breck <kernel@networkimprov.net>
> 
> Previously there was no way to configure chip registers in the event that the
> defaults didn't match the battery in question.
> 
> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
> and writes battery data to chip RAM or non-volatile memory.
> 
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> Signed-off-by: Liam Breck <kernel@networkimprov.net>
> ---
>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>  1 file changed, 456 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 7475a5f..41d4ce7 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c
> @@ -51,7 +51,7 @@
>  
>  #include <linux/power/bq27xxx_battery.h>
>  
> -#define DRIVER_VERSION		"1.2.0"
> +#define DRIVER_VERSION		"1.3.0"
>  
>  #define BQ27XXX_MANUFACTURER	"Texas Instruments"
>  
> @@ -59,6 +59,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(5)
>  #define BQ27XXX_FLAG_FC		BIT(9)
>  #define BQ27XXX_FLAG_OTD	BIT(14)
>  #define BQ27XXX_FLAG_OTC	BIT(15)
> @@ -72,6 +73,11 @@
>  #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_RS			(20) /* Resistor sense mOhm */
>  #define BQ27XXX_POWER_CONSTANT		(29200) /* 29.2 µV^2 * 1000 */
>  #define BQ27XXX_CURRENT_CONSTANT	(3570) /* 3.57 µV * 1000 */
> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>  	BQ27XXX_REG_SOC,	/* State-of-Charge */
>  	BQ27XXX_REG_DCAP,	/* Design Capacity */
>  	BQ27XXX_REG_AP,		/* Average Power */
> +	BQ27XXX_DM_CTRL,	/* BlockDataControl() */

/* Block Data Control */

> +	BQ27XXX_DM_CLASS,	/* DataClass() */

/* Data Class */

etc..

> +	BQ27XXX_DM_BLOCK,	/* DataBlock() */
> +	BQ27XXX_DM_DATA,	/* BlockData() */
> +	BQ27XXX_DM_CKSUM,	/* BlockDataChecksum() */
>  	BQ27XXX_REG_MAX,	/* sentinel */
>  };
>  
> @@ -125,6 +136,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,
> @@ -144,6 +160,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,
>  	},
>  	[BQ27500] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x2c,
>  		[BQ27XXX_REG_DCAP] = 0x3c,
>  		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27510] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x20,
>  		[BQ27XXX_REG_DCAP] = 0x2e,
>  		[BQ27XXX_REG_AP] = INVALID_REG_ADDR,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27530] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x2c,
>  		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>  		[BQ27XXX_REG_AP] = 0x24,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27541] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x2c,
>  		[BQ27XXX_REG_DCAP] = 0x3c,
>  		[BQ27XXX_REG_AP] = 0x24,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27545] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x2c,
>  		[BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>  		[BQ27XXX_REG_AP] = 0x24,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27421] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x1c,
>  		[BQ27XXX_REG_DCAP] = 0x3c,
>  		[BQ27XXX_REG_AP] = 0x18,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,
>  	},
>  	[BQ27425] = {
>  		[BQ27XXX_REG_CTRL] = 0x00,
> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>  		[BQ27XXX_REG_SOC] = 0x1c,
>  		[BQ27XXX_REG_DCAP] = 0x3c,
>  		[BQ27XXX_REG_AP] = 0x18,
> +		[BQ27XXX_DM_CTRL] = 0x61,
> +		[BQ27XXX_DM_CLASS] = 0x3e,
> +		[BQ27XXX_DM_BLOCK] = 0x3f,
> +		[BQ27XXX_DM_DATA] = 0x40,
> +		[BQ27XXX_DM_CKSUM] = 0x60,

That wasn't so painful was it :)

>  	},
>  };
>  
> @@ -452,6 +508,81 @@ static struct {
>  static DEFINE_MUTEX(bq27xxx_list_lock);
>  static LIST_HEAD(bq27xxx_battery_devices);
>  
> +#define BQ27XXX_DM_SZ			32
> +
> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
> +
> +struct bq27xxx_dm_reg {
> +	u8 subclass_id;
> +	u8 offset;
> +	u8 bytes;
> +	u16 min, max;
> +};
> +
> +struct bq27xxx_dm_buf {
> +	u8 class;
> +	u8 block;
> +	u8 a[BQ27XXX_DM_SZ];
> +	bool full, updt;
> +};
> +
> +#define BQ27XXX_DM_BUF(di, i) { \
> +	.class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
> +	.block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
> +}
> +
> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
> +				      struct bq27xxx_dm_reg *reg) {
> +	if (buf->class == reg->subclass_id
> +	 && buf->block == reg->offset / BQ27XXX_DM_SZ)
> +		return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
> +
> +	return NULL;
> +}
> +
> +enum bq27xxx_dm_reg_id {
> +	BQ27XXX_DM_DESIGN_CAPACITY = 0,
> +	BQ27XXX_DM_DESIGN_ENERGY,
> +	BQ27XXX_DM_TERMINATE_VOLTAGE,
> +};
> +
> +static const char* bq27xxx_dm_reg_name[] = {
> +	[BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
> +	[BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
> +	[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 },
> +};
> +
> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
> +	[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[] = { /* not tested */
> +//	[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 },
> +//};

I don't think this comment style is allowed.

> +
> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
> +	[BQ27421] = bq27421_dm_regs, /* and BQ27441 */
> +	[BQ27425] = bq27425_dm_regs,
> +//	[BQ27621] = bq27621_dm_regs,
> +};

I know it is not tested, but lets not comment it out, I'll do a round of
testing for this part when this series is ready.

> +
> +static u32 bq27xxx_unseal_keys[] = {
> +	[BQ27421] = 0x80008000, /* and BQ27441 */
> +	[BQ27425] = 0x04143672,
> +//	[BQ27621] = 0x80008000,
> +};
> +
> +
>  static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
>  {
>  	struct bq27xxx_device_info *di;
> @@ -496,6 +627,318 @@ static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,
>  	return di->bus.read(di, di->regs[reg_index], single);
>  }
>  
> +static int bq27xxx_battery_set_seal_state(struct bq27xxx_device_info *di,
> +					  bool state)
> +{
> +	int ret;
> +
> +	if (state) {
> +		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], BQ27XXX_SEALED, false);
> +		if (ret < 0)
> +			goto out;
> +	} else {
> +		u32 key = bq27xxx_unseal_keys[di->chip];
> +
> +		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], (u16)(key >> 16), false);
> +		if (ret < 0)
> +			goto out;
> +
> +		ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL], (u16)key, false);
> +		if (ret < 0)
> +			goto out;
> +	}
> +	return 0;
> +
> +out:
> +	dev_err(di->dev, "bus error on %s: %d\n", state ? "seal" : "unseal", ret);
> +	return ret;
> +}
> +
> +static u8 bq27xxx_battery_checksum(struct bq27xxx_dm_buf *buf)
> +{
> +	u16 sum = 0;
> +	int i;
> +
> +	for (i = 0; i < BQ27XXX_DM_SZ; i++)
> +		sum += buf->a[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;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CLASS], buf->class, true);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_BLOCK], buf->block, true);
> +	if (ret < 0)
> +		goto out;
> +
> +	BQ27XXX_MSLEEP(1);
> +
> +	ret = di->bus.read_bulk(di, di->regs[BQ27XXX_DM_DATA], buf->a, BQ27XXX_DM_SZ);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = di->bus.read(di, di->regs[BQ27XXX_DM_CKSUM], true);
> +	if (ret < 0)
> +		goto out;
> +
> +	if ((u8)ret != bq27xxx_battery_checksum(buf)) {
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	buf->full = true;
> +	buf->updt = false;
> +	return 0;
> +
> +out:
> +	dev_err(di->dev, "bus error reading chip memory: %d\n", ret);
> +	return ret;
> +}
> +
> +static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,
> +					    struct bq27xxx_dm_buf *buf,
> +					    enum bq27xxx_dm_reg_id reg_id,
> +					    unsigned int val)
> +{
> +	struct bq27xxx_dm_reg *reg = &bq27xxx_dm_regs[di->chip][reg_id];
> +	const char* str = bq27xxx_dm_reg_name[reg_id];
> +	u16 *prev = bq27xxx_dm_buf_ptr(buf, reg);
> +
> +	if (prev == NULL) {
> +		dev_warn(di->dev, "buffer does not match %s dm spec\n", str);
> +		return;
> +	}
> +
> +	if (reg->bytes != 2) {
> +		dev_warn(di->dev, "%s dm spec has unsupported byte size\n", str);
> +		return;
> +	}
> +
> +	if (!buf->full)
> +		return;
> +
> +	if (be16_to_cpup(prev) == val) {
> +		dev_info(di->dev, "%s has %u\n", str, val);
> +		return;
> +	}
> +
> +	dev_info(di->dev, "update %s to %u\n", str, val);
> +
> +	*prev = cpu_to_be16(val);
> +	buf->updt = true;
> +}
> +
> +static int bq27xxx_battery_set_cfgupdate(struct bq27xxx_device_info *di,
> +					 bool state)
> +{
> +	int ret, try=100;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_REG_CTRL],
> +			    state ? BQ27XXX_SET_CFGUPDATE : BQ27XXX_SOFT_RESET,
> +			    false);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (di->chip == BQ27425) /* chip fails to set/clear flag */
> +		return 0;
> +
> +	do {
> +		BQ27XXX_MSLEEP(5);
> +		ret = di->bus.read(di, di->regs[BQ27XXX_REG_FLAGS], false);
> +		if (ret < 0)
> +			goto out;
> +	} while (!(ret & BQ27XXX_FLAG_CFGUP) == state && --try);
> +
> +	if (100-try) /* remove after other cfgupdate parts are tested */
> +		dev_info(di->dev, "cfgupdate %d, retries %d\n", state, 100-try);
> +
> +	if (try)
> +		return 0;
> +
> +	dev_err(di->dev, "timed out waiting for cfgupdate flag %d\n", state);
> +	return -EINVAL;
> +
> +out:
> +	dev_err(di->dev, "bus error on %s: %d\n", state ? "set_cfgupdate" : "soft_reset", ret);
> +	return ret;
> +}
> +
> +static int bq27xxx_battery_write_dm_block(struct bq27xxx_device_info *di,
> +					  struct bq27xxx_dm_buf *buf)
> +{
> +	bool cfgup = di->chip == BQ27425 || di->chip == BQ27421; /* || BQ27441 || BQ27621 */
> +	int ret;
> +
> +	if (!buf->updt)
> +		return 0;
> +
> +	if (cfgup) {
> +		ret = bq27xxx_battery_set_cfgupdate(di, true);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CTRL], 0, true);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CLASS], buf->class, true);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_BLOCK], buf->block, true);
> +	if (ret < 0)
> +		goto out;
> +
> +	BQ27XXX_MSLEEP(1);
> +
> +	ret = di->bus.write_bulk(di, di->regs[BQ27XXX_DM_DATA], buf->a, BQ27XXX_DM_SZ);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = di->bus.write(di, di->regs[BQ27XXX_DM_CKSUM],
> +			    bq27xxx_battery_checksum(buf), true);
> +	if (ret < 0)
> +		goto out;
> +
> +	/* THE FOLLOWING SEQUENCE IS TOXIC. DO NOT USE!
> +	 * If the 'time' delay is insufficient, NVM corruption results on
> +	 * the '425 chip (and perhaps others), which could damage the chip.
> +	 * It was suggested in this TI tool:
> +	 *   http://git.ti.com/bms-linux/bqtool/blobs/master/gauge.c#line328
> +	 *
> +	 * 1. sleep 'time' after above write(BQ27XXX_DM_CKSUM, ...)
> +	 * 2. write(BQ27XXX_DM_BLOCK, buf->block)
> +	 * 3. sum = read(BQ27XXX_DM_CKSUM)
> +	 * 4. if (sum != bq27xxx_battery_checksum(buf))
> +	 *      error
> +	 */
> +
> +	if (cfgup) {
> +		BQ27XXX_MSLEEP(1);
> +		ret = bq27xxx_battery_set_cfgupdate(di, false);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	buf->updt = false;
> +	return 0;
> +
> +out:
> +	if (cfgup)
> +		bq27xxx_battery_set_cfgupdate(di, false);
> +
> +	dev_err(di->dev, "bus error writing chip memory: %d\n", ret);
> +	return ret;
> +}
> +
> +static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
> +				       struct power_supply_battery_info *info)
> +{
> +	struct bq27xxx_dm_buf bd = BQ27XXX_DM_BUF(di, BQ27XXX_DM_DESIGN_ENERGY);
> +	struct bq27xxx_dm_buf bt = BQ27XXX_DM_BUF(di, BQ27XXX_DM_TERMINATE_VOLTAGE);
> +
> +	if (info->charge_full_design_uah != -EINVAL
> +	 && info->energy_full_design_uwh != -EINVAL) {
> +		bq27xxx_battery_read_dm_block(di, &bd);
> +		/* assume design energy & capacity are in same block */
> +		bq27xxx_battery_update_dm_block(di, &bd,
> +					BQ27XXX_DM_DESIGN_CAPACITY,
> +					info->charge_full_design_uah / 1000);
> +		bq27xxx_battery_update_dm_block(di, &bd,
> +					BQ27XXX_DM_DESIGN_ENERGY,
> +					info->energy_full_design_uwh / 1000);
> +	}
> +
> +	if (info->voltage_min_design_uv != -EINVAL) {
> +		bool same = bd.class == bt.class && bd.block == bt.block;
> +		if (!same)
> +			bq27xxx_battery_read_dm_block(di, &bt);
> +		bq27xxx_battery_update_dm_block(di, same ? &bd : &bt,
> +					BQ27XXX_DM_TERMINATE_VOLTAGE,
> +					info->voltage_min_design_uv / 1000);
> +	}
> +
> +	bq27xxx_battery_write_dm_block(di, &bd);
> +	bq27xxx_battery_write_dm_block(di, &bt);
> +}
> +
> +void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
> +{
> +	struct power_supply_battery_info info = {};
> +	unsigned int min, max;
> +
> +	/* functions don't exist for writing data so abort */
> +	if (!di->bus.write || !di->bus.write_bulk)
> +		return;
> +
> +	/* no settings to be set for this chipset so abort */
> +	if (!bq27xxx_dm_regs[di->chip])
> +		return;
> +
> +	if (bq27xxx_battery_set_seal_state(di, false) < 0)
> +		return;
> +
> +	if (power_supply_get_battery_info(di->bat, &info) < 0)
> +		goto out;
> +
> +	if (info.energy_full_design_uwh != info.charge_full_design_uah) {
> +		if (info.energy_full_design_uwh == -EINVAL)
> +			dev_warn(di->dev,
> +				"missing battery:energy-full-design-microwatt-hours\n");
> +		else if (info.charge_full_design_uah == -EINVAL)
> +			dev_warn(di->dev,
> +				"missing battery:charge-full-design-microamp-hours\n");
> +	}
> +
> +	/* assume min == 0 */
> +	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_DESIGN_ENERGY].max;
> +	if (info.energy_full_design_uwh > max * 1000) {
> +		dev_err(di->dev,
> +		       "invalid battery:energy-full-design-microwatt-hours %d\n",
> +			info.energy_full_design_uwh);
> +		info.energy_full_design_uwh = -EINVAL;
> +	}
> +
> +	/* assume min == 0 */
> +	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_DESIGN_CAPACITY].max;
> +	if (info.charge_full_design_uah > max * 1000) {
> +		dev_err(di->dev,
> +		       "invalid battery:charge-full-design-microamp-hours %d\n",
> +			info.charge_full_design_uah);
> +		info.charge_full_design_uah = -EINVAL;
> +	}
> +
> +	min = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_TERMINATE_VOLTAGE].min;
> +	max = bq27xxx_dm_regs[di->chip][BQ27XXX_DM_TERMINATE_VOLTAGE].max;
> +	if ((info.voltage_min_design_uv < min * 1000
> +	  || info.voltage_min_design_uv > max * 1000)
> +	  && info.voltage_min_design_uv != -EINVAL) {
> +		dev_err(di->dev,
> +		       "invalid battery:voltage-min-design-microvolt %d\n",
> +			info.voltage_min_design_uv);
> +		info.voltage_min_design_uv = -EINVAL;
> +	}
> +
> +	if ((info.energy_full_design_uwh == -EINVAL
> +	  || info.charge_full_design_uah == -EINVAL)
> +	  && info.voltage_min_design_uv  == -EINVAL)
> +		goto out;
> +
> +	bq27xxx_battery_set_config(di, &info);
> +
> +out:
> +	bq27xxx_battery_set_seal_state(di, true);
> +}
> +
>  /*
>   * Return the battery State-of-Charge
>   * Or < 0 if something fails.
> @@ -1006,6 +1449,13 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>  	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
>  		ret = bq27xxx_simple_value(di->charge_design_full, val);
>  		break;
> +	/*
> +	 * TODO: Implement these to make registers set from
> +	 * power_supply_battery_info visible in sysfs.
> +	 */
> +	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
> +	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +		return -EINVAL;
>  	case POWER_SUPPLY_PROP_CYCLE_COUNT:
>  		ret = bq27xxx_simple_value(di->cache.cycle_count, val);
>  		break;
> @@ -1039,7 +1489,10 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
>  int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
>  {
>  	struct power_supply_desc *psy_desc;
> -	struct power_supply_config psy_cfg = { .drv_data = di, };
> +	struct power_supply_config psy_cfg = {
> +		.of_node = di->dev->of_node,
> +		.drv_data = di,
> +	};
>  
>  	INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
>  	mutex_init(&di->lock);
> @@ -1064,6 +1517,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
>  
>  	dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
>  
> +	bq27xxx_battery_settings(di);
>  	bq27xxx_battery_update(di);
>  
>  	mutex_lock(&bq27xxx_list_lock);
> 

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

* Re: [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory
  2017-02-27  7:11 ` [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory Liam Breck
@ 2017-02-27 18:07   ` Andrew F. Davis
  0 siblings, 0 replies; 37+ messages in thread
From: Andrew F. Davis @ 2017-02-27 18:07 UTC (permalink / raw)
  To: Liam Breck, Sebastian Reichel; +Cc: linux-pm, Matt Ranostay, Liam Breck

On 02/27/2017 01:11 AM, Liam Breck wrote:
> From: Liam Breck <kernel@networkimprov.net>
> 
> Enable listing of chip RAM and/or NVM at startup, for debugging use.
> Intially supports BQ27425. Support for other chips may be added.
> 
> Signed-off-by: Liam Breck <kernel@networkimprov.net>
> ---
>  drivers/power/supply/bq27xxx_battery.c | 70 ++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 41d4ce7..8ba0568 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c
> @@ -703,6 +703,74 @@ static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,
>  	return ret;
>  }
>  
> +/* Translate F4 floating point values to/from hexadecimal:
> + *   perl -e 'printf("%08x\n", unpack("I", pack("f", 3.93e-4   )))' # 39ce0b91
> + *   perl -e 'printf("%f\n"  , unpack("f", pack("I", 0x39ce0b91)))' # 0.000393
> + */
> +
> +#define BQ27XXX_DM_INFO(f,o,v) dev_info(di->dev, "offset %d, " f "\n", o, v)
> +
> +static void bq27xxx_battery_print_dm_blocks(struct bq27xxx_device_info *di) {
> +	enum { H1, H2, H4, I1, I2, U1, F4 };
> +
> +	struct dm_reg { int offset, type; }
> +		/* each array row describes one data block */
> +		c425_s82[][10] = {
> +			{ { 2,H1},{ 3,I2},{ 5,H2},{12,I2},{14,I2},{18,I2},{22,I2},{29,U1},{30,I2},{99,0} },
> +			{ {32,I2},{34,I2},{36,I2},{38,U1},{39,U1},{40,F4},{99,0} },
> +		},
> +		c425_s104[][10] = {
> +			{ { 0,I2},{ 2,I1},{ 3,I1},{ 4,I1},{99,0} },
> +		},
> +		c425_s105[][10] = {
> +			{ { 0,F4},{ 4,I2},{99,0} },
> +		};
> +		/* add more subclass maps here */
> +
> +	struct dm_class { int id, blocks; struct dm_reg (*reg)[10]; }
> +		c425[] = {
> +			{ .id =  82, .blocks = 2, .reg = c425_s82  },
> +			{ .id = 104, .blocks = 1, .reg = c425_s104 },
> +			{ .id = 105, .blocks = 1, .reg = c425_s105 },
> +			{ .reg = NULL }
> +		};
> +		/* add more chip maps here */
> +
> +	struct dm_class *chip = c425; /* set to your chip */
> +
> +	struct bq27xxx_dm_buf buf = { };
> +	int c, b, r;
> +
> +	for (c=0; chip[c].reg != NULL; ++c) {
> +		buf.class = chip[c].id;
> +		dev_info(di->dev, "subclass %d registers...\n", chip[c].id);
> +
> +		for (b=0; b < chip[c].blocks; ++b) {
> +			buf.block = b;
> +			if (bq27xxx_battery_read_dm_block(di, &buf) < 0)
> +				continue;
> +
> +			for (r=0; chip[c].reg[b][r].offset != 99; ++r) {
> +				int o = chip[c].reg[b][r].offset;
> +				u8* p = &buf.a[o % BQ27XXX_DM_SZ];
> +
> +				switch (chip[c].reg[b][r].type) {
> +				case H1: BQ27XXX_DM_INFO("%02x", o,   *p); break;
> +				case I1: BQ27XXX_DM_INFO("%d", o, (s8)*p); break;
> +				case U1: BQ27XXX_DM_INFO("%u", o,     *p); break;
> +				case H2: BQ27XXX_DM_INFO("%04x", o,
> +						   be16_to_cpup((u16*)p)); break;
> +				case I2: BQ27XXX_DM_INFO("%d", o,
> +					      (s16)be16_to_cpup((u16*)p)); break;
> +				case H4:
> +				case F4: BQ27XXX_DM_INFO("%08x", o,
> +						   be32_to_cpup((u32*)p)); break;
> +				}
> +			}
> +		}
> +	}
> +}
> +
>  static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,
>  					    struct bq27xxx_dm_buf *buf,
>  					    enum bq27xxx_dm_reg_id reg_id,
> @@ -936,6 +1004,8 @@ void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
>  	bq27xxx_battery_set_config(di, &info);
>  
>  out:
> +	/* bq27xxx_battery_print_dm_blocks(di); uncomment for debugging */
> +	(void)bq27xxx_battery_print_dm_blocks; /* prevent compiler warning */

__maybe_unused

>  	bq27xxx_battery_set_seal_state(di, true);
>  }
>  
> 

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 18:06   ` Andrew F. Davis
@ 2017-02-27 20:05     ` Liam Breck
  2017-02-27 21:21       ` Andrew F. Davis
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27 20:05 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
> On 02/27/2017 01:11 AM, Liam Breck wrote:
>> From: Liam Breck <kernel@networkimprov.net>
>>
>> Previously there was no way to configure chip registers in the event that the
>> defaults didn't match the battery in question.
>>
>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>> and writes battery data to chip RAM or non-volatile memory.
>>
>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>> ---
>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>> index 7475a5f..41d4ce7 100644
>> --- a/drivers/power/supply/bq27xxx_battery.c
>> +++ b/drivers/power/supply/bq27xxx_battery.c
>> @@ -51,7 +51,7 @@
>>
>>  #include <linux/power/bq27xxx_battery.h>
>>
>> -#define DRIVER_VERSION               "1.2.0"
>> +#define DRIVER_VERSION               "1.3.0"
>>
>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>
>> @@ -59,6 +59,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(5)
>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>> @@ -72,6 +73,11 @@
>>  #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_RS                   (20) /* Resistor sense mOhm */
>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>       BQ27XXX_REG_AP,         /* Average Power */
>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>
> /* Block Data Control */
>
>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>
> /* Data Class */

I used the terms from the docs, so a search will find meaningful results.

>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>       BQ27XXX_REG_MAX,        /* sentinel */
>>  };
>>
>> @@ -125,6 +136,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,
>> @@ -144,6 +160,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,
>>       },
>>       [BQ27500] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x2c,
>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27510] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x20,
>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27530] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x2c,
>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>               [BQ27XXX_REG_AP] = 0x24,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27541] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x2c,
>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>               [BQ27XXX_REG_AP] = 0x24,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27545] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x2c,
>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>               [BQ27XXX_REG_AP] = 0x24,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27421] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x1c,
>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>               [BQ27XXX_REG_AP] = 0x18,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>       },
>>       [BQ27425] = {
>>               [BQ27XXX_REG_CTRL] = 0x00,
>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>               [BQ27XXX_REG_SOC] = 0x1c,
>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>               [BQ27XXX_REG_AP] = 0x18,
>> +             [BQ27XXX_DM_CTRL] = 0x61,
>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>> +             [BQ27XXX_DM_DATA] = 0x40,
>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>
> That wasn't so painful was it :)

It added 11% to the patch :-/

>>       },
>>  };
>>
>> @@ -452,6 +508,81 @@ static struct {
>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>  static LIST_HEAD(bq27xxx_battery_devices);
>>
>> +#define BQ27XXX_DM_SZ                        32
>> +
>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>> +
>> +struct bq27xxx_dm_reg {
>> +     u8 subclass_id;
>> +     u8 offset;
>> +     u8 bytes;
>> +     u16 min, max;
>> +};
>> +
>> +struct bq27xxx_dm_buf {
>> +     u8 class;
>> +     u8 block;
>> +     u8 a[BQ27XXX_DM_SZ];
>> +     bool full, updt;
>> +};
>> +
>> +#define BQ27XXX_DM_BUF(di, i) { \
>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>> +}
>> +
>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>> +                                   struct bq27xxx_dm_reg *reg) {
>> +     if (buf->class == reg->subclass_id
>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>> +
>> +     return NULL;
>> +}
>> +
>> +enum bq27xxx_dm_reg_id {
>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>> +     BQ27XXX_DM_DESIGN_ENERGY,
>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>> +};
>> +
>> +static const char* bq27xxx_dm_reg_name[] = {
>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>> +     [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 },
>> +};
>> +
>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>> +     [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[] = { /* not tested */
>> +//   [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 },
>> +//};
>
> I don't think this comment style is allowed.

This is a to-do item.

>> +
>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>> +     [BQ27425] = bq27425_dm_regs,
>> +//   [BQ27621] = bq27621_dm_regs,
>> +};
>
> I know it is not tested, but lets not comment it out, I'll do a round of
> testing for this part when this series is ready.

ID for 621 is not yet defined. We need an efficient way to add IDs.
Perhaps via chip-id and group-id. Most current ID refs would be to
group-id. I'd like to defer that, so we should only add inputs for the
single-chip groups in this patchset: 500, 545, 425.

We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
docs. It's not clear whether documented data-memory ops change OTP.
Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
the above have cfgupdate mode, which the rest of the family lacks.

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 20:05     ` Liam Breck
@ 2017-02-27 21:21       ` Andrew F. Davis
  2017-02-27 21:35         ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-02-27 21:21 UTC (permalink / raw)
  To: Liam Breck; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On 02/27/2017 02:05 PM, Liam Breck wrote:
> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>> From: Liam Breck <kernel@networkimprov.net>
>>>
>>> Previously there was no way to configure chip registers in the event that the
>>> defaults didn't match the battery in question.
>>>
>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>> and writes battery data to chip RAM or non-volatile memory.
>>>
>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>> ---
>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>> index 7475a5f..41d4ce7 100644
>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>> @@ -51,7 +51,7 @@
>>>
>>>  #include <linux/power/bq27xxx_battery.h>
>>>
>>> -#define DRIVER_VERSION               "1.2.0"
>>> +#define DRIVER_VERSION               "1.3.0"
>>>
>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>
>>> @@ -59,6 +59,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(5)
>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>> @@ -72,6 +73,11 @@
>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>       BQ27XXX_REG_AP,         /* Average Power */
>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>
>> /* Block Data Control */
>>
>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>
>> /* Data Class */
> 
> I used the terms from the docs, so a search will find meaningful results.
> 
>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>  };
>>>
>>> @@ -125,6 +136,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,
>>> @@ -144,6 +160,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,
>>>       },
>>>       [BQ27500] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27510] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27530] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>               [BQ27XXX_REG_AP] = 0x24,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27541] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>               [BQ27XXX_REG_AP] = 0x24,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27545] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>               [BQ27XXX_REG_AP] = 0x24,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27421] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>               [BQ27XXX_REG_AP] = 0x18,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>       },
>>>       [BQ27425] = {
>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>               [BQ27XXX_REG_AP] = 0x18,
>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>
>> That wasn't so painful was it :)
> 
> It added 11% to the patch :-/
> 
>>>       },
>>>  };
>>>
>>> @@ -452,6 +508,81 @@ static struct {
>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>
>>> +#define BQ27XXX_DM_SZ                        32
>>> +
>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>> +
>>> +struct bq27xxx_dm_reg {
>>> +     u8 subclass_id;
>>> +     u8 offset;
>>> +     u8 bytes;
>>> +     u16 min, max;
>>> +};
>>> +
>>> +struct bq27xxx_dm_buf {
>>> +     u8 class;
>>> +     u8 block;
>>> +     u8 a[BQ27XXX_DM_SZ];
>>> +     bool full, updt;
>>> +};
>>> +
>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>> +}
>>> +
>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>> +                                   struct bq27xxx_dm_reg *reg) {
>>> +     if (buf->class == reg->subclass_id
>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>> +
>>> +     return NULL;
>>> +}
>>> +
>>> +enum bq27xxx_dm_reg_id {
>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>> +};
>>> +
>>> +static const char* bq27xxx_dm_reg_name[] = {
>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>> +     [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 },
>>> +};
>>> +
>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>> +     [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[] = { /* not tested */
>>> +//   [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 },
>>> +//};
>>
>> I don't think this comment style is allowed.
> 
> This is a to-do item.
> 
>>> +
>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>> +     [BQ27425] = bq27425_dm_regs,
>>> +//   [BQ27621] = bq27621_dm_regs,
>>> +};
>>
>> I know it is not tested, but lets not comment it out, I'll do a round of
>> testing for this part when this series is ready.
> 
> ID for 621 is not yet defined. We need an efficient way to add IDs.
> Perhaps via chip-id and group-id. Most current ID refs would be to
> group-id. I'd like to defer that, so we should only add inputs for the
> single-chip groups in this patchset: 500, 545, 425.
> 
> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
> docs. It's not clear whether documented data-memory ops change OTP.
> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
> the above have cfgupdate mode, which the rest of the family lacks.
> 

This would be a good question for e2e[0].

[0] http://e2e.ti.com/support/power_management/battery_management/f/180

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 21:21       ` Andrew F. Davis
@ 2017-02-27 21:35         ` Liam Breck
  2017-02-27 21:47           ` Andrew F. Davis
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27 21:35 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Feb 27, 2017 at 1:21 PM, Andrew F. Davis <afd@ti.com> wrote:
> On 02/27/2017 02:05 PM, Liam Breck wrote:
>> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>
>>>> Previously there was no way to configure chip registers in the event that the
>>>> defaults didn't match the battery in question.
>>>>
>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>
>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>> ---
>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>> index 7475a5f..41d4ce7 100644
>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>> @@ -51,7 +51,7 @@
>>>>
>>>>  #include <linux/power/bq27xxx_battery.h>
>>>>
>>>> -#define DRIVER_VERSION               "1.2.0"
>>>> +#define DRIVER_VERSION               "1.3.0"
>>>>
>>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>>
>>>> @@ -59,6 +59,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(5)
>>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>>> @@ -72,6 +73,11 @@
>>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>>       BQ27XXX_REG_AP,         /* Average Power */
>>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>>
>>> /* Block Data Control */
>>>
>>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>>
>>> /* Data Class */
>>
>> I used the terms from the docs, so a search will find meaningful results.
>>
>>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>>  };
>>>>
>>>> @@ -125,6 +136,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,
>>>> @@ -144,6 +160,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,
>>>>       },
>>>>       [BQ27500] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27510] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27530] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27541] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27545] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27421] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>       },
>>>>       [BQ27425] = {
>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>
>>> That wasn't so painful was it :)
>>
>> It added 11% to the patch :-/
>>
>>>>       },
>>>>  };
>>>>
>>>> @@ -452,6 +508,81 @@ static struct {
>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>
>>>> +#define BQ27XXX_DM_SZ                        32
>>>> +
>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>> +
>>>> +struct bq27xxx_dm_reg {
>>>> +     u8 subclass_id;
>>>> +     u8 offset;
>>>> +     u8 bytes;
>>>> +     u16 min, max;
>>>> +};
>>>> +
>>>> +struct bq27xxx_dm_buf {
>>>> +     u8 class;
>>>> +     u8 block;
>>>> +     u8 a[BQ27XXX_DM_SZ];
>>>> +     bool full, updt;
>>>> +};
>>>> +
>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>> +}
>>>> +
>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>> +                                   struct bq27xxx_dm_reg *reg) {
>>>> +     if (buf->class == reg->subclass_id
>>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>> +
>>>> +     return NULL;
>>>> +}
>>>> +
>>>> +enum bq27xxx_dm_reg_id {
>>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>> +};
>>>> +
>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>> +     [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 },
>>>> +};
>>>> +
>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>> +     [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[] = { /* not tested */
>>>> +//   [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 },
>>>> +//};
>>>
>>> I don't think this comment style is allowed.
>>
>> This is a to-do item.
>>
>>>> +
>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>> +     [BQ27425] = bq27425_dm_regs,
>>>> +//   [BQ27621] = bq27621_dm_regs,
>>>> +};
>>>
>>> I know it is not tested, but lets not comment it out, I'll do a round of
>>> testing for this part when this series is ready.
>>
>> ID for 621 is not yet defined. We need an efficient way to add IDs.
>> Perhaps via chip-id and group-id. Most current ID refs would be to
>> group-id. I'd like to defer that, so we should only add inputs for the
>> single-chip groups in this patchset: 500, 545, 425.
>>
>> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
>> docs. It's not clear whether documented data-memory ops change OTP.
>> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
>> the above have cfgupdate mode, which the rest of the family lacks.
>>
>
> This would be a good question for e2e[0].
>
> [0] http://e2e.ti.com/support/power_management/battery_management/f/180

Can I ask you to handle discussions with TI folks?

Thanks :-)

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 21:35         ` Liam Breck
@ 2017-02-27 21:47           ` Andrew F. Davis
  2017-02-27 22:14             ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-02-27 21:47 UTC (permalink / raw)
  To: Liam Breck; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On 02/27/2017 03:35 PM, Liam Breck wrote:
> On Mon, Feb 27, 2017 at 1:21 PM, Andrew F. Davis <afd@ti.com> wrote:
>> On 02/27/2017 02:05 PM, Liam Breck wrote:
>>> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>>>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>
>>>>> Previously there was no way to configure chip registers in the event that the
>>>>> defaults didn't match the battery in question.
>>>>>
>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>
>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>> ---
>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>> index 7475a5f..41d4ce7 100644
>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>> @@ -51,7 +51,7 @@
>>>>>
>>>>>  #include <linux/power/bq27xxx_battery.h>
>>>>>
>>>>> -#define DRIVER_VERSION               "1.2.0"
>>>>> +#define DRIVER_VERSION               "1.3.0"
>>>>>
>>>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>>>
>>>>> @@ -59,6 +59,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(5)
>>>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>>>> @@ -72,6 +73,11 @@
>>>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>>>       BQ27XXX_REG_AP,         /* Average Power */
>>>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>>>
>>>> /* Block Data Control */
>>>>
>>>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>>>
>>>> /* Data Class */
>>>
>>> I used the terms from the docs, so a search will find meaningful results.
>>>
>>>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>>>  };
>>>>>
>>>>> @@ -125,6 +136,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,
>>>>> @@ -144,6 +160,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,
>>>>>       },
>>>>>       [BQ27500] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27510] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27530] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27541] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27545] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27421] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>       },
>>>>>       [BQ27425] = {
>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>
>>>> That wasn't so painful was it :)
>>>
>>> It added 11% to the patch :-/
>>>
>>>>>       },
>>>>>  };
>>>>>
>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>
>>>>> +#define BQ27XXX_DM_SZ                        32
>>>>> +
>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>> +
>>>>> +struct bq27xxx_dm_reg {
>>>>> +     u8 subclass_id;
>>>>> +     u8 offset;
>>>>> +     u8 bytes;
>>>>> +     u16 min, max;
>>>>> +};
>>>>> +
>>>>> +struct bq27xxx_dm_buf {
>>>>> +     u8 class;
>>>>> +     u8 block;
>>>>> +     u8 a[BQ27XXX_DM_SZ];
>>>>> +     bool full, updt;
>>>>> +};
>>>>> +
>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>> +}
>>>>> +
>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>> +                                   struct bq27xxx_dm_reg *reg) {
>>>>> +     if (buf->class == reg->subclass_id
>>>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>> +
>>>>> +     return NULL;
>>>>> +}
>>>>> +
>>>>> +enum bq27xxx_dm_reg_id {
>>>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>> +};
>>>>> +
>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>> +     [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 },
>>>>> +};
>>>>> +
>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>> +     [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[] = { /* not tested */
>>>>> +//   [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 },
>>>>> +//};
>>>>
>>>> I don't think this comment style is allowed.
>>>
>>> This is a to-do item.
>>>
>>>>> +
>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>> +     [BQ27425] = bq27425_dm_regs,
>>>>> +//   [BQ27621] = bq27621_dm_regs,
>>>>> +};
>>>>
>>>> I know it is not tested, but lets not comment it out, I'll do a round of
>>>> testing for this part when this series is ready.
>>>
>>> ID for 621 is not yet defined. We need an efficient way to add IDs.
>>> Perhaps via chip-id and group-id. Most current ID refs would be to
>>> group-id. I'd like to defer that, so we should only add inputs for the
>>> single-chip groups in this patchset: 500, 545, 425.
>>>
>>> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
>>> docs. It's not clear whether documented data-memory ops change OTP.
>>> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
>>> the above have cfgupdate mode, which the rest of the family lacks.
>>>
>>
>> This would be a good question for e2e[0].
>>
>> [0] http://e2e.ti.com/support/power_management/battery_management/f/180
> 
> Can I ask you to handle discussions with TI folks?
> 

You can ask, doesn't mean I will :) but really I don't have any special
means of getting a hold of the gauge team that you don't have (except
maybe walking over to their cubes and bugging them).

We try to ask even internal inter-team questions on e2e, you can see
questions asked by TI employees to other employees on that site, the
idea is that if we have a problem, someday customers may have the same
problem, so it's best not no keep these answers buried in some internal
email chain. So the most I would do is post the same question to them on
e2e, you can avoid me being a middle-man by asking them directly.

Thanks,
Andrew

> Thanks :-)
> 

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 21:47           ` Andrew F. Davis
@ 2017-02-27 22:14             ` Liam Breck
  2017-02-27 22:37               ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27 22:14 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Feb 27, 2017 at 1:47 PM, Andrew F. Davis <afd@ti.com> wrote:
> On 02/27/2017 03:35 PM, Liam Breck wrote:
>> On Mon, Feb 27, 2017 at 1:21 PM, Andrew F. Davis <afd@ti.com> wrote:
>>> On 02/27/2017 02:05 PM, Liam Breck wrote:
>>>> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>>>>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>
>>>>>> Previously there was no way to configure chip registers in the event that the
>>>>>> defaults didn't match the battery in question.
>>>>>>
>>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>>
>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>> ---
>>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>>> index 7475a5f..41d4ce7 100644
>>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>>> @@ -51,7 +51,7 @@
>>>>>>
>>>>>>  #include <linux/power/bq27xxx_battery.h>
>>>>>>
>>>>>> -#define DRIVER_VERSION               "1.2.0"
>>>>>> +#define DRIVER_VERSION               "1.3.0"
>>>>>>
>>>>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>>>>
>>>>>> @@ -59,6 +59,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(5)
>>>>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>>>>> @@ -72,6 +73,11 @@
>>>>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>>>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>>>>       BQ27XXX_REG_AP,         /* Average Power */
>>>>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>>>>
>>>>> /* Block Data Control */
>>>>>
>>>>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>>>>
>>>>> /* Data Class */
>>>>
>>>> I used the terms from the docs, so a search will find meaningful results.
>>>>
>>>>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>>>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>>>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>>>>  };
>>>>>>
>>>>>> @@ -125,6 +136,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,
>>>>>> @@ -144,6 +160,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,
>>>>>>       },
>>>>>>       [BQ27500] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27510] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27530] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27541] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27545] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27421] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>       },
>>>>>>       [BQ27425] = {
>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>
>>>>> That wasn't so painful was it :)
>>>>
>>>> It added 11% to the patch :-/
>>>>
>>>>>>       },
>>>>>>  };
>>>>>>
>>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>>
>>>>>> +#define BQ27XXX_DM_SZ                        32
>>>>>> +
>>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>>> +
>>>>>> +struct bq27xxx_dm_reg {
>>>>>> +     u8 subclass_id;
>>>>>> +     u8 offset;
>>>>>> +     u8 bytes;
>>>>>> +     u16 min, max;
>>>>>> +};
>>>>>> +
>>>>>> +struct bq27xxx_dm_buf {
>>>>>> +     u8 class;
>>>>>> +     u8 block;
>>>>>> +     u8 a[BQ27XXX_DM_SZ];
>>>>>> +     bool full, updt;
>>>>>> +};
>>>>>> +
>>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>>> +}
>>>>>> +
>>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>>> +                                   struct bq27xxx_dm_reg *reg) {
>>>>>> +     if (buf->class == reg->subclass_id
>>>>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>>> +
>>>>>> +     return NULL;
>>>>>> +}
>>>>>> +
>>>>>> +enum bq27xxx_dm_reg_id {
>>>>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>>>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>>> +};
>>>>>> +
>>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>>> +     [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 },
>>>>>> +};
>>>>>> +
>>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>>> +     [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[] = { /* not tested */
>>>>>> +//   [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 },
>>>>>> +//};
>>>>>
>>>>> I don't think this comment style is allowed.
>>>>
>>>> This is a to-do item.
>>>>
>>>>>> +
>>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>>> +     [BQ27425] = bq27425_dm_regs,
>>>>>> +//   [BQ27621] = bq27621_dm_regs,
>>>>>> +};
>>>>>
>>>>> I know it is not tested, but lets not comment it out, I'll do a round of
>>>>> testing for this part when this series is ready.
>>>>
>>>> ID for 621 is not yet defined. We need an efficient way to add IDs.
>>>> Perhaps via chip-id and group-id. Most current ID refs would be to
>>>> group-id. I'd like to defer that, so we should only add inputs for the
>>>> single-chip groups in this patchset: 500, 545, 425.
>>>>
>>>> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
>>>> docs. It's not clear whether documented data-memory ops change OTP.
>>>> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
>>>> the above have cfgupdate mode, which the rest of the family lacks.
>>>>
>>>
>>> This would be a good question for e2e[0].
>>>
>>> [0] http://e2e.ti.com/support/power_management/battery_management/f/180
>>
>> Can I ask you to handle discussions with TI folks?
>>
>
> You can ask, doesn't mean I will :) but really I don't have any special
> means of getting a hold of the gauge team that you don't have (except
> maybe walking over to their cubes and bugging them).
>
> We try to ask even internal inter-team questions on e2e, you can see
> questions asked by TI employees to other employees on that site, the
> idea is that if we have a problem, someday customers may have the same
> problem, so it's best not no keep these answers buried in some internal
> email chain. So the most I would do is post the same question to them on
> e2e, you can avoid me being a middle-man by asking them directly.

I understand; I'm just trying to minimize my todo list for this
patchset. We can put off the OTP issue, as this patchset won't support
those parts, since that needs the chip-id/group-id fix I mentioned.

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 22:14             ` Liam Breck
@ 2017-02-27 22:37               ` Liam Breck
  2017-03-01 23:09                 ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-02-27 22:37 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Feb 27, 2017 at 2:14 PM, Liam Breck <liam@networkimprov.net> wrote:
> On Mon, Feb 27, 2017 at 1:47 PM, Andrew F. Davis <afd@ti.com> wrote:
>> On 02/27/2017 03:35 PM, Liam Breck wrote:
>>> On Mon, Feb 27, 2017 at 1:21 PM, Andrew F. Davis <afd@ti.com> wrote:
>>>> On 02/27/2017 02:05 PM, Liam Breck wrote:
>>>>> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>>>>>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>>
>>>>>>> Previously there was no way to configure chip registers in the event that the
>>>>>>> defaults didn't match the battery in question.
>>>>>>>
>>>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>>>
>>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>>> ---
>>>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>>>> index 7475a5f..41d4ce7 100644
>>>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>>>> @@ -51,7 +51,7 @@
>>>>>>>
>>>>>>>  #include <linux/power/bq27xxx_battery.h>
>>>>>>>
>>>>>>> -#define DRIVER_VERSION               "1.2.0"
>>>>>>> +#define DRIVER_VERSION               "1.3.0"
>>>>>>>
>>>>>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>>>>>
>>>>>>> @@ -59,6 +59,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(5)
>>>>>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>>>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>>>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>>>>>> @@ -72,6 +73,11 @@
>>>>>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>>>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>>>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>>>>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>>>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>>>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>>>>>       BQ27XXX_REG_AP,         /* Average Power */
>>>>>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>>>>>
>>>>>> /* Block Data Control */
>>>>>>
>>>>>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>>>>>
>>>>>> /* Data Class */
>>>>>
>>>>> I used the terms from the docs, so a search will find meaningful results.
>>>>>
>>>>>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>>>>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>>>>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>>>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>>>>>  };
>>>>>>>
>>>>>>> @@ -125,6 +136,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,
>>>>>>> @@ -144,6 +160,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,
>>>>>>>       },
>>>>>>>       [BQ27500] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27510] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>>>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27530] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27541] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27545] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27421] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>       },
>>>>>>>       [BQ27425] = {
>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>
>>>>>> That wasn't so painful was it :)
>>>>>
>>>>> It added 11% to the patch :-/
>>>>>
>>>>>>>       },
>>>>>>>  };
>>>>>>>
>>>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>>>
>>>>>>> +#define BQ27XXX_DM_SZ                        32
>>>>>>> +
>>>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>>>> +
>>>>>>> +struct bq27xxx_dm_reg {
>>>>>>> +     u8 subclass_id;
>>>>>>> +     u8 offset;
>>>>>>> +     u8 bytes;
>>>>>>> +     u16 min, max;
>>>>>>> +};
>>>>>>> +
>>>>>>> +struct bq27xxx_dm_buf {
>>>>>>> +     u8 class;
>>>>>>> +     u8 block;
>>>>>>> +     u8 a[BQ27XXX_DM_SZ];
>>>>>>> +     bool full, updt;
>>>>>>> +};
>>>>>>> +
>>>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>>>> +}
>>>>>>> +
>>>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>>>> +                                   struct bq27xxx_dm_reg *reg) {
>>>>>>> +     if (buf->class == reg->subclass_id
>>>>>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>>>> +
>>>>>>> +     return NULL;
>>>>>>> +}
>>>>>>> +
>>>>>>> +enum bq27xxx_dm_reg_id {
>>>>>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>>>>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>>>> +};
>>>>>>> +
>>>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>>>> +     [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 },
>>>>>>> +};
>>>>>>> +
>>>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>>>> +     [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[] = { /* not tested */
>>>>>>> +//   [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 },
>>>>>>> +//};
>>>>>>
>>>>>> I don't think this comment style is allowed.
>>>>>
>>>>> This is a to-do item.
>>>>>
>>>>>>> +
>>>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>>>> +     [BQ27425] = bq27425_dm_regs,
>>>>>>> +//   [BQ27621] = bq27621_dm_regs,
>>>>>>> +};
>>>>>>
>>>>>> I know it is not tested, but lets not comment it out, I'll do a round of
>>>>>> testing for this part when this series is ready.
>>>>>
>>>>> ID for 621 is not yet defined. We need an efficient way to add IDs.
>>>>> Perhaps via chip-id and group-id. Most current ID refs would be to
>>>>> group-id. I'd like to defer that, so we should only add inputs for the
>>>>> single-chip groups in this patchset: 500, 545, 425.
>>>>>
>>>>> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
>>>>> docs. It's not clear whether documented data-memory ops change OTP.
>>>>> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
>>>>> the above have cfgupdate mode, which the rest of the family lacks.
>>>>>
>>>>
>>>> This would be a good question for e2e[0].
>>>>
>>>> [0] http://e2e.ti.com/support/power_management/battery_management/f/180
>>>
>>> Can I ask you to handle discussions with TI folks?
>>>
>>
>> You can ask, doesn't mean I will :) but really I don't have any special
>> means of getting a hold of the gauge team that you don't have (except
>> maybe walking over to their cubes and bugging them).
>>
>> We try to ask even internal inter-team questions on e2e, you can see
>> questions asked by TI employees to other employees on that site, the
>> idea is that if we have a problem, someday customers may have the same
>> problem, so it's best not no keep these answers buried in some internal
>> email chain. So the most I would do is post the same question to them on
>> e2e, you can avoid me being a middle-man by asking them directly.
>
> I understand; I'm just trying to minimize my todo list for this
> patchset. We can put off the OTP issue, as this patchset won't support
> those parts, since that needs the chip-id/group-id fix I mentioned.

Here for use now or later is the Q I would ask:

The following parts provide set_cfgupdate & soft_reset commands:
BQ27... 421, 425, 441, 621

Docs for 421 & 441 mention OTP memory
Docs for 621 do not mention OTP
Docs for 425 mention rewritable NVM

What is in OTP on 421 & 441?
Is anything in OTP on 621?
Is anything in OTP on 425?

Will documented data-memory ops, e.g. BlockData(), change OTP?
Is OTP only changed in config-update mode?

Context: we are adding DM update to the BQ27xxx linux driver, and must
avoid setting OTP memory.

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27 22:37               ` Liam Breck
@ 2017-03-01 23:09                 ` Liam Breck
  0 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-03-01 23:09 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Feb 27, 2017 at 2:37 PM, Liam Breck <liam@networkimprov.net> wrote:
> On Mon, Feb 27, 2017 at 2:14 PM, Liam Breck <liam@networkimprov.net> wrote:
>> On Mon, Feb 27, 2017 at 1:47 PM, Andrew F. Davis <afd@ti.com> wrote:
>>> On 02/27/2017 03:35 PM, Liam Breck wrote:
>>>> On Mon, Feb 27, 2017 at 1:21 PM, Andrew F. Davis <afd@ti.com> wrote:
>>>>> On 02/27/2017 02:05 PM, Liam Breck wrote:
>>>>>> On Mon, Feb 27, 2017 at 10:06 AM, Andrew F. Davis <afd@ti.com> wrote:
>>>>>>> On 02/27/2017 01:11 AM, Liam Breck wrote:
>>>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>>>
>>>>>>>> Previously there was no way to configure chip registers in the event that the
>>>>>>>> defaults didn't match the battery in question.
>>>>>>>>
>>>>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>>>>
>>>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>>>> ---
>>>>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>>>>> index 7475a5f..41d4ce7 100644
>>>>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>>>>> @@ -51,7 +51,7 @@
>>>>>>>>
>>>>>>>>  #include <linux/power/bq27xxx_battery.h>
>>>>>>>>
>>>>>>>> -#define DRIVER_VERSION               "1.2.0"
>>>>>>>> +#define DRIVER_VERSION               "1.3.0"
>>>>>>>>
>>>>>>>>  #define BQ27XXX_MANUFACTURER "Texas Instruments"
>>>>>>>>
>>>>>>>> @@ -59,6 +59,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(5)
>>>>>>>>  #define BQ27XXX_FLAG_FC              BIT(9)
>>>>>>>>  #define BQ27XXX_FLAG_OTD     BIT(14)
>>>>>>>>  #define BQ27XXX_FLAG_OTC     BIT(15)
>>>>>>>> @@ -72,6 +73,11 @@
>>>>>>>>  #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_RS                   (20) /* Resistor sense mOhm */
>>>>>>>>  #define BQ27XXX_POWER_CONSTANT               (29200) /* 29.2 µV^2 * 1000 */
>>>>>>>>  #define BQ27XXX_CURRENT_CONSTANT     (3570) /* 3.57 µV * 1000 */
>>>>>>>> @@ -102,6 +108,11 @@ enum bq27xxx_reg_index {
>>>>>>>>       BQ27XXX_REG_SOC,        /* State-of-Charge */
>>>>>>>>       BQ27XXX_REG_DCAP,       /* Design Capacity */
>>>>>>>>       BQ27XXX_REG_AP,         /* Average Power */
>>>>>>>> +     BQ27XXX_DM_CTRL,        /* BlockDataControl() */
>>>>>>>
>>>>>>> /* Block Data Control */
>>>>>>>
>>>>>>>> +     BQ27XXX_DM_CLASS,       /* DataClass() */
>>>>>>>
>>>>>>> /* Data Class */
>>>>>>
>>>>>> I used the terms from the docs, so a search will find meaningful results.
>>>>>>
>>>>>>>> +     BQ27XXX_DM_BLOCK,       /* DataBlock() */
>>>>>>>> +     BQ27XXX_DM_DATA,        /* BlockData() */
>>>>>>>> +     BQ27XXX_DM_CKSUM,       /* BlockDataChecksum() */
>>>>>>>>       BQ27XXX_REG_MAX,        /* sentinel */
>>>>>>>>  };
>>>>>>>>
>>>>>>>> @@ -125,6 +136,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,
>>>>>>>> @@ -144,6 +160,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,
>>>>>>>>       },
>>>>>>>>       [BQ27500] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -163,6 +184,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27510] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -182,6 +208,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x20,
>>>>>>>>               [BQ27XXX_REG_DCAP] = 0x2e,
>>>>>>>>               [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27530] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -201,6 +232,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27541] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -220,6 +256,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27545] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -239,6 +280,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x2c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
>>>>>>>>               [BQ27XXX_REG_AP] = 0x24,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27421] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -258,6 +304,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>>       },
>>>>>>>>       [BQ27425] = {
>>>>>>>>               [BQ27XXX_REG_CTRL] = 0x00,
>>>>>>>> @@ -277,6 +328,11 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
>>>>>>>>               [BQ27XXX_REG_SOC] = 0x1c,
>>>>>>>>               [BQ27XXX_REG_DCAP] = 0x3c,
>>>>>>>>               [BQ27XXX_REG_AP] = 0x18,
>>>>>>>> +             [BQ27XXX_DM_CTRL] = 0x61,
>>>>>>>> +             [BQ27XXX_DM_CLASS] = 0x3e,
>>>>>>>> +             [BQ27XXX_DM_BLOCK] = 0x3f,
>>>>>>>> +             [BQ27XXX_DM_DATA] = 0x40,
>>>>>>>> +             [BQ27XXX_DM_CKSUM] = 0x60,
>>>>>>>
>>>>>>> That wasn't so painful was it :)
>>>>>>
>>>>>> It added 11% to the patch :-/
>>>>>>
>>>>>>>>       },
>>>>>>>>  };
>>>>>>>>
>>>>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>>>>
>>>>>>>> +#define BQ27XXX_DM_SZ                        32
>>>>>>>> +
>>>>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>>>>> +
>>>>>>>> +struct bq27xxx_dm_reg {
>>>>>>>> +     u8 subclass_id;
>>>>>>>> +     u8 offset;
>>>>>>>> +     u8 bytes;
>>>>>>>> +     u16 min, max;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct bq27xxx_dm_buf {
>>>>>>>> +     u8 class;
>>>>>>>> +     u8 block;
>>>>>>>> +     u8 a[BQ27XXX_DM_SZ];
>>>>>>>> +     bool full, updt;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>>>>> +     .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>>>>> +     .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>>>>> +                                   struct bq27xxx_dm_reg *reg) {
>>>>>>>> +     if (buf->class == reg->subclass_id
>>>>>>>> +      && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>>>>> +             return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>>>>> +
>>>>>>>> +     return NULL;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +enum bq27xxx_dm_reg_id {
>>>>>>>> +     BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>>>>> +     BQ27XXX_DM_DESIGN_ENERGY,
>>>>>>>> +     BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>>>>> +     [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>>>>> +     [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>>>>> +     [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 },
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>>>>> +     [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[] = { /* not tested */
>>>>>>>> +//   [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 },
>>>>>>>> +//};
>>>>>>>
>>>>>>> I don't think this comment style is allowed.
>>>>>>
>>>>>> This is a to-do item.
>>>>>>
>>>>>>>> +
>>>>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>>>>> +     [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>>>>> +     [BQ27425] = bq27425_dm_regs,
>>>>>>>> +//   [BQ27621] = bq27621_dm_regs,
>>>>>>>> +};
>>>>>>>
>>>>>>> I know it is not tested, but lets not comment it out, I'll do a round of
>>>>>>> testing for this part when this series is ready.
>>>>>>
>>>>>> ID for 621 is not yet defined. We need an efficient way to add IDs.
>>>>>> Perhaps via chip-id and group-id. Most current ID refs would be to
>>>>>> group-id. I'd like to defer that, so we should only add inputs for the
>>>>>> single-chip groups in this patchset: 500, 545, 425.
>>>>>>
>>>>>> We must NOT set one-time program (OTP) memory, mentioned in 421 & 441
>>>>>> docs. It's not clear whether documented data-memory ops change OTP.
>>>>>> Can you ask? The 425 has rewritable NVM. The 621 docs don't say. All
>>>>>> the above have cfgupdate mode, which the rest of the family lacks.
>>>>>>
>>>>>
>>>>> This would be a good question for e2e[0].
>>>>>
>>>>> [0] http://e2e.ti.com/support/power_management/battery_management/f/180
>>>>
>>>> Can I ask you to handle discussions with TI folks?
>>>>
>>>
>>> You can ask, doesn't mean I will :) but really I don't have any special
>>> means of getting a hold of the gauge team that you don't have (except
>>> maybe walking over to their cubes and bugging them).
>>>
>>> We try to ask even internal inter-team questions on e2e, you can see
>>> questions asked by TI employees to other employees on that site, the
>>> idea is that if we have a problem, someday customers may have the same
>>> problem, so it's best not no keep these answers buried in some internal
>>> email chain. So the most I would do is post the same question to them on
>>> e2e, you can avoid me being a middle-man by asking them directly.
>>
>> I understand; I'm just trying to minimize my todo list for this
>> patchset. We can put off the OTP issue, as this patchset won't support
>> those parts, since that needs the chip-id/group-id fix I mentioned.
>
> Here for use now or later is the Q I would ask:
>
> The following parts provide set_cfgupdate & soft_reset commands:
> BQ27... 421, 425, 441, 621
>
> Docs for 421 & 441 mention OTP memory
> Docs for 621 do not mention OTP
> Docs for 425 mention rewritable NVM
>
> What is in OTP on 421 & 441?
> Is anything in OTP on 621?
> Is anything in OTP on 425?
>
> Will documented data-memory ops, e.g. BlockData(), change OTP?
> Is OTP only changed in config-update mode?
>
> Context: we are adding DM update to the BQ27xxx linux driver, and must
> avoid setting OTP memory.

The above Q was asked and answered here:
https://e2e.ti.com/support/power_management/battery_management/f/180/t/577798

On that basis, I'll use set_cfgupdate for all the mentioned parts.

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found]     ` <20170227071117.18934-2-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
@ 2017-03-02 15:14       ` Rob Herring
  2017-03-02 18:31         ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Rob Herring @ 2017-03-02 15:14 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Matt Ranostay,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> 
> Documentation of static battery characteristics that can be defined
> for batteries which cannot self-identify. This information is required
> by fuel-gauge and charger chips for proper handling of the battery.
> 
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> ---
>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
> new file mode 100644
> index 0000000..3d916bd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
> @@ -0,0 +1,42 @@
> +Battery Characteristics
> +
> +Required Properties:
> + - compatible: Must be "fixed-battery"

Still not liking this name, but I don't have a better suggestion. Please 
describe here what is and isn't a "fixed 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
> +
> +Future Properties must be named for the corresponding elements in
> +enum power_supply_property, defined in include/linux/power_supply.h.

Um, no. That's exactly not how DT bindings should be done.

> +
> +Batteries must be referenced by chargers and/or fuel-gauges
> +using a phandle. The phandle's property should be named
> +"monitored-battery".
> +
> +Driver code should call power_supply_get_battery_info() to obtain
> +battery properties via monitored-battery. For details see:
> +  drivers/power/supply/power_supply_core.c
> +  drivers/power/supply/bq27xxx_battery.c
> +
> +Example:
> +
> +	bat: battery {
> +		compatible = "fixed-battery";
> +		voltage-min-design-microvolt = <3200000>;
> +		energy-full-design-microwatt-hours = <5290000>;
> +		charge-full-design-microamp-hours = <1430000>;
> +	};
> +
> +	charger: charger@11 {
> +		....
> +		monitored-battery = <&bat>;
> +		...
> +	};
> +
> +	fuel_gauge: fuel-gauge@22 {
> +		....
> +		monitored-battery = <&bat>;
> +		...
> +	};
> -- 
> 2.9.3
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 3/9] devicetree: power: bq27xxx: Add monitored-battery documentation
       [not found]     ` <20170227071117.18934-4-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
@ 2017-03-02 15:16       ` Rob Herring
  0 siblings, 0 replies; 37+ messages in thread
From: Rob Herring @ 2017-03-02 15:16 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Matt Ranostay,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Sun, Feb 26, 2017 at 11:11:11PM -0800, Liam Breck wrote:
> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> 
> Document monitored-battery = <&battery_node>
> 
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
  2017-03-02 15:14       ` Rob Herring
@ 2017-03-02 18:31         ` Liam Breck
  2017-03-15 20:10           ` Rob Herring
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-03-02 18:31 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Matt Ranostay,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

Hi Rob,

On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>
>> Documentation of static battery characteristics that can be defined
>> for batteries which cannot self-identify. This information is required
>> by fuel-gauge and charger chips for proper handling of the battery.
>>
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>> ---
>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>  1 file changed, 42 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>> new file mode 100644
>> index 0000000..3d916bd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>> @@ -0,0 +1,42 @@
>> +Battery Characteristics
>> +
>> +Required Properties:
>> + - compatible: Must be "fixed-battery"
>
> Still not liking this name, but I don't have a better suggestion. Please
> describe here what is and isn't a "fixed battery".

Sebastian...?

>> +
>> +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
>> +
>> +Future Properties must be named for the corresponding elements in
>> +enum power_supply_property, defined in include/linux/power_supply.h.
>
> Um, no. That's exactly not how DT bindings should be done.

Power supply components surface stats in sysfs using the names in enum
power_supply_property. For example,
/sys/class/power_supply/.../voltage_min_design. Matching input (DT)
and output (sysfs) names is sensible. The above comment is already
attached to struct power_supply_battery_info, which is the initial
destination for the above DT properties.

Shall I mention sysfs in the above comment?

>> +
>> +Batteries must be referenced by chargers and/or fuel-gauges
>> +using a phandle. The phandle's property should be named
>> +"monitored-battery".
>> +
>> +Driver code should call power_supply_get_battery_info() to obtain
>> +battery properties via monitored-battery. For details see:
>> +  drivers/power/supply/power_supply_core.c
>> +  drivers/power/supply/bq27xxx_battery.c
>> +
>> +Example:
>> +
>> +     bat: battery {
>> +             compatible = "fixed-battery";
>> +             voltage-min-design-microvolt = <3200000>;
>> +             energy-full-design-microwatt-hours = <5290000>;
>> +             charge-full-design-microamp-hours = <1430000>;
>> +     };
>> +
>> +     charger: charger@11 {
>> +             ....
>> +             monitored-battery = <&bat>;
>> +             ...
>> +     };
>> +
>> +     fuel_gauge: fuel-gauge@22 {
>> +             ....
>> +             monitored-battery = <&bat>;
>> +             ...
>> +     };
>> --
>> 2.9.3
>>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-02-27  7:11 ` [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support Liam Breck
  2017-02-27 18:06   ` Andrew F. Davis
@ 2017-03-03 21:36   ` Liam Breck
  2017-03-03 21:51     ` Andrew F. Davis
  1 sibling, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-03-03 21:36 UTC (permalink / raw)
  To: Sebastian Reichel; +Cc: Andrew F. Davis, linux-pm, Matt Ranostay, Liam Breck

Hi Andrew,

On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
> From: Liam Breck <kernel@networkimprov.net>
>
> Previously there was no way to configure chip registers in the event that the
> defaults didn't match the battery in question.
>
> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
> and writes battery data to chip RAM or non-volatile memory.
>
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> Signed-off-by: Liam Breck <kernel@networkimprov.net>
> ---
>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>  1 file changed, 456 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 7475a5f..41d4ce7 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c

> @@ -452,6 +508,81 @@ static struct {
>  static DEFINE_MUTEX(bq27xxx_list_lock);
>  static LIST_HEAD(bq27xxx_battery_devices);
>
> +#define BQ27XXX_DM_SZ                  32
> +
> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
> +
> +struct bq27xxx_dm_reg {
> +       u8 subclass_id;
> +       u8 offset;
> +       u8 bytes;
> +       u16 min, max;
> +};
> +
> +struct bq27xxx_dm_buf {
> +       u8 class;
> +       u8 block;
> +       u8 a[BQ27XXX_DM_SZ];
> +       bool full, updt;
> +};
> +
> +#define BQ27XXX_DM_BUF(di, i) { \
> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
> +}
> +
> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
> +                                     struct bq27xxx_dm_reg *reg) {
> +       if (buf->class == reg->subclass_id
> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
> +
> +       return NULL;
> +}
> +
> +enum bq27xxx_dm_reg_id {
> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
> +       BQ27XXX_DM_DESIGN_ENERGY,
> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
> +};
> +
> +static const char* bq27xxx_dm_reg_name[] = {
> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
> +       [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 },
> +};
> +
> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
> +       [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[] = { /* not tested */
> +//     [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 },
> +//};
> +
> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
> +       [BQ27425] = bq27425_dm_regs,
> +//     [BQ27621] = bq27621_dm_regs,
> +};
> +
> +static u32 bq27xxx_unseal_keys[] = {
> +       [BQ27421] = 0x80008000, /* and BQ27441 */
> +       [BQ27425] = 0x04143672,
> +//     [BQ27621] = 0x80008000,
> +};

Maybe instead of defining dm_regs_* tables for many chips in this
file, we should land them in a new header, to let the kernel builder
define and/or pick one for his platform by setting a config option,
e.g. config_bq27xxx_dm_type=421

We could also pull in the dm update code if such an option is defined,
tho it isn't that much code, ~230 lines plus whitespace.

Thoughts?

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-03 21:36   ` Liam Breck
@ 2017-03-03 21:51     ` Andrew F. Davis
  2017-03-03 22:04       ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-03-03 21:51 UTC (permalink / raw)
  To: Liam Breck, Sebastian Reichel; +Cc: linux-pm, Matt Ranostay, Liam Breck

On 03/03/2017 03:36 PM, Liam Breck wrote:
> Hi Andrew,
> 
> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>> From: Liam Breck <kernel@networkimprov.net>
>>
>> Previously there was no way to configure chip registers in the event that the
>> defaults didn't match the battery in question.
>>
>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>> and writes battery data to chip RAM or non-volatile memory.
>>
>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>> ---
>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>> index 7475a5f..41d4ce7 100644
>> --- a/drivers/power/supply/bq27xxx_battery.c
>> +++ b/drivers/power/supply/bq27xxx_battery.c
> 
>> @@ -452,6 +508,81 @@ static struct {
>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>  static LIST_HEAD(bq27xxx_battery_devices);
>>
>> +#define BQ27XXX_DM_SZ                  32
>> +
>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>> +
>> +struct bq27xxx_dm_reg {
>> +       u8 subclass_id;
>> +       u8 offset;
>> +       u8 bytes;
>> +       u16 min, max;
>> +};
>> +
>> +struct bq27xxx_dm_buf {
>> +       u8 class;
>> +       u8 block;
>> +       u8 a[BQ27XXX_DM_SZ];
>> +       bool full, updt;
>> +};
>> +
>> +#define BQ27XXX_DM_BUF(di, i) { \
>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>> +}
>> +
>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>> +                                     struct bq27xxx_dm_reg *reg) {
>> +       if (buf->class == reg->subclass_id
>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>> +
>> +       return NULL;
>> +}
>> +
>> +enum bq27xxx_dm_reg_id {
>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>> +       BQ27XXX_DM_DESIGN_ENERGY,
>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>> +};
>> +
>> +static const char* bq27xxx_dm_reg_name[] = {
>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>> +       [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 },
>> +};
>> +
>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>> +       [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[] = { /* not tested */
>> +//     [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 },
>> +//};
>> +
>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>> +       [BQ27425] = bq27425_dm_regs,
>> +//     [BQ27621] = bq27621_dm_regs,
>> +};
>> +
>> +static u32 bq27xxx_unseal_keys[] = {
>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>> +       [BQ27425] = 0x04143672,
>> +//     [BQ27621] = 0x80008000,
>> +};
> 
> Maybe instead of defining dm_regs_* tables for many chips in this
> file, we should land them in a new header, to let the kernel builder
> define and/or pick one for his platform by setting a config option,
> e.g. config_bq27xxx_dm_type=421
> 

Size isn't really an issue, we build drivers for parts we may not have,
you should be able to add a part to a system and only change the DT. So
supporting all these chips is okay.

> We could also pull in the dm update code if such an option is defined,
> tho it isn't that much code, ~230 lines plus whitespace.
> 

We can have a config option to enable support for DM update, if it can
be factored out in such a way. Otherwise if someone uses it, just
include it for everyone, if they need it it's there, if they don't then
no harm done.

> Thoughts?
> 

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-03 21:51     ` Andrew F. Davis
@ 2017-03-03 22:04       ` Liam Breck
  2017-03-03 22:07         ` Andrew F. Davis
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-03-03 22:04 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Fri, Mar 3, 2017 at 1:51 PM, Andrew F. Davis <afd@ti.com> wrote:
> On 03/03/2017 03:36 PM, Liam Breck wrote:
>> Hi Andrew,
>>
>> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>>> From: Liam Breck <kernel@networkimprov.net>
>>>
>>> Previously there was no way to configure chip registers in the event that the
>>> defaults didn't match the battery in question.
>>>
>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>> and writes battery data to chip RAM or non-volatile memory.
>>>
>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>> ---
>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>> index 7475a5f..41d4ce7 100644
>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>
>>> @@ -452,6 +508,81 @@ static struct {
>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>
>>> +#define BQ27XXX_DM_SZ                  32
>>> +
>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>> +
>>> +struct bq27xxx_dm_reg {
>>> +       u8 subclass_id;
>>> +       u8 offset;
>>> +       u8 bytes;
>>> +       u16 min, max;
>>> +};
>>> +
>>> +struct bq27xxx_dm_buf {
>>> +       u8 class;
>>> +       u8 block;
>>> +       u8 a[BQ27XXX_DM_SZ];
>>> +       bool full, updt;
>>> +};
>>> +
>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>> +}
>>> +
>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>> +                                     struct bq27xxx_dm_reg *reg) {
>>> +       if (buf->class == reg->subclass_id
>>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>> +
>>> +       return NULL;
>>> +}
>>> +
>>> +enum bq27xxx_dm_reg_id {
>>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>> +       BQ27XXX_DM_DESIGN_ENERGY,
>>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>>> +};
>>> +
>>> +static const char* bq27xxx_dm_reg_name[] = {
>>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>> +       [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 },
>>> +};
>>> +
>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>> +       [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[] = { /* not tested */
>>> +//     [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 },
>>> +//};
>>> +
>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>> +       [BQ27425] = bq27425_dm_regs,
>>> +//     [BQ27621] = bq27621_dm_regs,
>>> +};
>>> +
>>> +static u32 bq27xxx_unseal_keys[] = {
>>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>>> +       [BQ27425] = 0x04143672,
>>> +//     [BQ27621] = 0x80008000,
>>> +};
>>
>> Maybe instead of defining dm_regs_* tables for many chips in this
>> file, we should land them in a new header, to let the kernel builder
>> define and/or pick one for his platform by setting a config option,
>> e.g. config_bq27xxx_dm_type=421
>>
>
> Size isn't really an issue, we build drivers for parts we may not have,
> you should be able to add a part to a system and only change the DT. So
> supporting all these chips is okay.

OK but suppose kernel builders define a dm_regs{} when it's missing.
Doing that in bq27xxx_battery.c isn't ideal.

>> We could also pull in the dm update code if such an option is defined,
>> tho it isn't that much code, ~230 lines plus whitespace.
>>
>
> We can have a config option to enable support for DM update, if it can
> be factored out in such a way. Otherwise if someone uses it, just
> include it for everyone, if they need it it's there, if they don't then
> no harm done.
>
>> Thoughts?
>>

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-03 22:04       ` Liam Breck
@ 2017-03-03 22:07         ` Andrew F. Davis
  2017-03-03 22:13           ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-03-03 22:07 UTC (permalink / raw)
  To: Liam Breck; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On 03/03/2017 04:04 PM, Liam Breck wrote:
> On Fri, Mar 3, 2017 at 1:51 PM, Andrew F. Davis <afd@ti.com> wrote:
>> On 03/03/2017 03:36 PM, Liam Breck wrote:
>>> Hi Andrew,
>>>
>>> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>
>>>> Previously there was no way to configure chip registers in the event that the
>>>> defaults didn't match the battery in question.
>>>>
>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>
>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>> ---
>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>> index 7475a5f..41d4ce7 100644
>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>
>>>> @@ -452,6 +508,81 @@ static struct {
>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>
>>>> +#define BQ27XXX_DM_SZ                  32
>>>> +
>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>> +
>>>> +struct bq27xxx_dm_reg {
>>>> +       u8 subclass_id;
>>>> +       u8 offset;
>>>> +       u8 bytes;
>>>> +       u16 min, max;
>>>> +};
>>>> +
>>>> +struct bq27xxx_dm_buf {
>>>> +       u8 class;
>>>> +       u8 block;
>>>> +       u8 a[BQ27XXX_DM_SZ];
>>>> +       bool full, updt;
>>>> +};
>>>> +
>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>> +}
>>>> +
>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>> +                                     struct bq27xxx_dm_reg *reg) {
>>>> +       if (buf->class == reg->subclass_id
>>>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>> +
>>>> +       return NULL;
>>>> +}
>>>> +
>>>> +enum bq27xxx_dm_reg_id {
>>>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>> +       BQ27XXX_DM_DESIGN_ENERGY,
>>>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>> +};
>>>> +
>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>> +       [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 },
>>>> +};
>>>> +
>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>> +       [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[] = { /* not tested */
>>>> +//     [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 },
>>>> +//};
>>>> +
>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>> +       [BQ27425] = bq27425_dm_regs,
>>>> +//     [BQ27621] = bq27621_dm_regs,
>>>> +};
>>>> +
>>>> +static u32 bq27xxx_unseal_keys[] = {
>>>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>>>> +       [BQ27425] = 0x04143672,
>>>> +//     [BQ27621] = 0x80008000,
>>>> +};
>>>
>>> Maybe instead of defining dm_regs_* tables for many chips in this
>>> file, we should land them in a new header, to let the kernel builder
>>> define and/or pick one for his platform by setting a config option,
>>> e.g. config_bq27xxx_dm_type=421
>>>
>>
>> Size isn't really an issue, we build drivers for parts we may not have,
>> you should be able to add a part to a system and only change the DT. So
>> supporting all these chips is okay.
> 
> OK but suppose kernel builders define a dm_regs{} when it's missing.
> Doing that in bq27xxx_battery.c isn't ideal.
> 

Why would it be missing? All this stuff should be left defined always,
if it is unused on a particular board that really cant be avoided.

>>> We could also pull in the dm update code if such an option is defined,
>>> tho it isn't that much code, ~230 lines plus whitespace.
>>>
>>
>> We can have a config option to enable support for DM update, if it can
>> be factored out in such a way. Otherwise if someone uses it, just
>> include it for everyone, if they need it it's there, if they don't then
>> no harm done.
>>
>>> Thoughts?
>>>

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-03 22:07         ` Andrew F. Davis
@ 2017-03-03 22:13           ` Liam Breck
  2017-03-06 16:42             ` Andrew F. Davis
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-03-03 22:13 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Fri, Mar 3, 2017 at 2:07 PM, Andrew F. Davis <afd@ti.com> wrote:
> On 03/03/2017 04:04 PM, Liam Breck wrote:
>> On Fri, Mar 3, 2017 at 1:51 PM, Andrew F. Davis <afd@ti.com> wrote:
>>> On 03/03/2017 03:36 PM, Liam Breck wrote:
>>>> Hi Andrew,
>>>>
>>>> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>
>>>>> Previously there was no way to configure chip registers in the event that the
>>>>> defaults didn't match the battery in question.
>>>>>
>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>
>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>> ---
>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>> index 7475a5f..41d4ce7 100644
>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>
>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>
>>>>> +#define BQ27XXX_DM_SZ                  32
>>>>> +
>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>> +
>>>>> +struct bq27xxx_dm_reg {
>>>>> +       u8 subclass_id;
>>>>> +       u8 offset;
>>>>> +       u8 bytes;
>>>>> +       u16 min, max;
>>>>> +};
>>>>> +
>>>>> +struct bq27xxx_dm_buf {
>>>>> +       u8 class;
>>>>> +       u8 block;
>>>>> +       u8 a[BQ27XXX_DM_SZ];
>>>>> +       bool full, updt;
>>>>> +};
>>>>> +
>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>> +}
>>>>> +
>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>> +                                     struct bq27xxx_dm_reg *reg) {
>>>>> +       if (buf->class == reg->subclass_id
>>>>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>> +
>>>>> +       return NULL;
>>>>> +}
>>>>> +
>>>>> +enum bq27xxx_dm_reg_id {
>>>>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>> +       BQ27XXX_DM_DESIGN_ENERGY,
>>>>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>> +};
>>>>> +
>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>> +       [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 },
>>>>> +};
>>>>> +
>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>> +       [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[] = { /* not tested */
>>>>> +//     [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 },
>>>>> +//};
>>>>> +
>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>> +       [BQ27425] = bq27425_dm_regs,
>>>>> +//     [BQ27621] = bq27621_dm_regs,
>>>>> +};
>>>>> +
>>>>> +static u32 bq27xxx_unseal_keys[] = {
>>>>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>>>>> +       [BQ27425] = 0x04143672,
>>>>> +//     [BQ27621] = 0x80008000,
>>>>> +};
>>>>
>>>> Maybe instead of defining dm_regs_* tables for many chips in this
>>>> file, we should land them in a new header, to let the kernel builder
>>>> define and/or pick one for his platform by setting a config option,
>>>> e.g. config_bq27xxx_dm_type=421
>>>>
>>>
>>> Size isn't really an issue, we build drivers for parts we may not have,
>>> you should be able to add a part to a system and only change the DT. So
>>> supporting all these chips is okay.
>>
>> OK but suppose kernel builders define a dm_regs{} when it's missing.
>> Doing that in bq27xxx_battery.c isn't ideal.
>>
>
> Why would it be missing? All this stuff should be left defined always,
> if it is unused on a particular board that really cant be avoided.

Are you going to comb thru the manuals for all the supported parts,
assemble dm_regs tables and test them? :-)

>>>> We could also pull in the dm update code if such an option is defined,
>>>> tho it isn't that much code, ~230 lines plus whitespace.
>>>>
>>>
>>> We can have a config option to enable support for DM update, if it can
>>> be factored out in such a way. Otherwise if someone uses it, just
>>> include it for everyone, if they need it it's there, if they don't then
>>> no harm done.
>>>
>>>> Thoughts?
>>>>

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-03 22:13           ` Liam Breck
@ 2017-03-06 16:42             ` Andrew F. Davis
  2017-03-06 20:14               ` Liam Breck
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-03-06 16:42 UTC (permalink / raw)
  To: Liam Breck; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On 03/03/2017 04:13 PM, Liam Breck wrote:
> On Fri, Mar 3, 2017 at 2:07 PM, Andrew F. Davis <afd@ti.com> wrote:
>> On 03/03/2017 04:04 PM, Liam Breck wrote:
>>> On Fri, Mar 3, 2017 at 1:51 PM, Andrew F. Davis <afd@ti.com> wrote:
>>>> On 03/03/2017 03:36 PM, Liam Breck wrote:
>>>>> Hi Andrew,
>>>>>
>>>>> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>
>>>>>> Previously there was no way to configure chip registers in the event that the
>>>>>> defaults didn't match the battery in question.
>>>>>>
>>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>>
>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>> ---
>>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>>> index 7475a5f..41d4ce7 100644
>>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>>
>>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>>
>>>>>> +#define BQ27XXX_DM_SZ                  32
>>>>>> +
>>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>>> +
>>>>>> +struct bq27xxx_dm_reg {
>>>>>> +       u8 subclass_id;
>>>>>> +       u8 offset;
>>>>>> +       u8 bytes;
>>>>>> +       u16 min, max;
>>>>>> +};
>>>>>> +
>>>>>> +struct bq27xxx_dm_buf {
>>>>>> +       u8 class;
>>>>>> +       u8 block;
>>>>>> +       u8 a[BQ27XXX_DM_SZ];
>>>>>> +       bool full, updt;
>>>>>> +};
>>>>>> +
>>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>>> +}
>>>>>> +
>>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>>> +                                     struct bq27xxx_dm_reg *reg) {
>>>>>> +       if (buf->class == reg->subclass_id
>>>>>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>>> +
>>>>>> +       return NULL;
>>>>>> +}
>>>>>> +
>>>>>> +enum bq27xxx_dm_reg_id {
>>>>>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>>> +       BQ27XXX_DM_DESIGN_ENERGY,
>>>>>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>>> +};
>>>>>> +
>>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>>> +       [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 },
>>>>>> +};
>>>>>> +
>>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>>> +       [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[] = { /* not tested */
>>>>>> +//     [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 },
>>>>>> +//};
>>>>>> +
>>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>>> +       [BQ27425] = bq27425_dm_regs,
>>>>>> +//     [BQ27621] = bq27621_dm_regs,
>>>>>> +};
>>>>>> +
>>>>>> +static u32 bq27xxx_unseal_keys[] = {
>>>>>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>>>>>> +       [BQ27425] = 0x04143672,
>>>>>> +//     [BQ27621] = 0x80008000,
>>>>>> +};
>>>>>
>>>>> Maybe instead of defining dm_regs_* tables for many chips in this
>>>>> file, we should land them in a new header, to let the kernel builder
>>>>> define and/or pick one for his platform by setting a config option,
>>>>> e.g. config_bq27xxx_dm_type=421
>>>>>
>>>>
>>>> Size isn't really an issue, we build drivers for parts we may not have,
>>>> you should be able to add a part to a system and only change the DT. So
>>>> supporting all these chips is okay.
>>>
>>> OK but suppose kernel builders define a dm_regs{} when it's missing.
>>> Doing that in bq27xxx_battery.c isn't ideal.
>>>
>>
>> Why would it be missing? All this stuff should be left defined always,
>> if it is unused on a particular board that really cant be avoided.
> 
> Are you going to comb thru the manuals for all the supported parts,
> assemble dm_regs tables and test them? :-)
> 

If I was adding a device, then yes, I would do it fully, even if it was
a bit more of a pain at first :)

>>>>> We could also pull in the dm update code if such an option is defined,
>>>>> tho it isn't that much code, ~230 lines plus whitespace.
>>>>>
>>>>
>>>> We can have a config option to enable support for DM update, if it can
>>>> be factored out in such a way. Otherwise if someone uses it, just
>>>> include it for everyone, if they need it it's there, if they don't then
>>>> no harm done.
>>>>
>>>>> Thoughts?
>>>>>

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

* Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
  2017-03-06 16:42             ` Andrew F. Davis
@ 2017-03-06 20:14               ` Liam Breck
  0 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-03-06 20:14 UTC (permalink / raw)
  To: Andrew F. Davis; +Cc: Sebastian Reichel, linux-pm, Matt Ranostay, Liam Breck

On Mon, Mar 6, 2017 at 8:42 AM, Andrew F. Davis <afd@ti.com> wrote:
> On 03/03/2017 04:13 PM, Liam Breck wrote:
>> On Fri, Mar 3, 2017 at 2:07 PM, Andrew F. Davis <afd@ti.com> wrote:
>>> On 03/03/2017 04:04 PM, Liam Breck wrote:
>>>> On Fri, Mar 3, 2017 at 1:51 PM, Andrew F. Davis <afd@ti.com> wrote:
>>>>> On 03/03/2017 03:36 PM, Liam Breck wrote:
>>>>>> Hi Andrew,
>>>>>>
>>>>>> On Sun, Feb 26, 2017 at 11:11 PM, Liam Breck <liam@networkimprov.net> wrote:
>>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>>
>>>>>>> Previously there was no way to configure chip registers in the event that the
>>>>>>> defaults didn't match the battery in question.
>>>>>>>
>>>>>>> BQ27xxx driver now calls power_supply_get_battery_info, checks the inputs,
>>>>>>> and writes battery data to chip RAM or non-volatile memory.
>>>>>>>
>>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>>> ---
>>>>>>>  drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++-
>>>>>>>  1 file changed, 456 insertions(+), 2 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>>>>>>> index 7475a5f..41d4ce7 100644
>>>>>>> --- a/drivers/power/supply/bq27xxx_battery.c
>>>>>>> +++ b/drivers/power/supply/bq27xxx_battery.c
>>>>>>
>>>>>>> @@ -452,6 +508,81 @@ static struct {
>>>>>>>  static DEFINE_MUTEX(bq27xxx_list_lock);
>>>>>>>  static LIST_HEAD(bq27xxx_battery_devices);
>>>>>>>
>>>>>>> +#define BQ27XXX_DM_SZ                  32
>>>>>>> +
>>>>>>> +#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)
>>>>>>> +
>>>>>>> +struct bq27xxx_dm_reg {
>>>>>>> +       u8 subclass_id;
>>>>>>> +       u8 offset;
>>>>>>> +       u8 bytes;
>>>>>>> +       u16 min, max;
>>>>>>> +};
>>>>>>> +
>>>>>>> +struct bq27xxx_dm_buf {
>>>>>>> +       u8 class;
>>>>>>> +       u8 block;
>>>>>>> +       u8 a[BQ27XXX_DM_SZ];
>>>>>>> +       bool full, updt;
>>>>>>> +};
>>>>>>> +
>>>>>>> +#define BQ27XXX_DM_BUF(di, i) { \
>>>>>>> +       .class = bq27xxx_dm_regs[(di)->chip][i].subclass_id, \
>>>>>>> +       .block = bq27xxx_dm_regs[(di)->chip][i].offset / BQ27XXX_DM_SZ, \
>>>>>>> +}
>>>>>>> +
>>>>>>> +static inline u16* bq27xxx_dm_buf_ptr(struct bq27xxx_dm_buf *buf,
>>>>>>> +                                     struct bq27xxx_dm_reg *reg) {
>>>>>>> +       if (buf->class == reg->subclass_id
>>>>>>> +        && buf->block == reg->offset / BQ27XXX_DM_SZ)
>>>>>>> +               return (u16*) (buf->a + reg->offset % BQ27XXX_DM_SZ);
>>>>>>> +
>>>>>>> +       return NULL;
>>>>>>> +}
>>>>>>> +
>>>>>>> +enum bq27xxx_dm_reg_id {
>>>>>>> +       BQ27XXX_DM_DESIGN_CAPACITY = 0,
>>>>>>> +       BQ27XXX_DM_DESIGN_ENERGY,
>>>>>>> +       BQ27XXX_DM_TERMINATE_VOLTAGE,
>>>>>>> +};
>>>>>>> +
>>>>>>> +static const char* bq27xxx_dm_reg_name[] = {
>>>>>>> +       [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",
>>>>>>> +       [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",
>>>>>>> +       [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 },
>>>>>>> +};
>>>>>>> +
>>>>>>> +static struct bq27xxx_dm_reg bq27421_dm_regs[] = { /* not tested */
>>>>>>> +       [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[] = { /* not tested */
>>>>>>> +//     [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 },
>>>>>>> +//};
>>>>>>> +
>>>>>>> +static struct bq27xxx_dm_reg *bq27xxx_dm_regs[] = {
>>>>>>> +       [BQ27421] = bq27421_dm_regs, /* and BQ27441 */
>>>>>>> +       [BQ27425] = bq27425_dm_regs,
>>>>>>> +//     [BQ27621] = bq27621_dm_regs,
>>>>>>> +};
>>>>>>> +
>>>>>>> +static u32 bq27xxx_unseal_keys[] = {
>>>>>>> +       [BQ27421] = 0x80008000, /* and BQ27441 */
>>>>>>> +       [BQ27425] = 0x04143672,
>>>>>>> +//     [BQ27621] = 0x80008000,
>>>>>>> +};
>>>>>>
>>>>>> Maybe instead of defining dm_regs_* tables for many chips in this
>>>>>> file, we should land them in a new header, to let the kernel builder
>>>>>> define and/or pick one for his platform by setting a config option,
>>>>>> e.g. config_bq27xxx_dm_type=421
>>>>>>
>>>>>
>>>>> Size isn't really an issue, we build drivers for parts we may not have,
>>>>> you should be able to add a part to a system and only change the DT. So
>>>>> supporting all these chips is okay.
>>>>
>>>> OK but suppose kernel builders define a dm_regs{} when it's missing.
>>>> Doing that in bq27xxx_battery.c isn't ideal.
>>>>
>>>
>>> Why would it be missing? All this stuff should be left defined always,
>>> if it is unused on a particular board that really cant be avoided.
>>
>> Are you going to comb thru the manuals for all the supported parts,
>> assemble dm_regs tables and test them? :-)
>>
>
> If I was adding a device, then yes, I would do it fully, even if it was
> a bit more of a pain at first :)

By "device" you mean chip? We do not enable new chips in this patchset.

In v9, I support uniquely-defined chip IDs (500, 545, 421), which I
need you to test. As there's 13 more chips to test, I think we should
limit this patchset to those 3.


>>>>>> We could also pull in the dm update code if such an option is defined,
>>>>>> tho it isn't that much code, ~230 lines plus whitespace.
>>>>>>
>>>>>
>>>>> We can have a config option to enable support for DM update, if it can
>>>>> be factored out in such a way. Otherwise if someone uses it, just
>>>>> include it for everyone, if they need it it's there, if they don't then
>>>>> no harm done.
>>>>>
>>>>>> Thoughts?
>>>>>>

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
  2017-03-02 18:31         ` Liam Breck
@ 2017-03-15 20:10           ` Rob Herring
       [not found]             ` <CAL_Jsq+8Y=GtyjVZA-suZLH+ySDshaoU9qh96BF+PeUYK3FZxg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 37+ messages in thread
From: Rob Herring @ 2017-03-15 20:10 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Andrew F. Davis, linux-pm, Matt Ranostay,
	devicetree, Liam Breck

On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam@networkimprov.net> wrote:
> Hi Rob,
>
> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh@kernel.org> wrote:
>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>> From: Liam Breck <kernel@networkimprov.net>
>>>
>>> Documentation of static battery characteristics that can be defined
>>> for batteries which cannot self-identify. This information is required
>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>
>>> Cc: Rob Herring <robh@kernel.org>
>>> Cc: devicetree@vger.kernel.org
>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>> ---
>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>  1 file changed, 42 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>> new file mode 100644
>>> index 0000000..3d916bd
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>> @@ -0,0 +1,42 @@
>>> +Battery Characteristics
>>> +
>>> +Required Properties:
>>> + - compatible: Must be "fixed-battery"
>>
>> Still not liking this name, but I don't have a better suggestion. Please
>> describe here what is and isn't a "fixed battery".
>
> Sebastian...?
>
>>> +
>>> +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
>>> +
>>> +Future Properties must be named for the corresponding elements in
>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>
>> Um, no. That's exactly not how DT bindings should be done.
>
> Power supply components surface stats in sysfs using the names in enum
> power_supply_property. For example,
> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
> and output (sysfs) names is sensible. The above comment is already
> attached to struct power_supply_battery_info, which is the initial
> destination for the above DT properties.
>
> Shall I mention sysfs in the above comment?

Absolutely not. Bindings should not reference Linux.

While sometimes things can align, there is no guarantee that they
will. DT is h/w description. sysfs is user configuration.

Rob

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found]             ` <CAL_Jsq+8Y=GtyjVZA-suZLH+ySDshaoU9qh96BF+PeUYK3FZxg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-03-15 22:04               ` Liam Breck
  2017-03-15 23:50                 ` Rob Herring
  0 siblings, 1 reply; 37+ messages in thread
From: Liam Breck @ 2017-03-15 22:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>> Hi Rob,
>>
>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>
>>>> Documentation of static battery characteristics that can be defined
>>>> for batteries which cannot self-identify. This information is required
>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>
>>>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>> ---
>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>  1 file changed, 42 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>> new file mode 100644
>>>> index 0000000..3d916bd
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>> @@ -0,0 +1,42 @@
>>>> +Battery Characteristics
>>>> +
>>>> +Required Properties:
>>>> + - compatible: Must be "fixed-battery"
>>>
>>> Still not liking this name, but I don't have a better suggestion. Please
>>> describe here what is and isn't a "fixed battery".
>>
>> Sebastian...?
>>
>>>> +
>>>> +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
>>>> +
>>>> +Future Properties must be named for the corresponding elements in
>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>
>>> Um, no. That's exactly not how DT bindings should be done.
>>
>> Power supply components surface stats in sysfs using the names in enum
>> power_supply_property. For example,
>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>> and output (sysfs) names is sensible. The above comment is already
>> attached to struct power_supply_battery_info, which is the initial
>> destination for the above DT properties.
>>
>> Shall I mention sysfs in the above comment?
>
> Absolutely not. Bindings should not reference Linux.
>
> While sometimes things can align, there is no guarantee that they
> will. DT is h/w description. sysfs is user configuration.

sysfs for power_supply also provides fixed hw characteristics.

Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery and
power_supply_property to diverge would cause confusion and wasted
time, for no particular benefit. As there is no rationale to
reconsider the names of these fields for DT:battery, let's write that
into the docs.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
  2017-03-15 22:04               ` Liam Breck
@ 2017-03-15 23:50                 ` Rob Herring
       [not found]                   ` <CAL_JsqJOFUSRY_KPzwNWrx4FF1_F6XNK8OfkqhqgBpxH9WrZeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 37+ messages in thread
From: Rob Herring @ 2017-03-15 23:50 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Andrew F. Davis, linux-pm, devicetree, Liam Breck

On Wed, Mar 15, 2017 at 5:04 PM, Liam Breck <liam@networkimprov.net> wrote:
> On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh@kernel.org> wrote:
>> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam@networkimprov.net> wrote:
>>> Hi Rob,
>>>
>>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh@kernel.org> wrote:
>>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>
>>>>> Documentation of static battery characteristics that can be defined
>>>>> for batteries which cannot self-identify. This information is required
>>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>>
>>>>> Cc: Rob Herring <robh@kernel.org>
>>>>> Cc: devicetree@vger.kernel.org
>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>> ---
>>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>>  1 file changed, 42 insertions(+)
>>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>> new file mode 100644
>>>>> index 0000000..3d916bd
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>> @@ -0,0 +1,42 @@
>>>>> +Battery Characteristics
>>>>> +
>>>>> +Required Properties:
>>>>> + - compatible: Must be "fixed-battery"
>>>>
>>>> Still not liking this name, but I don't have a better suggestion. Please
>>>> describe here what is and isn't a "fixed battery".
>>>
>>> Sebastian...?
>>>
>>>>> +
>>>>> +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
>>>>> +
>>>>> +Future Properties must be named for the corresponding elements in
>>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>>
>>>> Um, no. That's exactly not how DT bindings should be done.
>>>
>>> Power supply components surface stats in sysfs using the names in enum
>>> power_supply_property. For example,
>>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>>> and output (sysfs) names is sensible. The above comment is already
>>> attached to struct power_supply_battery_info, which is the initial
>>> destination for the above DT properties.
>>>
>>> Shall I mention sysfs in the above comment?
>>
>> Absolutely not. Bindings should not reference Linux.
>>
>> While sometimes things can align, there is no guarantee that they
>> will. DT is h/w description. sysfs is user configuration.
>
> sysfs for power_supply also provides fixed hw characteristics.
>
> Sebastian proposed DT:battery specifically to be consumed by
> power_supply_core. Allowing names in DT:battery and
> power_supply_property to diverge would cause confusion and wasted
> time, for no particular benefit. As there is no rationale to
> reconsider the names of these fields for DT:battery, let's write that
> into the docs.

Write it into the Linux docs then. The DT docs need to stand on their
own for the standalone DT tree[1] that other projects import.

Rob

[1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found]                   ` <CAL_JsqJOFUSRY_KPzwNWrx4FF1_F6XNK8OfkqhqgBpxH9WrZeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-03-16  6:45                     ` Liam Breck
  2017-03-16 13:31                       ` Andrew F. Davis
       [not found]                       ` <CAKvHMgQujE4uYNt0vPkt6qUOtVqdvzXs0zXTkDVRq9YLNvunBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 2 replies; 37+ messages in thread
From: Liam Breck @ 2017-03-16  6:45 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Wed, Mar 15, 2017 at 4:50 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Wed, Mar 15, 2017 at 5:04 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>> On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>>>> Hi Rob,
>>>>
>>>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>>>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>>
>>>>>> Documentation of static battery characteristics that can be defined
>>>>>> for batteries which cannot self-identify. This information is required
>>>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>>>
>>>>>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>>>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>>>>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>>>>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>> ---
>>>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>>>  1 file changed, 42 insertions(+)
>>>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>> new file mode 100644
>>>>>> index 0000000..3d916bd
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>> @@ -0,0 +1,42 @@
>>>>>> +Battery Characteristics
>>>>>> +
>>>>>> +Required Properties:
>>>>>> + - compatible: Must be "fixed-battery"
>>>>>
>>>>> Still not liking this name, but I don't have a better suggestion. Please
>>>>> describe here what is and isn't a "fixed battery".
>>>>
>>>> Sebastian...?
>>>>
>>>>>> +
>>>>>> +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
>>>>>> +
>>>>>> +Future Properties must be named for the corresponding elements in
>>>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>>>
>>>>> Um, no. That's exactly not how DT bindings should be done.
>>>>
>>>> Power supply components surface stats in sysfs using the names in enum
>>>> power_supply_property. For example,
>>>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>>>> and output (sysfs) names is sensible. The above comment is already
>>>> attached to struct power_supply_battery_info, which is the initial
>>>> destination for the above DT properties.
>>>>
>>>> Shall I mention sysfs in the above comment?
>>>
>>> Absolutely not. Bindings should not reference Linux.
>>>
>>> While sometimes things can align, there is no guarantee that they
>>> will. DT is h/w description. sysfs is user configuration.
>>
>> sysfs for power_supply also provides fixed hw characteristics.
>>
>> Sebastian proposed DT:battery specifically to be consumed by
>> power_supply_core. Allowing names in DT:battery and
>> power_supply_property to diverge would cause confusion and wasted
>> time, for no particular benefit. As there is no rationale to
>> reconsider the names of these fields for DT:battery, let's write that
>> into the docs.
>
> Write it into the Linux docs then. The DT docs need to stand on their
> own for the standalone DT tree[1] that other projects import.

We will document it on the Linux side. But referencing a Linux header
file as the origin of property names in DT;battery does not create a
Linux dependency for standalone DT. It merely clarifies the naming
scheme.

Also a huge number of DT bindings are Linux-specific, as they are
implemented by some kernel driver. Do you plan to rip those out of
devicetree-rebasing?

> [1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
  2017-03-16  6:45                     ` Liam Breck
@ 2017-03-16 13:31                       ` Andrew F. Davis
       [not found]                         ` <bb0928ce-6d29-3d09-2c5b-f4a084fe06e9-l0cyMroinI0@public.gmane.org>
       [not found]                       ` <CAKvHMgQujE4uYNt0vPkt6qUOtVqdvzXs0zXTkDVRq9YLNvunBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 37+ messages in thread
From: Andrew F. Davis @ 2017-03-16 13:31 UTC (permalink / raw)
  To: Liam Breck, Rob Herring
  Cc: Sebastian Reichel, linux-pm, devicetree, Liam Breck

On 03/16/2017 01:45 AM, Liam Breck wrote:
> On Wed, Mar 15, 2017 at 4:50 PM, Rob Herring <robh@kernel.org> wrote:
>> On Wed, Mar 15, 2017 at 5:04 PM, Liam Breck <liam@networkimprov.net> wrote:
>>> On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh@kernel.org> wrote:
>>>> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam@networkimprov.net> wrote:
>>>>> Hi Rob,
>>>>>
>>>>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh@kernel.org> wrote:
>>>>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>>>>> From: Liam Breck <kernel@networkimprov.net>
>>>>>>>
>>>>>>> Documentation of static battery characteristics that can be defined
>>>>>>> for batteries which cannot self-identify. This information is required
>>>>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>>>>
>>>>>>> Cc: Rob Herring <robh@kernel.org>
>>>>>>> Cc: devicetree@vger.kernel.org
>>>>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>>>>> Signed-off-by: Liam Breck <kernel@networkimprov.net>
>>>>>>> ---
>>>>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>>>>  1 file changed, 42 insertions(+)
>>>>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>> new file mode 100644
>>>>>>> index 0000000..3d916bd
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>> @@ -0,0 +1,42 @@
>>>>>>> +Battery Characteristics
>>>>>>> +
>>>>>>> +Required Properties:
>>>>>>> + - compatible: Must be "fixed-battery"
>>>>>>
>>>>>> Still not liking this name, but I don't have a better suggestion. Please
>>>>>> describe here what is and isn't a "fixed battery".
>>>>>
>>>>> Sebastian...?
>>>>>
>>>>>>> +
>>>>>>> +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
>>>>>>> +
>>>>>>> +Future Properties must be named for the corresponding elements in
>>>>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>>>>
>>>>>> Um, no. That's exactly not how DT bindings should be done.
>>>>>
>>>>> Power supply components surface stats in sysfs using the names in enum
>>>>> power_supply_property. For example,
>>>>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>>>>> and output (sysfs) names is sensible. The above comment is already
>>>>> attached to struct power_supply_battery_info, which is the initial
>>>>> destination for the above DT properties.
>>>>>
>>>>> Shall I mention sysfs in the above comment?
>>>>
>>>> Absolutely not. Bindings should not reference Linux.
>>>>
>>>> While sometimes things can align, there is no guarantee that they
>>>> will. DT is h/w description. sysfs is user configuration.
>>>
>>> sysfs for power_supply also provides fixed hw characteristics.
>>>
>>> Sebastian proposed DT:battery specifically to be consumed by
>>> power_supply_core. Allowing names in DT:battery and
>>> power_supply_property to diverge would cause confusion and wasted
>>> time, for no particular benefit. As there is no rationale to
>>> reconsider the names of these fields for DT:battery, let's write that
>>> into the docs.
>>
>> Write it into the Linux docs then. The DT docs need to stand on their
>> own for the standalone DT tree[1] that other projects import.
> 
> We will document it on the Linux side. But referencing a Linux header
> file as the origin of property names in DT;battery does not create a
> Linux dependency for standalone DT. It merely clarifies the naming
> scheme.
> 
> Also a huge number of DT bindings are Linux-specific, as they are
> implemented by some kernel driver. Do you plan to rip those out of
> devicetree-rebasing?
> 

Being implemented by a Linux kernel driver does not mean they can *only*
every be implemented by a Linux kernel driver, U-Boot for instance takes
drivers from Linux and so the DTs work mostly unchanged.

Also the biggest thing to remember is that doing something wrong before,
doesn't justify continuing to do it wrong.

>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found]                         ` <bb0928ce-6d29-3d09-2c5b-f4a084fe06e9-l0cyMroinI0@public.gmane.org>
@ 2017-03-16 14:07                           ` Liam Breck
  0 siblings, 0 replies; 37+ messages in thread
From: Liam Breck @ 2017-03-16 14:07 UTC (permalink / raw)
  To: Andrew F. Davis
  Cc: Rob Herring, Sebastian Reichel, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Thu, Mar 16, 2017 at 6:31 AM, Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org> wrote:
> On 03/16/2017 01:45 AM, Liam Breck wrote:
>> On Wed, Mar 15, 2017 at 4:50 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>> On Wed, Mar 15, 2017 at 5:04 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>>>> On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>>> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>>>>>> Hi Rob,
>>>>>>
>>>>>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>>>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>>>>>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>>>>
>>>>>>>> Documentation of static battery characteristics that can be defined
>>>>>>>> for batteries which cannot self-identify. This information is required
>>>>>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>>>>>
>>>>>>>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>>>>>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>>>>>>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>>>>>>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>>>> ---
>>>>>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>>>>>  1 file changed, 42 insertions(+)
>>>>>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>>>
>>>>>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>>> new file mode 100644
>>>>>>>> index 0000000..3d916bd
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>>> @@ -0,0 +1,42 @@
>>>>>>>> +Battery Characteristics
>>>>>>>> +
>>>>>>>> +Required Properties:
>>>>>>>> + - compatible: Must be "fixed-battery"
>>>>>>>
>>>>>>> Still not liking this name, but I don't have a better suggestion. Please
>>>>>>> describe here what is and isn't a "fixed battery".
>>>>>>
>>>>>> Sebastian...?
>>>>>>
>>>>>>>> +
>>>>>>>> +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
>>>>>>>> +
>>>>>>>> +Future Properties must be named for the corresponding elements in
>>>>>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>>>>>
>>>>>>> Um, no. That's exactly not how DT bindings should be done.
>>>>>>
>>>>>> Power supply components surface stats in sysfs using the names in enum
>>>>>> power_supply_property. For example,
>>>>>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>>>>>> and output (sysfs) names is sensible. The above comment is already
>>>>>> attached to struct power_supply_battery_info, which is the initial
>>>>>> destination for the above DT properties.
>>>>>>
>>>>>> Shall I mention sysfs in the above comment?
>>>>>
>>>>> Absolutely not. Bindings should not reference Linux.
>>>>>
>>>>> While sometimes things can align, there is no guarantee that they
>>>>> will. DT is h/w description. sysfs is user configuration.
>>>>
>>>> sysfs for power_supply also provides fixed hw characteristics.
>>>>
>>>> Sebastian proposed DT:battery specifically to be consumed by
>>>> power_supply_core. Allowing names in DT:battery and
>>>> power_supply_property to diverge would cause confusion and wasted
>>>> time, for no particular benefit. As there is no rationale to
>>>> reconsider the names of these fields for DT:battery, let's write that
>>>> into the docs.
>>>
>>> Write it into the Linux docs then. The DT docs need to stand on their
>>> own for the standalone DT tree[1] that other projects import.
>>
>> We will document it on the Linux side. But referencing a Linux header
>> file as the origin of property names in DT;battery does not create a
>> Linux dependency for standalone DT. It merely clarifies the naming
>> scheme.
>>
>> Also a huge number of DT bindings are Linux-specific, as they are
>> implemented by some kernel driver. Do you plan to rip those out of
>> devicetree-rebasing?
>>
>
> Being implemented by a Linux kernel driver does not mean they can *only*
> every be implemented by a Linux kernel driver, U-Boot for instance takes
> drivers from Linux and so the DTs work mostly unchanged.

True, but in many cases Linux drivers have implemented a DT property
set badly. The standalone DT user might prefer to renovate vs
replicate a design flaw. Either the kernel-derived DT bindings in the
standalone tree mandate their flaws, or that tree accumulates
overlapping bindings.

> Also the biggest thing to remember is that doing something wrong before,
> doesn't justify continuing to do it wrong.

It certainly is justified if most ppl insist on continuing to do it wrong :-)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
       [not found]                       ` <CAKvHMgQujE4uYNt0vPkt6qUOtVqdvzXs0zXTkDVRq9YLNvunBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-03-18 20:34                         ` Rob Herring
  0 siblings, 0 replies; 37+ messages in thread
From: Rob Herring @ 2017-03-18 20:34 UTC (permalink / raw)
  To: Liam Breck
  Cc: Sebastian Reichel, Andrew F. Davis,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Liam Breck

On Thu, Mar 16, 2017 at 1:45 AM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
> On Wed, Mar 15, 2017 at 4:50 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Wed, Mar 15, 2017 at 5:04 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>>> On Wed, Mar 15, 2017 at 1:10 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>> On Thu, Mar 2, 2017 at 12:31 PM, Liam Breck <liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org> wrote:
>>>>> Hi Rob,
>>>>>
>>>>> On Thu, Mar 2, 2017 at 7:14 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>>>> On Sun, Feb 26, 2017 at 11:11:09PM -0800, Liam Breck wrote:
>>>>>>> From: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>>>
>>>>>>> Documentation of static battery characteristics that can be defined
>>>>>>> for batteries which cannot self-identify. This information is required
>>>>>>> by fuel-gauge and charger chips for proper handling of the battery.
>>>>>>>
>>>>>>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>>>>> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>>>>>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>>>>>> Signed-off-by: Liam Breck <kernel-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
>>>>>>> ---
>>>>>>>  .../devicetree/bindings/power/supply/battery.txt   | 42 ++++++++++++++++++++++
>>>>>>>  1 file changed, 42 insertions(+)
>>>>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>> new file mode 100644
>>>>>>> index 0000000..3d916bd
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
>>>>>>> @@ -0,0 +1,42 @@
>>>>>>> +Battery Characteristics
>>>>>>> +
>>>>>>> +Required Properties:
>>>>>>> + - compatible: Must be "fixed-battery"
>>>>>>
>>>>>> Still not liking this name, but I don't have a better suggestion. Please
>>>>>> describe here what is and isn't a "fixed battery".
>>>>>
>>>>> Sebastian...?
>>>>>
>>>>>>> +
>>>>>>> +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
>>>>>>> +
>>>>>>> +Future Properties must be named for the corresponding elements in
>>>>>>> +enum power_supply_property, defined in include/linux/power_supply.h.
>>>>>>
>>>>>> Um, no. That's exactly not how DT bindings should be done.
>>>>>
>>>>> Power supply components surface stats in sysfs using the names in enum
>>>>> power_supply_property. For example,
>>>>> /sys/class/power_supply/.../voltage_min_design. Matching input (DT)
>>>>> and output (sysfs) names is sensible. The above comment is already
>>>>> attached to struct power_supply_battery_info, which is the initial
>>>>> destination for the above DT properties.
>>>>>
>>>>> Shall I mention sysfs in the above comment?
>>>>
>>>> Absolutely not. Bindings should not reference Linux.
>>>>
>>>> While sometimes things can align, there is no guarantee that they
>>>> will. DT is h/w description. sysfs is user configuration.
>>>
>>> sysfs for power_supply also provides fixed hw characteristics.
>>>
>>> Sebastian proposed DT:battery specifically to be consumed by
>>> power_supply_core. Allowing names in DT:battery and
>>> power_supply_property to diverge would cause confusion and wasted
>>> time, for no particular benefit. As there is no rationale to
>>> reconsider the names of these fields for DT:battery, let's write that
>>> into the docs.
>>
>> Write it into the Linux docs then. The DT docs need to stand on their
>> own for the standalone DT tree[1] that other projects import.
>
> We will document it on the Linux side. But referencing a Linux header
> file as the origin of property names in DT;battery does not create a
> Linux dependency for standalone DT. It merely clarifies the naming
> scheme.

Perhaps, but it doesn't help the perception that bindings located in
the kernel tree are "kernel bindings". The policy is bindings should
stand on their own.

> Also a huge number of DT bindings are Linux-specific, as they are
> implemented by some kernel driver. Do you plan to rip those out of
> devicetree-rebasing?

Care to highlight some? I'm aware of a few cases, but hardly a "huge
number". I hear lots of complaints of bindings/dts's being Linux
specific, but no specific examples nor attempts to fix those cases.
I'd happily take patches to at least mark bad or linux specific
bindings.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2017-03-18 20:34 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-27  7:11 [PATCH v8 0/9] devicetree battery support and client bq27xxx_battery Liam Breck
2017-02-27  7:11 ` [PATCH v8 2/9] devicetree: property-units: Add uWh and uAh units Liam Breck
     [not found] ` <20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
2017-02-27  7:11   ` [PATCH v8 1/9] devicetree: power: Add battery.txt Liam Breck
     [not found]     ` <20170227071117.18934-2-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
2017-03-02 15:14       ` Rob Herring
2017-03-02 18:31         ` Liam Breck
2017-03-15 20:10           ` Rob Herring
     [not found]             ` <CAL_Jsq+8Y=GtyjVZA-suZLH+ySDshaoU9qh96BF+PeUYK3FZxg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-15 22:04               ` Liam Breck
2017-03-15 23:50                 ` Rob Herring
     [not found]                   ` <CAL_JsqJOFUSRY_KPzwNWrx4FF1_F6XNK8OfkqhqgBpxH9WrZeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-16  6:45                     ` Liam Breck
2017-03-16 13:31                       ` Andrew F. Davis
     [not found]                         ` <bb0928ce-6d29-3d09-2c5b-f4a084fe06e9-l0cyMroinI0@public.gmane.org>
2017-03-16 14:07                           ` Liam Breck
     [not found]                       ` <CAKvHMgQujE4uYNt0vPkt6qUOtVqdvzXs0zXTkDVRq9YLNvunBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-18 20:34                         ` Rob Herring
2017-02-27  7:11   ` [PATCH v8 3/9] devicetree: power: bq27xxx: Add monitored-battery documentation Liam Breck
     [not found]     ` <20170227071117.18934-4-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org>
2017-03-02 15:16       ` Rob Herring
2017-02-27  7:11 ` [PATCH v8 4/9] power: power_supply: Add power_supply_battery_info and API Liam Breck
2017-02-27  7:11 ` [PATCH v8 5/9] power: bq27xxx_battery: Define access methods to write chip registers Liam Breck
2017-02-27  7:11 ` [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id Liam Breck
2017-02-27 16:28   ` Andrew F. Davis
2017-02-27  7:11 ` [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support Liam Breck
2017-02-27 18:06   ` Andrew F. Davis
2017-02-27 20:05     ` Liam Breck
2017-02-27 21:21       ` Andrew F. Davis
2017-02-27 21:35         ` Liam Breck
2017-02-27 21:47           ` Andrew F. Davis
2017-02-27 22:14             ` Liam Breck
2017-02-27 22:37               ` Liam Breck
2017-03-01 23:09                 ` Liam Breck
2017-03-03 21:36   ` Liam Breck
2017-03-03 21:51     ` Andrew F. Davis
2017-03-03 22:04       ` Liam Breck
2017-03-03 22:07         ` Andrew F. Davis
2017-03-03 22:13           ` Liam Breck
2017-03-06 16:42             ` Andrew F. Davis
2017-03-06 20:14               ` Liam Breck
2017-02-27  7:11 ` [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory Liam Breck
2017-02-27 18:07   ` Andrew F. Davis
2017-02-27  7:11 ` [PATCH v8 9/9] power: bq27xxx_battery_i2c: Add I2C bulk read/write functions Liam Breck

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