devicetree battery support and client bq27xxx_battery
Subsystems (4)
v8 cover devicetree battery support and client bq27xxx_battery
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
Signature · 1 line
2.9.3
A message that is not in the archive (sent off-list or not yet received): 20170227071117.18934-1-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org
PATCH v8 1/9 devicetree: power: Add battery.txt
From: Liam Breck <[email protected]>
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.
--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
Documentation/devicetree/bindings/power/supply/battery.txt new file +42 -0
@@ -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>; + ... + };
Signature · 6 lines
2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170227071117.18934-2-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 21 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtDocumentation/devicetree/bindings/power/supply/battery.txt new file +0
-0
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 4 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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".
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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.
Quoted 33 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +30
-0+ +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>; + ... + };Signature · 1 line
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
Quoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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?
Quoted 25 lines
Quoted 25 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +25
-0+ +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>; + ... + }; +
Quoted 8 lines
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +5
-1+ 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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Rob Herring
maintainerRe: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 46 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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.
Quoted 8 lines
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 structpower_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
A message that is not in the archive (sent off-list or not yet received): CAL_Jsq+8Y=GtyjVZA-suZLH+ySDshaoU9qh96BF+PeUYK3FZxg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.
Quoted 6 lines
Quoted 1 line
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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Rob Herring
maintainerRe: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 62 lines · Liam Breck
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.Quoted 6 lines
Quoted 1 line
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.
Quoted 8 lines
sysfs for
power_supplyalso provides fixed hw characteristics.Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery andpower_supply_propertyto 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/
A message that is not in the archive (sent off-list or not yet received): CAL_JsqJOFUSRY_KPzwNWrx4FF1_F6XNK8OfkqhqgBpxH9WrZeQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 72 lines · Rob Herring
Quoted 62 lines · Liam Breck
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.Quoted 6 lines
Quoted 1 line
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.
Quoted 8 lines
sysfs for
power_supplyalso provides fixed hw characteristics.Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery andpower_supply_propertyto 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.
Quoted 2 lines
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?
Quoted 1 line
[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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 76 lines · Liam Breck
Quoted 72 lines · Rob Herring
Quoted 62 lines · Liam Breck
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.Quoted 6 lines
Quoted 1 line
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.
Quoted 8 lines
sysfs for
power_supplyalso provides fixed hw characteristics.Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery andpower_supply_propertyto 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.Quoted 2 lines
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.
Quoted 9 lines
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.
Quoted 1 line
A message that is not in the archive (sent off-list or not yet received): bb0928ce-6d29-3d09-2c5b-f4a084fe06e9-l0cyMroinI0@public.gmane.org
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 82 lines · Andrew F. Davis
Quoted 81 lines · Liam Breck
Quoted 72 lines · Rob Herring
Quoted 62 lines · Liam Breck
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.Quoted 6 lines
Quoted 1 line
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.
Quoted 8 lines
sysfs for
power_supplyalso provides fixed hw characteristics.Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery andpower_supply_propertyto 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.Quoted 2 lines
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.
Quoted 8 lines
Quoted 4 lines
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.
Quoted 2 lines
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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): CAKvHMgQujE4uYNt0vPkt6qUOtVqdvzXs0zXTkDVRq9YLNvunBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Re: [PATCH v8 1/9] devicetree: power: Add battery.txt
Quoted 73 lines · Liam Breck
Quoted 72 lines · Rob Herring
Quoted 70 lines · Liam Breck
Quoted 54 lines · Rob Herring
Quoted 53 lines · Liam Breck
Hi Rob,
Quoted 16 lines · Rob Herring
Quoted 15 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- .../devicetree/bindings/power/supply/battery.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txtQuoted 13 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 4
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +4
-0@@ -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...?
Quoted 10 lines
Documentation/devicetree/bindings/power/supply/battery.txt line 12
Quoted 8 lines
Documentation/devicetree/bindings/power/supply/battery.txt new file +8
-0+ +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 structpower_supply_battery_info, which is the initial destination for the above DT properties.Quoted 6 lines
Quoted 1 line
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_supplyalso provides fixed hw characteristics.Sebastian proposed DT:battery specifically to be consumed by
power_supply_core. Allowing names in DT:battery andpower_supply_propertyto 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.
Quoted 7 lines
Quoted 2 lines
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.
Quoted 3 lines
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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v8 3/9 devicetree: power: bq27xxx: Add monitored-battery documentation
In reply to a message not in the archiveFrom: Liam Breck <[email protected]>
Document monitored-battery = <&battery_node>
--- Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/power/supply/bq27xxx.txt +10 -1
@@ -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>; };
Signature · 6 lines
2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170227071117.18934-4-liam-RYWXG+zxWwBdeoIcmNTgJF6hYfS7NtTn@public.gmane.org
Rob Herring
Acked-byRe: [PATCH v8 3/9] devicetree: power: bq27xxx: Add monitored-battery documentation
Quoted 11 lines · Liam Breck
From: Liam Breck <[email protected]>
Document monitored-battery = <
&battery_node>Cc Rob Herring <[email protected]>Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>--- Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v8 2/9 devicetree: property-units: Add uWh and uAh units
In reply to Liam BreckFrom: Matt Ranostay <[email protected]>
Add entries for microwatt-hours and microamp-hours.
--- Documentation/devicetree/bindings/property-units.txt | 2 ++ 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/property-units.txt +2 -0
@@ -25,8 +25,10 @@ Distance Electricity ---------------------------------------- -microamp : micro amps +-microamp-hours : micro amp-hours -ohms : Ohms -micro-ohms : micro Ohms +-microwatt-hours: micro Watt-hours -microvolt : micro volts Temperature
Signature · 1 line
2.9.3
PATCH v8 4/9 power: power_supply: Add power_supply_battery_info and API
In reply to Liam BreckFrom: Liam Breck <[email protected]>
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.
--- drivers/power/supply/power_supply_core.c | 40 ++++++++++++++++++++++++++++++++ include/linux/power_supply.h | 18 ++++++++++++++ 2 files changed, 58 insertions(+)
drivers/power/supply/power_supply_core.c +40 -0
@@ -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)
include/linux/power_supply.h +18 -0
@@ -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);
Signature · 1 line
2.9.3
PATCH v8 5/9 power: bq27xxx_battery: Define access methods to write chip registers
In reply to Liam BreckFrom: Matt Ranostay <[email protected]>
write(), read_bulk(), write_bulk() support setting chip registers, e.g. with data obtained from power_supply_battery_info.
--- include/linux/power/bq27xxx_battery.h | 3 +++ 1 file changed, 3 insertions(+)
include/linux/power/bq27xxx_battery.h +3 -0
@@ -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 {
Signature · 1 line
2.9.3
PATCH v8 6/9 power: bq27xxx_battery: Add BQ27425 chip id
In reply to Liam BreckFrom: Matt Ranostay <[email protected]>
This patch does not alter the function of the driver. This chip ID is referenced in the devicetree code.
--- 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(-)
drivers/power/supply/bq27xxx_battery.c +22 -1
@@ -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;
drivers/power/supply/bq27xxx_battery_i2c.c +1 -1
@@ -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 }, {},
include/linux/power/bq27xxx_battery.h +2 -1
@@ -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 */ };/**
Signature · 1 line
2.9.3
Re: [PATCH v8 6/9] power: bq27xxx_battery: Add BQ27425 chip id
Quoted 7 lines · Liam Breck
From: Matt Ranostay <[email protected]>
This patch does not alter the function of the driver. This chip ID is referenced in the devicetree code.
Signed-off-by Matt Ranostay <[email protected]>Signed-off-by Liam Breck <[email protected]>
I think I already acked this one..
Quoted 89 lines
--- 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(-)drivers/power/supply/bq27xxx_battery.c +22
-1@@ -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;drivers/power/supply/bq27xxx_battery_i2c.c +1
-1@@ -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 }, {},include/linux/power/bq27xxx_battery.h +2
-1@@ -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 */ };/**
PATCH v8 7/9 power: bq27xxx_battery: Add power_supply_battery_info support
In reply to Liam BreckFrom: Liam Breck <[email protected]>
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.
--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)
drivers/power/supply/bq27xxx_battery.c +456 -2
@@ -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);
Signature · 1 line
2.9.3
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() */
/* Data Class */
etc..
Quoted 103 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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 ,
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 335
Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c +5
-0@@ -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 :)
Quoted 58 lines
drivers/power/supply/bq27xxx_battery.c +51
-0}, };@@ -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 */
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 10 lines
drivers/power/supply/bq27xxx_battery.c +10
-0+ [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.
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 365 lines
drivers/power/supply/bq27xxx_battery.c +332
-1+ +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);
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,
Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 311
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};
Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 267 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 311
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 5 lines
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
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 274 lines · Andrew F. Davis
Quoted 267 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 311
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 5 lines
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.
Quoted 3 lines
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 :-)
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 275 lines · Liam Breck
Quoted 274 lines · Andrew F. Davis
Quoted 272 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 311
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 6 lines
Quoted 3 lines
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
Quoted 2 lines
Thanks :-)
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 287 lines · Andrew F. Davis
Quoted 275 lines · Liam Breck
Quoted 274 lines · Andrew F. Davis
Quoted 272 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 311
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 6 lines
Quoted 3 lines
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).
Quoted 6 lines
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.
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 295 lines · Liam Breck
Quoted 287 lines · Andrew F. Davis
Quoted 275 lines · Liam Breck
Quoted 274 lines · Andrew F. Davis
Quoted 272 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 335
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 6 lines
Quoted 3 lines
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).
Quoted 6 lines
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.
Quoted 3 lines
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.
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 313 lines · Liam Breck
Quoted 295 lines · Liam Breck
Quoted 287 lines · Andrew F. Davis
Quoted 275 lines · Liam Breck
Quoted 274 lines · Andrew F. Davis
Quoted 272 lines · Liam Breck
Quoted 56 lines · Andrew F. Davis
Quoted 48 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +7
-1@@ -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 */ drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 111
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +1
-0@@ -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 */
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c enum bq27xxx_reg_index { · line 112
Quoted 1 line
drivers/power/supply/bq27xxx_battery.c +1
-0+ BQ27XXX_DM_CLASS, /* DataClass() *//* Data Class */
I used the terms from the docs, so a search will find meaningful results.
Quoted 105 lines
Quoted 105 lines
drivers/power/supply/bq27xxx_battery.c +43
-0+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,Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = { · line 335
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +5
-0[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 :-/
Quoted 62 lines
Quoted 62 lines
drivers/power/supply/bq27xxx_battery.c +55
-0}, };@@ -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 }, +};Quoted 8 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 571
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +//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.
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 577
Quoted 6 lines
drivers/power/supply/bq27xxx_battery.c +6
-0+ +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.
Quoted 6 lines
Quoted 3 lines
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).
Quoted 6 lines
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.
Quoted 3 lines
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_resetcommands:
BQ27... 421, 425, 441, 621Docs for 421 & 441 mention OTP memory
Docs for 621 do not mention OTP
Docs for 425 mention rewritable NVMWhat is in OTP on 421 & 441?
Is anything in OTP on 621?
Is anything in OTP on 425?
Quoted 5 lines
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.
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
In reply to Liam BreckHi Andrew,
Quoted 86 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +63
-0@@ -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[] = {
drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 10 lines
drivers/power/supply/bq27xxx_battery.c +10
-0+ [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?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 96 lines · Liam Breck
Hi Andrew,
Quoted 93 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +70
-0@@ -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 */
Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c +3
-0+ [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.
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 107 lines · Andrew F. Davis
Quoted 96 lines · Liam Breck
Hi Andrew,
Quoted 93 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +70
-0@@ -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 */ Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c +3
-0+ [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
Quoted 3 lines
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.
Quoted 11 lines
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 108 lines · Liam Breck
Quoted 107 lines · Andrew F. Davis
Quoted 105 lines · Liam Breck
Hi Andrew,
Quoted 86 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +63
-0@@ -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[] = {drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 10 lines
drivers/power/supply/bq27xxx_battery.c +10
-0+ [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
Quoted 7 lines
Quoted 3 lines
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.cisn'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.
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 113 lines · Andrew F. Davis
Quoted 112 lines · Liam Breck
Quoted 110 lines · Andrew F. Davis
Quoted 96 lines · Liam Breck
Hi Andrew,
Quoted 93 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +70
-0@@ -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 */ Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c +3
-0+ [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.
Quoted 6 lines
Quoted 3 lines
OK but suppose kernel builders define a dm_regs{} when it's missing. Doing that in
bq27xxx_battery.cisn'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? :-)
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 118 lines · Liam Breck
Quoted 117 lines · Andrew F. Davis
Quoted 115 lines · Liam Breck
Quoted 107 lines · Andrew F. Davis
Quoted 96 lines · Liam Breck
Hi Andrew,
Quoted 93 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +70
-0@@ -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 */ Quoted 9 lines
drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 3 lines
drivers/power/supply/bq27xxx_battery.c +3
-0+ [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
Quoted 3 lines
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.cisn't ideal.
Quoted 6 lines
Quoted 2 lines
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_regstables 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 :)
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
Re: [PATCH v8 7/9] power: bq27xxx_battery: Add power_supply_battery_info support
Quoted 122 lines · Andrew F. Davis
Quoted 121 lines · Liam Breck
Quoted 119 lines · Andrew F. Davis
Quoted 108 lines · Liam Breck
Quoted 107 lines · Andrew F. Davis
Quoted 105 lines · Liam Breck
Hi Andrew,
Quoted 86 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>Signed-off-by Liam Breck <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 458 ++++++++++++++++++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-)drivers/power/supply/bq27xxx_battery.c +63
-0@@ -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[] = {drivers/power/supply/bq27xxx_battery.c static struct { · line 583
Quoted 10 lines
drivers/power/supply/bq27xxx_battery.c +10
-0+ [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
Quoted 7 lines
Quoted 3 lines
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.cisn'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.
Quoted 6 lines
Quoted 3 lines
Are you going to comb thru the manuals for all the supported parts, assemble
dm_regstables 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.
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines
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.
Quoted 2 lines
Thoughts?
PATCH v8 8/9 power: bq27xxx_battery: Add print_dm_blocks() to log chip memory
In reply to Liam BreckFrom: Liam Breck <[email protected]>
Enable listing of chip RAM and/or NVM at startup, for debugging use. Intially supports BQ27425. Support for other chips may be added.
--- drivers/power/supply/bq27xxx_battery.c | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
drivers/power/supply/bq27xxx_battery.c +70 -0
@@ -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); }
Signature · 1 line
2.9.3
Re: [PATCH v8 8/9] power: bq27xxx_battery: Add print_dm_blocks() to log chip memory
Quoted 90 lines · Liam Breck
From: Liam Breck <[email protected]>
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 <[email protected]>--- drivers/power/supply/bq27xxx_battery.c | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)drivers/power/supply/bq27xxx_battery.c +68
-0@@ -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,
drivers/power/supply/bq27xxx_battery.c void bq27xxx_battery_settings(struct bq27xxx_device_info *di) · line 1008
Quoted 5 lines
drivers/power/supply/bq27xxx_battery.c +2
-0@@ -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
Quoted 4 lines
drivers/power/supply/bq27xxx_battery.c +0
-0bq27xxx_battery_set_seal_state (di, true); }
PATCH v8 9/9 power: bq27xxx_battery_i2c: Add I2C bulk read/write functions
In reply to Liam BreckFrom: Matt Ranostay <[email protected]>
write(), read_bulk(), write_bulk() are required by bq27xxx_battery devicetree code.
--- drivers/power/supply/bq27xxx_battery_i2c.c | 82 +++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-)
drivers/power/supply/bq27xxx_battery_i2c.c +81 -1
@@ -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)
Signature · 1 line
2.9.3