* [PATCH v3 1/7] devicetree: power: add battery state machine documentation
[not found] ` <20170111062003.10110-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
@ 2017-01-11 6:19 ` Matt Ranostay
[not found] ` <20170111062003.10110-2-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
2017-01-13 18:33 ` Sebastian Reichel
2017-01-11 6:20 ` [PATCH v3 4/7] power: bq27xxx_battery: add BQ27425 chip id Matt Ranostay
` (2 subsequent siblings)
3 siblings, 2 replies; 13+ messages in thread
From: Matt Ranostay @ 2017-01-11 6:19 UTC (permalink / raw)
To: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: sre-DgEjT+Ai2ygdnm+yROfE0A, tony-4v6yS6AI5VpBDgjK7y7TUQ,
Matt Ranostay, Rob Herring
Documentation on battery properties that can be defined for
fine tuning fuel gauge state machines.
Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
.../devicetree/bindings/power/supply/battery.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
new file mode 100644
index 000000000000..a6ca761e0a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/battery.txt
@@ -0,0 +1,20 @@
+Battery State Machine Support
+
+Optional Properties
+ - nominal-microvolt: dead battery voltage in microvolts
+ - design-microwatt-hours: battery design mWh in microwatts
+ - design-microamp-hours: battery design mAh in microamps
+
+Example:
+
+ bat: battery@0 {
+ nominal-microvolt = <3700000>;
+ design-microwatt-hours = <5290000>;
+ design-microamp-hours = <1430000>;
+ };
+
+ charger: charger@0 {
+ ....
+ monitored-battery = <&bat>;
+ ...
+ };
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 13+ messages in thread[parent not found: <20170111062003.10110-2-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>]
* Re: [PATCH v3 1/7] devicetree: power: add battery state machine documentation
[not found] ` <20170111062003.10110-2-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
@ 2017-01-13 17:23 ` Rob Herring
0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2017-01-13 17:23 UTC (permalink / raw)
To: Matt Ranostay
Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, sre-DgEjT+Ai2ygdnm+yROfE0A,
tony-4v6yS6AI5VpBDgjK7y7TUQ
On Tue, Jan 10, 2017 at 10:19:57PM -0800, Matt Ranostay wrote:
> Documentation on battery properties that can be defined for
> fine tuning fuel gauge state machines.
>
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> ---
> .../devicetree/bindings/power/supply/battery.txt | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>
> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
> new file mode 100644
> index 000000000000..a6ca761e0a29
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
> @@ -0,0 +1,20 @@
> +Battery State Machine Support
> +
> +Optional Properties
> + - nominal-microvolt: dead battery voltage in microvolts
> + - design-microwatt-hours: battery design mWh in microwatts
mWh in microwatts?
mWh would be milliwatt-hours.
> + - design-microamp-hours: battery design mAh in microamps
ditto
> +
> +Example:
> +
> + bat: battery@0 {
No reg prop, so no unit-address.
> + nominal-microvolt = <3700000>;
> + design-microwatt-hours = <5290000>;
> + design-microamp-hours = <1430000>;
> + };
> +
> + charger: charger@0 {
> + ....
> + monitored-battery = <&bat>;
> + ...
> + };
> --
> 2.10.2
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/7] devicetree: power: add battery state machine documentation
2017-01-11 6:19 ` [PATCH v3 1/7] devicetree: power: add battery state machine documentation Matt Ranostay
[not found] ` <20170111062003.10110-2-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
@ 2017-01-13 18:33 ` Sebastian Reichel
1 sibling, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2017-01-13 18:33 UTC (permalink / raw)
To: Matt Ranostay, Rob Herring; +Cc: linux-pm, devicetree, tony
[-- Attachment #1: Type: text/plain, Size: 2012 bytes --]
Hi,
On Tue, Jan 10, 2017 at 10:19:57PM -0800, Matt Ranostay wrote:
> Documentation on battery properties that can be defined for
> fine tuning fuel gauge state machines.
>
> Cc: Rob Herring <robh@kernel.org>
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> ---
> .../devicetree/bindings/power/supply/battery.txt | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/power/supply/battery.txt
>
> diff --git a/Documentation/devicetree/bindings/power/supply/battery.txt b/Documentation/devicetree/bindings/power/supply/battery.txt
> new file mode 100644
> index 000000000000..a6ca761e0a29
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/battery.txt
> @@ -0,0 +1,20 @@
> +Battery State Machine Support
Let's also add a mandatory compatible string. This binding
is only relevant for dumb batteries, since other ones can
self-identify. I suggest
compatible = "fixed-battery"
> +Optional Properties
> + - nominal-microvolt: dead battery voltage in microvolts
> + - design-microwatt-hours: battery design mWh in microwatts
> + - design-microamp-hours: battery design mAh in microamps
I think we should mandate the property name of the phandle in the
generic binding instead of each potential fuel-gauge/charger.
Maybe something like the following paragraph:
Batteries are supposed to be referenced by chargers and/or
fuel-gauges using a phandle. The phandle's property should
be named "monitored-battery".
> +Example:
> +
> + bat: battery@0 {
> + nominal-microvolt = <3700000>;
> + design-microwatt-hours = <5290000>;
> + design-microamp-hours = <1430000>;
> + };
> +
> + charger: charger@0 {
> + ...
> + monitored-battery = <&bat>;
> + ...
> + };
Let's also add a fuel-gauge to the example to avoid any confusion
between fuel-gauge and battery.
fuel_gauge: fuel-gauge {
...
monitored-battery = <&bat>;
...
};
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 4/7] power: bq27xxx_battery: add BQ27425 chip id
[not found] ` <20170111062003.10110-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
2017-01-11 6:19 ` [PATCH v3 1/7] devicetree: power: add battery state machine documentation Matt Ranostay
@ 2017-01-11 6:20 ` Matt Ranostay
2017-01-11 6:20 ` [PATCH v3 5/7] power: bq27xxx_battery: add i2c bulk read/write functions Matt Ranostay
2017-01-11 6:20 ` [PATCH v3 7/7] power: bq27xxx_battery: add initial state machine support Matt Ranostay
3 siblings, 0 replies; 13+ messages in thread
From: Matt Ranostay @ 2017-01-11 6:20 UTC (permalink / raw)
To: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: sre-DgEjT+Ai2ygdnm+yROfE0A, tony-4v6yS6AI5VpBDgjK7y7TUQ,
Matt Ranostay
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
drivers/power/supply/bq27xxx_battery.c | 23 ++++++++++++++++++++++-
drivers/power/supply/bq27xxx_battery_i2c.c | 2 +-
include/linux/power/bq27xxx_battery.h | 3 ++-
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 7272d1e024f9..7475a5f31c53 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -259,6 +259,25 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_DCAP] = 0x3c,
[BQ27XXX_REG_AP] = 0x18,
},
+ [BQ27425] = {
+ [BQ27XXX_REG_CTRL] = 0x00,
+ [BQ27XXX_REG_TEMP] = 0x02,
+ [BQ27XXX_REG_INT_TEMP] = 0x1e,
+ [BQ27XXX_REG_VOLT] = 0x04,
+ [BQ27XXX_REG_AI] = 0x10,
+ [BQ27XXX_REG_FLAGS] = 0x06,
+ [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_NAC] = 0x08,
+ [BQ27XXX_REG_FCC] = 0x0e,
+ [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_SOC] = 0x1c,
+ [BQ27XXX_REG_DCAP] = 0x3c,
+ [BQ27XXX_REG_AP] = 0x18,
+ },
};
static enum power_supply_property bq27000_battery_props[] = {
@@ -427,6 +446,7 @@ static struct {
BQ27XXX_PROP(BQ27541, bq27541_battery_props),
BQ27XXX_PROP(BQ27545, bq27545_battery_props),
BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+ BQ27XXX_PROP(BQ27425, bq27421_battery_props),
};
static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -682,6 +702,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
case BQ27530:
case BQ27421:
+ case BQ27425:
return flags & BQ27XXX_FLAG_OT;
default:
return false;
@@ -693,7 +714,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
*/
static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
{
- if (di->chip == BQ27530 || di->chip == BQ27421)
+ if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
return flags & BQ27XXX_FLAG_UT;
return false;
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 5c5c3a6f9923..27143230839a 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -159,9 +159,9 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27742", BQ27541 },
{ "bq27545", BQ27545 },
{ "bq27421", BQ27421 },
- { "bq27425", BQ27421 },
{ "bq27441", BQ27421 },
{ "bq27621", BQ27421 },
+ { "bq27425", BQ27425 },
{},
};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index bed9557b69e7..14ecac158150 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -9,7 +9,8 @@ enum bq27xxx_chip {
BQ27530, /* bq27530, bq27531 */
BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
BQ27545, /* bq27545 */
- BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+ BQ27421, /* bq27421, bq27441, bq27621 */
+ BQ27425, /* bq27425 */
};
/**
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 5/7] power: bq27xxx_battery: add i2c bulk read/write functions
[not found] ` <20170111062003.10110-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
2017-01-11 6:19 ` [PATCH v3 1/7] devicetree: power: add battery state machine documentation Matt Ranostay
2017-01-11 6:20 ` [PATCH v3 4/7] power: bq27xxx_battery: add BQ27425 chip id Matt Ranostay
@ 2017-01-11 6:20 ` Matt Ranostay
2017-01-11 6:20 ` [PATCH v3 7/7] power: bq27xxx_battery: add initial state machine support Matt Ranostay
3 siblings, 0 replies; 13+ messages in thread
From: Matt Ranostay @ 2017-01-11 6:20 UTC (permalink / raw)
To: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: sre-DgEjT+Ai2ygdnm+yROfE0A, tony-4v6yS6AI5VpBDgjK7y7TUQ,
Matt Ranostay
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
drivers/power/supply/bq27xxx_battery_i2c.c | 62 ++++++++++++++++++++++++++++++
include/linux/power/bq27xxx_battery.h | 4 ++
2 files changed, 66 insertions(+)
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 27143230839a..89e1dfec69fc 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -68,6 +68,64 @@ 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;
+ unsigned char data[4];
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data[0] = reg;
+ if (single) {
+ data[1] = (unsigned char) value;
+ msg.len = 2;
+ } else {
+ put_unaligned_le16(value, &data[1]);
+ msg.len = 3;
+ }
+
+ msg.buf = data;
+ msg.addr = client->addr;
+ msg.flags = 0;
+
+ return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EINVAL;
+}
+
+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);
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ return i2c_smbus_read_i2c_block_data(client, reg, len, data);
+}
+
+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];
+
+ 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;
+
+ return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EINVAL;
+}
+
static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -95,7 +153,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)
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index 14ecac158150..a4c2dfbbca02 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -33,6 +33,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 {
@@ -63,6 +66,7 @@ struct bq27xxx_device_info {
struct list_head list;
struct mutex lock;
u8 *regs;
+ u8 buffer[32];
};
void bq27xxx_battery_update(struct bq27xxx_device_info *di);
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 7/7] power: bq27xxx_battery: add initial state machine support
[not found] ` <20170111062003.10110-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
` (2 preceding siblings ...)
2017-01-11 6:20 ` [PATCH v3 5/7] power: bq27xxx_battery: add i2c bulk read/write functions Matt Ranostay
@ 2017-01-11 6:20 ` Matt Ranostay
3 siblings, 0 replies; 13+ messages in thread
From: Matt Ranostay @ 2017-01-11 6:20 UTC (permalink / raw)
To: linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: sre-DgEjT+Ai2ygdnm+yROfE0A, tony-4v6yS6AI5VpBDgjK7y7TUQ,
Matt Ranostay
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
drivers/power/supply/bq27xxx_battery.c | 230 ++++++++++++++++++++++++++++++++-
1 file changed, 229 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 7475a5f31c53..edb4bc78ae4d 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -37,6 +37,7 @@
* http://www.ti.com/product/bq27621-g1
*/
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -452,6 +453,46 @@ static struct {
static DEFINE_MUTEX(bq27xxx_list_lock);
static LIST_HEAD(bq27xxx_battery_devices);
+#define BQ27XXX_TERM_V_MIN 2800
+#define BQ27XXX_TERM_V_MAX 3700
+
+#define BQ27XXX_BLOCK_DATA_CLASS 0x3E
+#define BQ27XXX_DATA_BLOCK 0x3F
+#define BQ27XXX_BLOCK_DATA 0x40
+#define BQ27XXX_BLOCK_DATA_CHECKSUM 0x60
+#define BQ27XXX_BLOCK_DATA_CONTROL 0x61
+#define BQ27XXX_SET_CFGUPDATE 0x13
+#define BQ27XXX_SOFT_RESET 0x42
+
+enum bq27xxx_dm_subclass_index {
+ BQ27XXX_DM_DESIGN_CAP = 0,
+ BQ27XXX_DM_DESIGN_ENERGY,
+ BQ27XXX_DM_TERMINATE_VOLTAGE,
+ BQ27XXX_NUM_IDX,
+};
+
+struct bq27xxx_dm_regs {
+ unsigned int subclass_id;
+ unsigned int offset;
+ char *name;
+};
+
+#define BQ27XXX_GAS_GAUGING_STATE_SUBCLASS 82
+
+static struct bq27xxx_dm_regs bq27425_dm_subclass_regs[] = {
+ { BQ27XXX_GAS_GAUGING_STATE_SUBCLASS, 12, "design-capacity" },
+ { BQ27XXX_GAS_GAUGING_STATE_SUBCLASS, 14, "design-energy" },
+ { BQ27XXX_GAS_GAUGING_STATE_SUBCLASS, 18, "terminate-voltage" },
+};
+
+static struct bq27xxx_dm_regs *bq27xxx_dm_subclass_regs[] = {
+ [BQ27425] = bq27425_dm_subclass_regs,
+};
+
+static unsigned int bq27xxx_unseal_keys[] = {
+ [BQ27425] = 0x04143672,
+};
+
static int poll_interval_param_set(const char *val, const struct kernel_param *kp)
{
struct bq27xxx_device_info *di;
@@ -496,6 +537,165 @@ 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)
+{
+ unsigned int key = bq27xxx_unseal_keys[di->chip];
+ int ret;
+
+ if (state)
+ return di->bus.write(di, BQ27XXX_REG_CTRL, 0x20, false);
+
+ ret = di->bus.write(di, BQ27XXX_REG_CTRL, (key >> 16) & 0xffff, false);
+ if (ret < 0)
+ return ret;
+
+ return di->bus.write(di, BQ27XXX_REG_CTRL, key & 0xffff, false);
+}
+
+static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,
+ int subclass)
+{
+ int ret = di->bus.write(di, BQ27XXX_REG_CTRL, 0, false);
+
+ if (ret < 0)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_BLOCK_DATA_CONTROL, 0, true);
+ if (ret < 0)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_BLOCK_DATA_CLASS, subclass, true);
+ if (ret < 0)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_DATA_BLOCK, 0, true);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(1000, 1500);
+
+ return di->bus.read_bulk(di, BQ27XXX_BLOCK_DATA,
+ (u8 *) &di->buffer, sizeof(di->buffer));
+}
+
+static int bq27xxx_battery_print_config(struct bq27xxx_device_info *di)
+{
+ struct bq27xxx_dm_regs *reg = bq27xxx_dm_subclass_regs[di->chip];
+ int ret, i;
+
+ ret = bq27xxx_battery_read_dm_block(di,
+ BQ27XXX_GAS_GAUGING_STATE_SUBCLASS);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < BQ27XXX_NUM_IDX; i++) {
+ int val;
+
+ if (reg->subclass_id != BQ27XXX_GAS_GAUGING_STATE_SUBCLASS)
+ continue;
+
+ val = be16_to_cpup((u16 *) &di->buffer[reg->offset]);
+
+ dev_info(di->dev, "settings for %s set at %d\n", reg->name, val);
+
+ reg++;
+ }
+
+ return 0;
+}
+
+static bool bq27xxx_battery_update_dm_setting(struct bq27xxx_device_info *di,
+ unsigned int reg, unsigned int val)
+{
+ struct bq27xxx_dm_regs *dm_reg = &bq27xxx_dm_subclass_regs[di->chip][reg];
+ u16 *prev = (u16 *) &di->buffer[dm_reg->offset];
+
+ if (be16_to_cpup(prev) == val)
+ return false;
+
+ *prev = cpu_to_be16(val);
+
+ return true;
+}
+
+static u8 bq27xxx_battery_checksum(struct bq27xxx_device_info *di)
+{
+ u8 *data = (u8 *) &di->buffer;
+ u16 sum = 0;
+ int i;
+
+ for (i = 0; i < sizeof(di->buffer); i++) {
+ sum += data[i];
+ sum &= 0xff;
+ }
+
+ return 0xff - sum;
+}
+
+static int bq27xxx_battery_write_nvram(struct bq27xxx_device_info *di,
+ unsigned int subclass)
+{
+ int ret;
+
+ ret = di->bus.write(di, BQ27XXX_REG_CTRL, BQ27XXX_SET_CFGUPDATE, false);
+ if (ret)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_BLOCK_DATA_CONTROL, 0, true);
+ if (ret)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_BLOCK_DATA_CLASS, subclass, true);
+ if (ret)
+ return ret;
+
+ ret = di->bus.write(di, BQ27XXX_DATA_BLOCK, 0, true);
+ if (ret)
+ return ret;
+
+ ret = di->bus.write_bulk(di, BQ27XXX_BLOCK_DATA,
+ (u8 *) &di->buffer, sizeof(di->buffer));
+ if (ret < 0)
+ return ret;
+
+ usleep_range(1000, 1500);
+
+ di->bus.write(di, BQ27XXX_BLOCK_DATA_CHECKSUM,
+ bq27xxx_battery_checksum(di), true);
+
+ usleep_range(1000, 1500);
+
+ di->bus.write(di, BQ27XXX_REG_CTRL, BQ27XXX_SOFT_RESET, false);
+
+ return 0;
+}
+
+static int bq27xxx_battery_set_config(struct bq27xxx_device_info *di,
+ struct power_supply_battery_info *info)
+{
+ int ret = bq27xxx_battery_read_dm_block(di,
+ BQ27XXX_GAS_GAUGING_STATE_SUBCLASS);
+
+ if (ret < 0)
+ return ret;
+
+ ret = bq27xxx_battery_update_dm_setting(di, BQ27XXX_DM_DESIGN_CAP,
+ info->power / 1000);
+ ret |= bq27xxx_battery_update_dm_setting(di, BQ27XXX_DM_DESIGN_ENERGY,
+ info->energy / 1000);
+ ret |= bq27xxx_battery_update_dm_setting(di, BQ27XXX_DM_TERMINATE_VOLTAGE,
+ info->nominal_voltage / 1000);
+
+ if (ret) {
+ dev_info(di->dev, "updating NVM settings\n");
+ return bq27xxx_battery_write_nvram(di,
+ BQ27XXX_GAS_GAUGING_STATE_SUBCLASS);
+ }
+
+ return 0;
+}
+
/*
* Return the battery State-of-Charge
* Or < 0 if something fails.
@@ -757,6 +957,30 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
return POWER_SUPPLY_HEALTH_GOOD;
}
+void bq27xxx_battery_settings(struct bq27xxx_device_info *di)
+{
+ struct power_supply_battery_info info = {};
+
+ /* 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_subclass_regs[di->chip])
+ return;
+
+ bq27xxx_battery_set_seal_state(di, false);
+
+ if (power_supply_get_battery_info(di->bat, &info, "monitored-battery") < 0)
+ goto out;
+
+ bq27xxx_battery_set_config(di, &info);
+
+out:
+ bq27xxx_battery_print_config(di);
+ bq27xxx_battery_set_seal_state(di, true);
+}
+
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
{
struct bq27xxx_reg_cache cache = {0, };
@@ -1039,7 +1263,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;
+
+ psy_cfg.of_node = di->dev->of_node;
+ psy_cfg.drv_data = di;
INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
mutex_init(&di->lock);
@@ -1064,6 +1291,7 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+ bq27xxx_battery_settings(di);
bq27xxx_battery_update(di);
mutex_lock(&bq27xxx_list_lock);
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 13+ messages in thread