All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] power: bq27xxx: add support for NVRAM R/W access
@ 2016-12-26  5:44 Matt Ranostay
       [not found] ` <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Ranostay @ 2016-12-26  5:44 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay

Enable access to the NVRAM for the bq27425 chipset which allows to
update the battery metrics that are used in the state machine.

This allows adjustments of a termination voltage, design energy, and
design voltage.

Matt Ranostay (3):
  bq27xxx_battery: add BQ27425 chip id
  devicetree: bq27425: add documentation for bq27425 fuel gauge
  power: bq27xxx: add support for NVRAM R/W access

 .../devicetree/bindings/power/bq27425.txt          |  25 ++
 drivers/power/supply/bq27xxx_battery.c             |  24 +-
 drivers/power/supply/bq27xxx_battery_i2c.c         | 336 ++++++++++++++++++++-
 include/linux/power/bq27xxx_battery.h              |   7 +-
 4 files changed, 388 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt

-- 
2.7.4

--
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] 6+ messages in thread

* [PATCH 1/3] bq27xxx_battery: add BQ27425 chip id
       [not found] ` <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
@ 2016-12-26  5:44   ` Matt Ranostay
  2016-12-26  5:44   ` [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge Matt Ranostay
  2016-12-26  5:44   ` [PATCH 3/3] power: bq27xxx: add support for NVRAM R/W access Matt Ranostay
  2 siblings, 0 replies; 6+ messages in thread
From: Matt Ranostay @ 2016-12-26  5:44 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay

Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
 drivers/power/supply/bq27xxx_battery.c     | 24 ++++++++++++++++++++++--
 drivers/power/supply/bq27xxx_battery_i2c.c |  2 +-
 include/linux/power/bq27xxx_battery.h      |  3 ++-
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 08c36b8e04bd..721cf6f67874 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);
@@ -677,7 +697,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
 	if (di->chip == BQ27500 || di->chip == BQ27510 ||
 	    di->chip == BQ27541 || di->chip == BQ27545)
 		return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
-	if (di->chip == BQ27530 || di->chip == BQ27421)
+	if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
 		return flags & BQ27XXX_FLAG_OT;
 
 	return false;
@@ -688,7 +708,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.7.4

--
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] 6+ messages in thread

* [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge
       [not found] ` <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
  2016-12-26  5:44   ` [PATCH 1/3] bq27xxx_battery: add BQ27425 chip id Matt Ranostay
@ 2016-12-26  5:44   ` Matt Ranostay
       [not found]     ` <20161226054442.23599-3-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
  2016-12-26  5:44   ` [PATCH 3/3] power: bq27xxx: add support for NVRAM R/W access Matt Ranostay
  2 siblings, 1 reply; 6+ messages in thread
From: Matt Ranostay @ 2016-12-26  5:44 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay

Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
 .../devicetree/bindings/power/bq27425.txt          | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt

diff --git a/Documentation/devicetree/bindings/power/bq27425.txt b/Documentation/devicetree/bindings/power/bq27425.txt
new file mode 100644
index 000000000000..f09f787a9378
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/bq27425.txt
@@ -0,0 +1,25 @@
+* TI BQ27425 Fuel Gauge
+
+http://www.ti.com/lit/ds/symlink/bq27425-g2a.pdf
+
+Please note that if any of the optional properties are defined
+then all settings must be.
+
+Required properties:
+- compatible: Should be "ti,bq27425"
+- reg: integer, i2c of the device
+
+Optional properties:
+- ti,design-capacity: integer of mAh of the battery
+- ti,design-energy: integer of the mWh of the battery
+- ti,terminate-voltage: integer of mV of the dead voltage of
+			the battery
+
+bq27425 {
+	compatible = "ti,bq27425";
+	reg = <0x55>;
+
+	ti,design-capacity = <1360>;
+	ti,design-energy = <4970>;
+	ti,terminate-voltage = <3200>;
+};
-- 
2.7.4

--
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] 6+ messages in thread

* [PATCH 3/3] power: bq27xxx: add support for NVRAM R/W access
       [not found] ` <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
  2016-12-26  5:44   ` [PATCH 1/3] bq27xxx_battery: add BQ27425 chip id Matt Ranostay
  2016-12-26  5:44   ` [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge Matt Ranostay
@ 2016-12-26  5:44   ` Matt Ranostay
  2 siblings, 0 replies; 6+ messages in thread
From: Matt Ranostay @ 2016-12-26  5:44 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay

Initial support for access and modification of the non-volatile regions
of the bq27425 fuel gauge DesignEnergy, DesignCapacity, and
TerminateVoltage settings.

This is intended for fine tuning the fuel gauge state machine for the
respective battery specifications.

Cc: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
 drivers/power/supply/bq27xxx_battery_i2c.c | 334 +++++++++++++++++++++++++++++
 include/linux/power/bq27xxx_battery.h      |   4 +
 2 files changed, 338 insertions(+)

diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 27143230839a..c6f641cd3940 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -14,9 +14,11 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <asm/unaligned.h>
 
 #include <linux/power/bq27xxx_battery.h>
@@ -24,6 +26,48 @@
 static DEFINE_IDR(battery_id);
 static DEFINE_MUTEX(battery_mutex);
 
+#define BQ27XXX_TERM_V_MIN	2800
+#define BQ27XXX_TERM_V_MAX	3700
+
+#define BQ27XXX_REG_CTRL		0
+
+#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 irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
 {
 	struct bq27xxx_device_info *di = data;
@@ -68,6 +112,288 @@ 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_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_i2c_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_i2c_print_config(struct bq27xxx_device_info *di)
+{
+	struct bq27xxx_dm_regs *reg = bq27xxx_dm_subclass_regs[di->chip];
+	int ret, i;
+
+	ret = bq27xxx_battery_i2c_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_i2c_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_i2c_set_config(struct bq27xxx_device_info *di,
+					  unsigned int cap, unsigned int energy,
+					  unsigned int voltage)
+{
+	int ret = bq27xxx_battery_i2c_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, cap);
+	ret |= bq27xxx_battery_update_dm_setting(di, BQ27XXX_DM_DESIGN_ENERGY,
+						 energy);
+	ret |= bq27xxx_battery_update_dm_setting(di, BQ27XXX_DM_TERMINATE_VOLTAGE,
+						 voltage);
+
+	if (ret) {
+		dev_info(di->dev, "updating NVM settings\n");
+		return bq27xxx_battery_i2c_write_nvram(di,
+				BQ27XXX_GAS_GAUGING_STATE_SUBCLASS);
+	}
+
+	return 0;
+}
+
+static int bq27xxx_battery_i2c_parse_dt(struct bq27xxx_device_info *di)
+{
+	struct device_node *np = di->dev->of_node;
+	int cap, energy, voltage = -EINVAL;
+	int ret = 0;
+
+	/* no settings to be set for this chipset so abort */
+	if (!bq27xxx_dm_subclass_regs[di->chip])
+		return 0;
+
+	bq27xxx_battery_i2c_set_seal_state(di, false);
+
+	if (np) {
+		ret = of_property_read_u32(np, "ti,design-capacity", &cap);
+		if (ret < 0 || cap > 0x7fff) {
+			if (!ret)
+				dev_err(di->dev,
+					"invalid ti,design-capacity %d\n",
+					cap);
+			cap = -EINVAL;
+		}
+
+		ret = of_property_read_u32(np, "ti,design-energy", &energy);
+		if (ret < 0 || energy > 0x7fff) {
+			if (!ret)
+				dev_err(di->dev,
+					"invalid ti,design-energy %d\n",
+					energy);
+			energy = -EINVAL;
+		}
+
+		ret = of_property_read_u32(np, "ti,terminate-voltage", &voltage);
+		if (ret < 0 || voltage < BQ27XXX_TERM_V_MIN
+			    || voltage > BQ27XXX_TERM_V_MAX) {
+			if (!ret)
+				dev_err(di->dev,
+					"invalid ti,terminate-voltage %d\n",
+					voltage);
+			voltage = -EINVAL;
+		}
+
+		/* assume that we want the defaults */
+		if (cap < 0 && energy < 0 && voltage < 0) {
+			ret = 0;
+			goto out;
+		}
+
+		/* we need all three settings for safety reasons */
+		if (cap < 0 || energy < 0 || voltage < 0) {
+			dev_err(di->dev,
+				"missing or invalid devicetree values; NVM not updated\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ret = bq27xxx_battery_i2c_set_config(di, cap, energy, voltage);
+	}
+
+out:
+	bq27xxx_battery_i2c_print_config(di);
+	bq27xxx_battery_i2c_set_seal_state(di, true);
+
+	return ret;
+}
+
 static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 				     const struct i2c_device_id *id)
 {
@@ -95,7 +421,15 @@ 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_i2c_parse_dt(di);
+	if (ret)
+		goto err_failed;
 
 	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..22b4cfc3acab 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 {
@@ -62,6 +65,7 @@ struct bq27xxx_device_info {
 	struct power_supply *bat;
 	struct list_head list;
 	struct mutex lock;
+	u8 buffer[32];
 	u8 *regs;
 };
 
-- 
2.7.4

--
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] 6+ messages in thread

* Re: [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge
       [not found]     ` <20161226054442.23599-3-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
@ 2017-01-03 16:47       ` Rob Herring
  2017-01-04  5:23         ` Matt Ranostay
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Herring @ 2017-01-03 16:47 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA, Sebastian Reichel,
	Tony Lindgren

On Sun, Dec 25, 2016 at 09:44:41PM -0800, Matt Ranostay wrote:
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> ---
>  .../devicetree/bindings/power/bq27425.txt          | 25 ++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/bq27425.txt b/Documentation/devicetree/bindings/power/bq27425.txt
> new file mode 100644
> index 000000000000..f09f787a9378
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/bq27425.txt
> @@ -0,0 +1,25 @@
> +* TI BQ27425 Fuel Gauge
> +
> +http://www.ti.com/lit/ds/symlink/bq27425-g2a.pdf
> +
> +Please note that if any of the optional properties are defined
> +then all settings must be.
> +
> +Required properties:
> +- compatible: Should be "ti,bq27425"
> +- reg: integer, i2c of the device

s/i2c/I2C address/

> +
> +Optional properties:
> +- ti,design-capacity: integer of mAh of the battery
> +- ti,design-energy: integer of the mWh of the battery
> +- ti,terminate-voltage: integer of mV of the dead voltage of
> +			the battery

These all need unit suffixes. mAh and mWh may need to be added to 
property-units.txt.

> +
> +bq27425 {
> +	compatible = "ti,bq27425";
> +	reg = <0x55>;
> +
> +	ti,design-capacity = <1360>;
> +	ti,design-energy = <4970>;
> +	ti,terminate-voltage = <3200>;
> +};
> -- 
> 2.7.4
> 
> --
> 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
--
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] 6+ messages in thread

* Re: [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge
  2017-01-03 16:47       ` Rob Herring
@ 2017-01-04  5:23         ` Matt Ranostay
  0 siblings, 0 replies; 6+ messages in thread
From: Matt Ranostay @ 2017-01-04  5:23 UTC (permalink / raw)
  To: Rob Herring; +Cc: devicetree, linux-pm, Sebastian Reichel, Tony Lindgren

On Tue, Jan 3, 2017 at 8:47 AM, Rob Herring <robh@kernel.org> wrote:
> On Sun, Dec 25, 2016 at 09:44:41PM -0800, Matt Ranostay wrote:
>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>> ---
>>  .../devicetree/bindings/power/bq27425.txt          | 25 ++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt
>>
>> diff --git a/Documentation/devicetree/bindings/power/bq27425.txt b/Documentation/devicetree/bindings/power/bq27425.txt
>> new file mode 100644
>> index 000000000000..f09f787a9378
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/bq27425.txt
>> @@ -0,0 +1,25 @@
>> +* TI BQ27425 Fuel Gauge
>> +
>> +http://www.ti.com/lit/ds/symlink/bq27425-g2a.pdf
>> +
>> +Please note that if any of the optional properties are defined
>> +then all settings must be.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,bq27425"
>> +- reg: integer, i2c of the device
>
> s/i2c/I2C address/
>
>> +
>> +Optional properties:
>> +- ti,design-capacity: integer of mAh of the battery
>> +- ti,design-energy: integer of the mWh of the battery
>> +- ti,terminate-voltage: integer of mV of the dead voltage of
>> +                     the battery
>
> These all need unit suffixes. mAh and mWh may need to be added to
> property-units.txt.

Ok makes sense.

>
>> +
>> +bq27425 {
>> +     compatible = "ti,bq27425";
>> +     reg = <0x55>;
>> +
>> +     ti,design-capacity = <1360>;
>> +     ti,design-energy = <4970>;
>> +     ti,terminate-voltage = <3200>;
>> +};
>> --
>> 2.7.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2017-01-04  5:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-26  5:44 [PATCH 0/3] power: bq27xxx: add support for NVRAM R/W access Matt Ranostay
     [not found] ` <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
2016-12-26  5:44   ` [PATCH 1/3] bq27xxx_battery: add BQ27425 chip id Matt Ranostay
2016-12-26  5:44   ` [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge Matt Ranostay
     [not found]     ` <20161226054442.23599-3-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
2017-01-03 16:47       ` Rob Herring
2017-01-04  5:23         ` Matt Ranostay
2016-12-26  5:44   ` [PATCH 3/3] power: bq27xxx: add support for NVRAM R/W access Matt Ranostay

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