All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944
@ 2017-07-16  9:32 Ladislav Michl
  2017-07-16  9:33 ` [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for " Ladislav Michl
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Ladislav Michl @ 2017-07-16  9:32 UTC (permalink / raw)
  To: linux-pm-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Looijmans, Dragos Bogdan, Javier Martinez Canillas,
	Sebastian Reichel, Rob Herring, Mark Rutland

This is the 6th version of patch.
Changelog:
- v2: reworked voltage computing to not overflow and keep precision
- v3: update devicetree binding documentation
- v4: add ltc2942 devicetree compatible
- v5: reworked to incorporate Dragos' LTC2944 patch
- v6: fix missing break in the switch statement, move LTC2942 and LTC2944
      id definitions into respective patches
 
LTC2942 is pin compatible with LTC2941 providing few more registers
holding information about battery voltage and temperature. It can
be runtime detected using bit A7 in the Status register.

LTC2944 is compatible with LTC2943, but uses different
voltage and current computing constants.

Comments welcome,
	ladis
--
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] 9+ messages in thread

* [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for LTC2942 and LTC2944
  2017-07-16  9:32 [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Ladislav Michl
@ 2017-07-16  9:33 ` Ladislav Michl
  2017-07-17 14:52   ` Bogdan, Dragos
  2017-07-16  9:34 ` [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support Ladislav Michl
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Ladislav Michl @ 2017-07-16  9:33 UTC (permalink / raw)
  To: linux-pm, devicetree
  Cc: Mike Looijmans, Dragos Bogdan, Javier Martinez Canillas,
	Sebastian Reichel, Rob Herring, Mark Rutland

In order to support LTC2942 which has temperature registers
at different offsets than LTC2943 use following register naming
scheme (prefixes):
- LTC294X_ common registers
- LTC2942_ chips specific registers
- LTC2943_ specific registers

LTC2944 is compatible with LTC2943 but uses different constants
to compute voltage and current, so replace num_regs misused
for device indentification with real device id to discriminate
between those two.

There are no functional changes.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 - v2: None
 - v3: Extend commit message
 - v4: None
 - v5: Count on LTC2944 too
 - v6: Move LTC2942 and LTC2944 to respective patches

 drivers/power/supply/ltc2941-battery-gauge.c | 63 ++++++++++++++--------------
 1 file changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index 7efb908f4451..b0de448a226b 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -34,16 +34,19 @@ enum ltc294x_reg {
 	LTC294X_REG_CONTROL		= 0x01,
 	LTC294X_REG_ACC_CHARGE_MSB	= 0x02,
 	LTC294X_REG_ACC_CHARGE_LSB	= 0x03,
-	LTC294X_REG_THRESH_HIGH_MSB	= 0x04,
-	LTC294X_REG_THRESH_HIGH_LSB	= 0x05,
-	LTC294X_REG_THRESH_LOW_MSB	= 0x06,
-	LTC294X_REG_THRESH_LOW_LSB	= 0x07,
-	LTC294X_REG_VOLTAGE_MSB	= 0x08,
-	LTC294X_REG_VOLTAGE_LSB	= 0x09,
-	LTC294X_REG_CURRENT_MSB	= 0x0E,
-	LTC294X_REG_CURRENT_LSB	= 0x0F,
-	LTC294X_REG_TEMPERATURE_MSB	= 0x14,
-	LTC294X_REG_TEMPERATURE_LSB	= 0x15,
+	LTC294X_REG_VOLTAGE_MSB		= 0x08,
+	LTC294X_REG_VOLTAGE_LSB		= 0x09,
+	LTC2942_REG_TEMPERATURE_MSB	= 0x0C,
+	LTC2942_REG_TEMPERATURE_LSB	= 0x0D,
+	LTC2943_REG_CURRENT_MSB		= 0x0E,
+	LTC2943_REG_CURRENT_LSB		= 0x0F,
+	LTC2943_REG_TEMPERATURE_MSB	= 0x14,
+	LTC2943_REG_TEMPERATURE_LSB	= 0x15,
+};
+
+enum ltc294x_id {
+	LTC2941_ID,
+	LTC2943_ID,
 };
 
 #define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
@@ -54,15 +57,12 @@ enum ltc294x_reg {
 	((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED	0
 
-#define LTC2941_NUM_REGS	0x08
-#define LTC2943_NUM_REGS	0x18
-
 struct ltc294x_info {
 	struct i2c_client *client;	/* I2C Client pointer */
 	struct power_supply *supply;	/* Supply pointer */
 	struct power_supply_desc supply_desc;	/* Supply description */
 	struct delayed_work work;	/* Work scheduler */
-	unsigned long num_regs;	/* Number of registers (chip type) */
+	enum ltc294x_id id;		/* Chip type */
 	int charge;	/* Last charge register content */
 	int r_sense;	/* mOhm */
 	int Qlsb;	/* nAh */
@@ -146,7 +146,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
 	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
 				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
 	/* Put the 2943 into "monitor" mode, so it measures every 10 sec */
-	if (info->num_regs == LTC2943_NUM_REGS)
+	if (info->id == LTC2941_ID)
 		control |= LTC2943_REG_CONTROL_MODE_SCAN;
 
 	if (value != control) {
@@ -263,7 +263,7 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
 	s32 value;
 
 	ret = ltc294x_read_regs(info->client,
-		LTC294X_REG_CURRENT_MSB, &datar[0], 2);
+		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
 	value = (datar[0] << 8) | datar[1];
 	value -= 0x7FFF;
 	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
@@ -280,7 +280,7 @@ static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
 	u32 value;
 
 	ret = ltc294x_read_regs(info->client,
-		LTC294X_REG_TEMPERATURE_MSB, &datar[0], 2);
+		LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2);
 	value = (datar[0] << 8) | datar[1];
 	/* Full-scale is 510 Kelvin, convert to centidegrees  */
 	*val = (((51000 * value) / 0xFFFF) - 27215);
@@ -357,8 +357,8 @@ static enum power_supply_property ltc294x_properties[] = {
 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
-	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
 };
 
 static int ltc294x_i2c_remove(struct i2c_client *client)
@@ -388,7 +388,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 
 	np = of_node_get(client->dev.of_node);
 
-	info->num_regs = (unsigned long)of_device_get_match_data(&client->dev);
+	info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
 	info->supply_desc.name = np->name;
 
 	/* r_sense can be negative, when sense+ is connected to the battery
@@ -409,7 +409,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 		prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
 	}
 
-	if (info->num_regs == LTC2943_NUM_REGS) {
+	if (info->id == LTC2943_ID) {
 		if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
 			prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
 		info->Qlsb = ((340 * 50000) / r_sense) /
@@ -424,18 +424,17 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 	info->client = client;
 	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
 	info->supply_desc.properties = ltc294x_properties;
-	if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB)
+	switch (info->id) {
+	case LTC2943_ID:
 		info->supply_desc.num_properties =
 			ARRAY_SIZE(ltc294x_properties);
-	else if (info->num_regs >= LTC294X_REG_CURRENT_LSB)
-		info->supply_desc.num_properties =
-			ARRAY_SIZE(ltc294x_properties) - 1;
-	else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB)
-		info->supply_desc.num_properties =
-			ARRAY_SIZE(ltc294x_properties) - 2;
-	else
+		break;
+	case LTC2941_ID:
+	default:
 		info->supply_desc.num_properties =
 			ARRAY_SIZE(ltc294x_properties) - 3;
+		break;
+	}
 	info->supply_desc.get_property = ltc294x_get_property;
 	info->supply_desc.set_property = ltc294x_set_property;
 	info->supply_desc.property_is_writeable = ltc294x_property_is_writeable;
@@ -492,8 +491,8 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
 
 
 static const struct i2c_device_id ltc294x_i2c_id[] = {
-	{"ltc2941", LTC2941_NUM_REGS},
-	{"ltc2943", LTC2943_NUM_REGS},
+	{ "ltc2941", LTC2941_ID, },
+	{ "ltc2943", LTC2943_ID, },
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
@@ -501,11 +500,11 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
 static const struct of_device_id ltc294x_i2c_of_match[] = {
 	{
 		.compatible = "lltc,ltc2941",
-		.data = (void *)LTC2941_NUM_REGS
+		.data = (void *)LTC2941_ID,
 	},
 	{
 		.compatible = "lltc,ltc2943",
-		.data = (void *)LTC2943_NUM_REGS
+		.data = (void *)LTC2943_ID,
 	},
 	{ },
 };
-- 
2.11.0

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

* [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support
  2017-07-16  9:32 [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Ladislav Michl
  2017-07-16  9:33 ` [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for " Ladislav Michl
@ 2017-07-16  9:34 ` Ladislav Michl
  2017-07-17 14:53   ` Bogdan, Dragos
  2017-07-16  9:35 ` [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support Ladislav Michl
  2017-07-25 10:20 ` [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Sebastian Reichel
  3 siblings, 1 reply; 9+ messages in thread
From: Ladislav Michl @ 2017-07-16  9:34 UTC (permalink / raw)
  To: linux-pm-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Looijmans, Dragos Bogdan, Javier Martinez Canillas,
	Sebastian Reichel, Rob Herring, Mark Rutland

LTC2942 is pin compatible with LTC2941 providing additional
informations about battery voltage and temperature. It can
be runtime detected using bit A7 in the Status register.

Signed-off-by: Ladislav Michl <ladis-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 Changes:
 - v2: reworked voltage computing to not overflow and keep presision
 - v3: update devicetree binding documentation
 - v4: add ltc2942 devicetree compatible
 - v5: make use of info->id introduced in previous patch
 - v6: collect devicetree ack from Rob

 .../devicetree/bindings/power/supply/ltc2941.txt   | 15 ++--
 drivers/power/supply/ltc2941-battery-gauge.c       | 80 ++++++++++++++++++----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
index a9d7aa60558b..8ec10366295d 100644
--- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
+++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
@@ -1,13 +1,14 @@
-binding for LTC2941 and LTC2943 battery gauges
+binding for LTC2941, LTC2942 and LTC2943 battery gauges
 
-Both the LTC2941 and LTC2943 measure battery capacity.
-The LTC2943 is compatible with the LTC2941, it adds voltage and
-temperature monitoring, and uses a slightly different conversion
-formula for the charge counter.
+All chips measure battery capacity.
+The LTC2942 is pin compatible with the LTC2941, it adds voltage and
+temperature monitoring, and is runtime detected. LTC2943 is software
+compatible, uses a slightly different conversion formula for the
+charge counter and adds voltage, current and temperature monitoring.
 
 Required properties:
-- compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also
-    indicates the type of I2C chip attached.
+- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942" or "lltc,ltc2943"
+    which also indicates the type of I2C chip attached.
 - reg: The 7-bit I2C address.
 - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit
     negative value when the battery has been connected to the wrong end of the
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index b0de448a226b..42ff4e3daf35 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -1,5 +1,5 @@
 /*
- * I2C client/driver for the Linear Technology LTC2941 and LTC2943
+ * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943
  * Battery Gas Gauge IC
  *
  * Copyright (C) 2014 Topic Embedded Systems
@@ -46,11 +46,14 @@ enum ltc294x_reg {
 
 enum ltc294x_id {
 	LTC2941_ID,
+	LTC2942_ID,
 	LTC2943_ID,
 };
 
-#define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
-#define LTC2943_REG_CONTROL_MODE_SCAN BIT(7)
+#define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
+
+#define LTC2942_REG_CONTROL_MODE_SCAN	(BIT(7) | BIT(6))
+#define LTC2943_REG_CONTROL_MODE_SCAN	BIT(7)
 #define LTC294X_REG_CONTROL_PRESCALER_MASK	(BIT(5) | BIT(4) | BIT(3))
 #define LTC294X_REG_CONTROL_SHUTDOWN_MASK	(BIT(0))
 #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
@@ -145,9 +148,17 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
 
 	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
 				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
-	/* Put the 2943 into "monitor" mode, so it measures every 10 sec */
-	if (info->id == LTC2941_ID)
+	/* Put device into "monitor" mode */
+	switch (info->id) {
+	case LTC2942_ID:	/* 2942 measures every 2 sec */
+		control |= LTC2942_REG_CONTROL_MODE_SCAN;
+		break;
+	case LTC2943_ID:	/* 2943 measures every 10 sec */
 		control |= LTC2943_REG_CONTROL_MODE_SCAN;
+		break;
+	default:
+		break;
+	}
 
 	if (value != control) {
 		ret = ltc294x_write_regs(info->client,
@@ -252,7 +263,19 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
 	ret = ltc294x_read_regs(info->client,
 		LTC294X_REG_VOLTAGE_MSB, &datar[0], 2);
 	value = (datar[0] << 8) | datar[1];
-	*val = ((value * 23600) / 0xFFFF) * 1000; /* in uV */
+	switch (info->id) {
+	case LTC2943_ID:
+		value *= 23600 * 2;
+		value /= 0xFFFF;
+		value *= 1000 / 2;
+		break;
+	default:
+		value *= 6000 * 10;
+		value /= 0xFFFF;
+		value *= 1000 / 10;
+		break;
+	}
+	*val = value;
 	return ret;
 }
 
@@ -275,15 +298,22 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
 
 static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
 {
+	enum ltc294x_reg reg;
 	int ret;
 	u8 datar[2];
 	u32 value;
 
-	ret = ltc294x_read_regs(info->client,
-		LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2);
-	value = (datar[0] << 8) | datar[1];
-	/* Full-scale is 510 Kelvin, convert to centidegrees  */
-	*val = (((51000 * value) / 0xFFFF) - 27215);
+	if (info->id == LTC2942_ID) {
+		reg = LTC2942_REG_TEMPERATURE_MSB;
+		value = 60000;	/* Full-scale is 600 Kelvin */
+	} else {
+		reg = LTC2943_REG_TEMPERATURE_MSB;
+		value = 51000;	/* Full-scale is 510 Kelvin */
+	}
+	ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
+	value *= (datar[0] << 8) | datar[1];
+	/* Convert to centidegrees  */
+	*val = value / 0xFFFF - 27215;
 	return ret;
 }
 
@@ -375,10 +405,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 {
 	struct power_supply_config psy_cfg = {};
 	struct ltc294x_info *info;
+	struct device_node *np;
 	int ret;
 	u32 prescaler_exp;
 	s32 r_sense;
-	struct device_node *np;
+	u8 status;
 
 	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (info == NULL)
@@ -421,6 +452,20 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 				(128 / (1 << prescaler_exp));
 	}
 
+	/* Read status register to check for LTC2942 */
+	if (info->id == LTC2941_ID || info->id == LTC2942_ID) {
+		ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1);
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"Could not read status register\n");
+			return ret;
+		}
+		if (status & LTC2941_REG_STATUS_CHIP_ID)
+			info->id = LTC2941_ID;
+		else
+			info->id = LTC2942_ID;
+	}
+
 	info->client = client;
 	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
 	info->supply_desc.properties = ltc294x_properties;
@@ -429,6 +474,10 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 		info->supply_desc.num_properties =
 			ARRAY_SIZE(ltc294x_properties);
 		break;
+	case LTC2942_ID:
+		info->supply_desc.num_properties =
+			ARRAY_SIZE(ltc294x_properties) - 1;
+		break;
 	case LTC2941_ID:
 	default:
 		info->supply_desc.num_properties =
@@ -492,6 +541,7 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
 
 static const struct i2c_device_id ltc294x_i2c_id[] = {
 	{ "ltc2941", LTC2941_ID, },
+	{ "ltc2942", LTC2942_ID, },
 	{ "ltc2943", LTC2943_ID, },
 	{ },
 };
@@ -503,6 +553,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
 		.data = (void *)LTC2941_ID,
 	},
 	{
+		.compatible = "lltc,ltc2942",
+		.data = (void *)LTC2942_ID,
+	},
+	{
 		.compatible = "lltc,ltc2943",
 		.data = (void *)LTC2943_ID,
 	},
@@ -524,5 +578,5 @@ module_i2c_driver(ltc294x_driver);
 
 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
-MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
+MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0

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

* [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support
  2017-07-16  9:32 [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Ladislav Michl
  2017-07-16  9:33 ` [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for " Ladislav Michl
  2017-07-16  9:34 ` [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support Ladislav Michl
@ 2017-07-16  9:35 ` Ladislav Michl
  2017-07-17 14:55   ` Bogdan, Dragos
  2017-07-17 19:42   ` Rob Herring
  2017-07-25 10:20 ` [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Sebastian Reichel
  3 siblings, 2 replies; 9+ messages in thread
From: Ladislav Michl @ 2017-07-16  9:35 UTC (permalink / raw)
  To: linux-pm, devicetree
  Cc: Mike Looijmans, Dragos Bogdan, Javier Martinez Canillas,
	Sebastian Reichel, Rob Herring, Mark Rutland

From: Dragos Bogdan <dragos.bogdan@analog.com>

LTC2944 is compatible with LTC2943, but uses different
voltage and current computing constants.

Signed-off-by: Dragos Bogdan <dragos.bogdan@analog.com>
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 - v2: fixed voltage and current conversion
 - v3: skipped
 - v4: skipped
 - v5: fixed voltage conversion overflow, rebased on LTC2942 patchset
 - v6: fix missing break in the switch statement

 .../devicetree/bindings/power/supply/ltc2941.txt   | 12 +++++-----
 drivers/power/supply/ltc2941-battery-gauge.c       | 27 ++++++++++++++++++----
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
index 8ec10366295d..3b9ba147b041 100644
--- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
+++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
@@ -1,14 +1,14 @@
-binding for LTC2941, LTC2942 and LTC2943 battery gauges
+binding for LTC2941, LTC2942, LTC2943 and LTC2944 battery gauges
 
 All chips measure battery capacity.
 The LTC2942 is pin compatible with the LTC2941, it adds voltage and
-temperature monitoring, and is runtime detected. LTC2943 is software
-compatible, uses a slightly different conversion formula for the
-charge counter and adds voltage, current and temperature monitoring.
+temperature monitoring, and is runtime detected. LTC2943 and LTC2944
+is software compatible, uses a slightly different conversion formula
+for the charge counter and adds voltage, current and temperature monitoring.
 
 Required properties:
-- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942" or "lltc,ltc2943"
-    which also indicates the type of I2C chip attached.
+- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942", "lltc,ltc2943"
+    or "lltc,ltc2944" which also indicates the type of I2C chip attached.
 - reg: The 7-bit I2C address.
 - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit
     negative value when the battery has been connected to the wrong end of the
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index 42ff4e3daf35..08e4fd9ee607 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -1,6 +1,6 @@
 /*
- * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943
- * Battery Gas Gauge IC
+ * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943
+ * and LTC2944 Battery Gas Gauge IC
  *
  * Copyright (C) 2014 Topic Embedded Systems
  *
@@ -48,6 +48,7 @@ enum ltc294x_id {
 	LTC2941_ID,
 	LTC2942_ID,
 	LTC2943_ID,
+	LTC2944_ID,
 };
 
 #define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
@@ -153,7 +154,8 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
 	case LTC2942_ID:	/* 2942 measures every 2 sec */
 		control |= LTC2942_REG_CONTROL_MODE_SCAN;
 		break;
-	case LTC2943_ID:	/* 2943 measures every 10 sec */
+	case LTC2943_ID:
+	case LTC2944_ID:	/* 2943 and 2944 measure every 10 sec */
 		control |= LTC2943_REG_CONTROL_MODE_SCAN;
 		break;
 	default:
@@ -269,6 +271,11 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
 		value /= 0xFFFF;
 		value *= 1000 / 2;
 		break;
+	case LTC2944_ID:
+		value *= 70800 / 5*4;
+		value /= 0xFFFF;
+		value *= 1000 * 5/4;
+		break;
 	default:
 		value *= 6000 * 10;
 		value /= 0xFFFF;
@@ -289,10 +296,14 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
 		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
 	value = (datar[0] << 8) | datar[1];
 	value -= 0x7FFF;
+	if (info->id == LTC2944_ID)
+		value *= 64000;
+	else
+		value *= 60000;
 	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
 	 * the formula below keeps everything in s32 range while preserving
 	 * enough digits */
-	*val = 1000 * ((60000 * value) / (info->r_sense * 0x7FFF)); /* in uA */
+	*val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */
 	return ret;
 }
 
@@ -470,6 +481,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
 	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
 	info->supply_desc.properties = ltc294x_properties;
 	switch (info->id) {
+	case LTC2944_ID:
 	case LTC2943_ID:
 		info->supply_desc.num_properties =
 			ARRAY_SIZE(ltc294x_properties);
@@ -543,6 +555,7 @@ static const struct i2c_device_id ltc294x_i2c_id[] = {
 	{ "ltc2941", LTC2941_ID, },
 	{ "ltc2942", LTC2942_ID, },
 	{ "ltc2943", LTC2943_ID, },
+	{ "ltc2944", LTC2944_ID, },
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
@@ -560,6 +573,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
 		.compatible = "lltc,ltc2943",
 		.data = (void *)LTC2943_ID,
 	},
+	{
+		.compatible = "lltc,ltc2944",
+		.data = (void *)LTC2944_ID,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
@@ -578,5 +595,5 @@ module_i2c_driver(ltc294x_driver);
 
 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
-MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver");
+MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0

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

* Re: [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for LTC2942 and LTC2944
  2017-07-16  9:33 ` [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for " Ladislav Michl
@ 2017-07-17 14:52   ` Bogdan, Dragos
  0 siblings, 0 replies; 9+ messages in thread
From: Bogdan, Dragos @ 2017-07-17 14:52 UTC (permalink / raw)
  To: Ladislav Michl, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Looijmans, Javier Martinez Canillas, Sebastian Reichel,
	Rob Herring, Mark Rutland

On 07/16/2017 12:33 PM, Ladislav Michl wrote:
> In order to support LTC2942 which has temperature registers
> at different offsets than LTC2943 use following register naming
> scheme (prefixes):
> - LTC294X_ common registers
> - LTC2942_ chips specific registers
> - LTC2943_ specific registers
>
> LTC2944 is compatible with LTC2943 but uses different constants
> to compute voltage and current, so replace num_regs misused
> for device indentification with real device id to discriminate
> between those two.
>
> There are no functional changes.
>
> Signed-off-by: Ladislav Michl <ladis-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>

Acked-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Tested-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

> ---
>  Changes:
>  - v2: None
>  - v3: Extend commit message
>  - v4: None
>  - v5: Count on LTC2944 too
>  - v6: Move LTC2942 and LTC2944 to respective patches
>
>  drivers/power/supply/ltc2941-battery-gauge.c | 63 ++++++++++++++--------------
>  1 file changed, 31 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
> index 7efb908f4451..b0de448a226b 100644
> --- a/drivers/power/supply/ltc2941-battery-gauge.c
> +++ b/drivers/power/supply/ltc2941-battery-gauge.c
> @@ -34,16 +34,19 @@ enum ltc294x_reg {
>  	LTC294X_REG_CONTROL		= 0x01,
>  	LTC294X_REG_ACC_CHARGE_MSB	= 0x02,
>  	LTC294X_REG_ACC_CHARGE_LSB	= 0x03,
> -	LTC294X_REG_THRESH_HIGH_MSB	= 0x04,
> -	LTC294X_REG_THRESH_HIGH_LSB	= 0x05,
> -	LTC294X_REG_THRESH_LOW_MSB	= 0x06,
> -	LTC294X_REG_THRESH_LOW_LSB	= 0x07,
> -	LTC294X_REG_VOLTAGE_MSB	= 0x08,
> -	LTC294X_REG_VOLTAGE_LSB	= 0x09,
> -	LTC294X_REG_CURRENT_MSB	= 0x0E,
> -	LTC294X_REG_CURRENT_LSB	= 0x0F,
> -	LTC294X_REG_TEMPERATURE_MSB	= 0x14,
> -	LTC294X_REG_TEMPERATURE_LSB	= 0x15,
> +	LTC294X_REG_VOLTAGE_MSB		= 0x08,
> +	LTC294X_REG_VOLTAGE_LSB		= 0x09,
> +	LTC2942_REG_TEMPERATURE_MSB	= 0x0C,
> +	LTC2942_REG_TEMPERATURE_LSB	= 0x0D,
> +	LTC2943_REG_CURRENT_MSB		= 0x0E,
> +	LTC2943_REG_CURRENT_LSB		= 0x0F,
> +	LTC2943_REG_TEMPERATURE_MSB	= 0x14,
> +	LTC2943_REG_TEMPERATURE_LSB	= 0x15,
> +};
> +
> +enum ltc294x_id {
> +	LTC2941_ID,
> +	LTC2943_ID,
>  };
>  
>  #define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
> @@ -54,15 +57,12 @@ enum ltc294x_reg {
>  	((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
>  #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED	0
>  
> -#define LTC2941_NUM_REGS	0x08
> -#define LTC2943_NUM_REGS	0x18
> -
>  struct ltc294x_info {
>  	struct i2c_client *client;	/* I2C Client pointer */
>  	struct power_supply *supply;	/* Supply pointer */
>  	struct power_supply_desc supply_desc;	/* Supply description */
>  	struct delayed_work work;	/* Work scheduler */
> -	unsigned long num_regs;	/* Number of registers (chip type) */
> +	enum ltc294x_id id;		/* Chip type */
>  	int charge;	/* Last charge register content */
>  	int r_sense;	/* mOhm */
>  	int Qlsb;	/* nAh */
> @@ -146,7 +146,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
>  	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
>  				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
>  	/* Put the 2943 into "monitor" mode, so it measures every 10 sec */
> -	if (info->num_regs == LTC2943_NUM_REGS)
> +	if (info->id == LTC2941_ID)
>  		control |= LTC2943_REG_CONTROL_MODE_SCAN;
>  
>  	if (value != control) {
> @@ -263,7 +263,7 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
>  	s32 value;
>  
>  	ret = ltc294x_read_regs(info->client,
> -		LTC294X_REG_CURRENT_MSB, &datar[0], 2);
> +		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
>  	value = (datar[0] << 8) | datar[1];
>  	value -= 0x7FFF;
>  	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
> @@ -280,7 +280,7 @@ static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
>  	u32 value;
>  
>  	ret = ltc294x_read_regs(info->client,
> -		LTC294X_REG_TEMPERATURE_MSB, &datar[0], 2);
> +		LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2);
>  	value = (datar[0] << 8) | datar[1];
>  	/* Full-scale is 510 Kelvin, convert to centidegrees  */
>  	*val = (((51000 * value) / 0xFFFF) - 27215);
> @@ -357,8 +357,8 @@ static enum power_supply_property ltc294x_properties[] = {
>  	POWER_SUPPLY_PROP_CHARGE_COUNTER,
>  	POWER_SUPPLY_PROP_CHARGE_NOW,
>  	POWER_SUPPLY_PROP_VOLTAGE_NOW,
> -	POWER_SUPPLY_PROP_CURRENT_NOW,
>  	POWER_SUPPLY_PROP_TEMP,
> +	POWER_SUPPLY_PROP_CURRENT_NOW,
>  };
>  
>  static int ltc294x_i2c_remove(struct i2c_client *client)
> @@ -388,7 +388,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  
>  	np = of_node_get(client->dev.of_node);
>  
> -	info->num_regs = (unsigned long)of_device_get_match_data(&client->dev);
> +	info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
>  	info->supply_desc.name = np->name;
>  
>  	/* r_sense can be negative, when sense+ is connected to the battery
> @@ -409,7 +409,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  		prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
>  	}
>  
> -	if (info->num_regs == LTC2943_NUM_REGS) {
> +	if (info->id == LTC2943_ID) {
>  		if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
>  			prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
>  		info->Qlsb = ((340 * 50000) / r_sense) /
> @@ -424,18 +424,17 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  	info->client = client;
>  	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
>  	info->supply_desc.properties = ltc294x_properties;
> -	if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB)
> +	switch (info->id) {
> +	case LTC2943_ID:
>  		info->supply_desc.num_properties =
>  			ARRAY_SIZE(ltc294x_properties);
> -	else if (info->num_regs >= LTC294X_REG_CURRENT_LSB)
> -		info->supply_desc.num_properties =
> -			ARRAY_SIZE(ltc294x_properties) - 1;
> -	else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB)
> -		info->supply_desc.num_properties =
> -			ARRAY_SIZE(ltc294x_properties) - 2;
> -	else
> +		break;
> +	case LTC2941_ID:
> +	default:
>  		info->supply_desc.num_properties =
>  			ARRAY_SIZE(ltc294x_properties) - 3;
> +		break;
> +	}
>  	info->supply_desc.get_property = ltc294x_get_property;
>  	info->supply_desc.set_property = ltc294x_set_property;
>  	info->supply_desc.property_is_writeable = ltc294x_property_is_writeable;
> @@ -492,8 +491,8 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
>  
>  
>  static const struct i2c_device_id ltc294x_i2c_id[] = {
> -	{"ltc2941", LTC2941_NUM_REGS},
> -	{"ltc2943", LTC2943_NUM_REGS},
> +	{ "ltc2941", LTC2941_ID, },
> +	{ "ltc2943", LTC2943_ID, },
>  	{ },
>  };
>  MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
> @@ -501,11 +500,11 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
>  static const struct of_device_id ltc294x_i2c_of_match[] = {
>  	{
>  		.compatible = "lltc,ltc2941",
> -		.data = (void *)LTC2941_NUM_REGS
> +		.data = (void *)LTC2941_ID,
>  	},
>  	{
>  		.compatible = "lltc,ltc2943",
> -		.data = (void *)LTC2943_NUM_REGS
> +		.data = (void *)LTC2943_ID,
>  	},
>  	{ },
>  };


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

* Re: [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support
  2017-07-16  9:34 ` [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support Ladislav Michl
@ 2017-07-17 14:53   ` Bogdan, Dragos
  0 siblings, 0 replies; 9+ messages in thread
From: Bogdan, Dragos @ 2017-07-17 14:53 UTC (permalink / raw)
  To: Ladislav Michl, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Looijmans, Javier Martinez Canillas, Sebastian Reichel,
	Rob Herring, Mark Rutland

On 07/16/2017 12:34 PM, Ladislav Michl wrote:
> LTC2942 is pin compatible with LTC2941 providing additional
> informations about battery voltage and temperature. It can
> be runtime detected using bit A7 in the Status register.
>
> Signed-off-by: Ladislav Michl <ladis-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Acked-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Tested-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

> ---
>  Changes:
>  - v2: reworked voltage computing to not overflow and keep presision
>  - v3: update devicetree binding documentation
>  - v4: add ltc2942 devicetree compatible
>  - v5: make use of info->id introduced in previous patch
>  - v6: collect devicetree ack from Rob
>
>  .../devicetree/bindings/power/supply/ltc2941.txt   | 15 ++--
>  drivers/power/supply/ltc2941-battery-gauge.c       | 80 ++++++++++++++++++----
>  2 files changed, 75 insertions(+), 20 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> index a9d7aa60558b..8ec10366295d 100644
> --- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> +++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> @@ -1,13 +1,14 @@
> -binding for LTC2941 and LTC2943 battery gauges
> +binding for LTC2941, LTC2942 and LTC2943 battery gauges
>  
> -Both the LTC2941 and LTC2943 measure battery capacity.
> -The LTC2943 is compatible with the LTC2941, it adds voltage and
> -temperature monitoring, and uses a slightly different conversion
> -formula for the charge counter.
> +All chips measure battery capacity.
> +The LTC2942 is pin compatible with the LTC2941, it adds voltage and
> +temperature monitoring, and is runtime detected. LTC2943 is software
> +compatible, uses a slightly different conversion formula for the
> +charge counter and adds voltage, current and temperature monitoring.
>  
>  Required properties:
> -- compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also
> -    indicates the type of I2C chip attached.
> +- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942" or "lltc,ltc2943"
> +    which also indicates the type of I2C chip attached.
>  - reg: The 7-bit I2C address.
>  - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit
>      negative value when the battery has been connected to the wrong end of the
> diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
> index b0de448a226b..42ff4e3daf35 100644
> --- a/drivers/power/supply/ltc2941-battery-gauge.c
> +++ b/drivers/power/supply/ltc2941-battery-gauge.c
> @@ -1,5 +1,5 @@
>  /*
> - * I2C client/driver for the Linear Technology LTC2941 and LTC2943
> + * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943
>   * Battery Gas Gauge IC
>   *
>   * Copyright (C) 2014 Topic Embedded Systems
> @@ -46,11 +46,14 @@ enum ltc294x_reg {
>  
>  enum ltc294x_id {
>  	LTC2941_ID,
> +	LTC2942_ID,
>  	LTC2943_ID,
>  };
>  
> -#define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
> -#define LTC2943_REG_CONTROL_MODE_SCAN BIT(7)
> +#define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
> +
> +#define LTC2942_REG_CONTROL_MODE_SCAN	(BIT(7) | BIT(6))
> +#define LTC2943_REG_CONTROL_MODE_SCAN	BIT(7)
>  #define LTC294X_REG_CONTROL_PRESCALER_MASK	(BIT(5) | BIT(4) | BIT(3))
>  #define LTC294X_REG_CONTROL_SHUTDOWN_MASK	(BIT(0))
>  #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
> @@ -145,9 +148,17 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
>  
>  	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
>  				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
> -	/* Put the 2943 into "monitor" mode, so it measures every 10 sec */
> -	if (info->id == LTC2941_ID)
> +	/* Put device into "monitor" mode */
> +	switch (info->id) {
> +	case LTC2942_ID:	/* 2942 measures every 2 sec */
> +		control |= LTC2942_REG_CONTROL_MODE_SCAN;
> +		break;
> +	case LTC2943_ID:	/* 2943 measures every 10 sec */
>  		control |= LTC2943_REG_CONTROL_MODE_SCAN;
> +		break;
> +	default:
> +		break;
> +	}
>  
>  	if (value != control) {
>  		ret = ltc294x_write_regs(info->client,
> @@ -252,7 +263,19 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
>  	ret = ltc294x_read_regs(info->client,
>  		LTC294X_REG_VOLTAGE_MSB, &datar[0], 2);
>  	value = (datar[0] << 8) | datar[1];
> -	*val = ((value * 23600) / 0xFFFF) * 1000; /* in uV */
> +	switch (info->id) {
> +	case LTC2943_ID:
> +		value *= 23600 * 2;
> +		value /= 0xFFFF;
> +		value *= 1000 / 2;
> +		break;
> +	default:
> +		value *= 6000 * 10;
> +		value /= 0xFFFF;
> +		value *= 1000 / 10;
> +		break;
> +	}
> +	*val = value;
>  	return ret;
>  }
>  
> @@ -275,15 +298,22 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
>  
>  static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
>  {
> +	enum ltc294x_reg reg;
>  	int ret;
>  	u8 datar[2];
>  	u32 value;
>  
> -	ret = ltc294x_read_regs(info->client,
> -		LTC2943_REG_TEMPERATURE_MSB, &datar[0], 2);
> -	value = (datar[0] << 8) | datar[1];
> -	/* Full-scale is 510 Kelvin, convert to centidegrees  */
> -	*val = (((51000 * value) / 0xFFFF) - 27215);
> +	if (info->id == LTC2942_ID) {
> +		reg = LTC2942_REG_TEMPERATURE_MSB;
> +		value = 60000;	/* Full-scale is 600 Kelvin */
> +	} else {
> +		reg = LTC2943_REG_TEMPERATURE_MSB;
> +		value = 51000;	/* Full-scale is 510 Kelvin */
> +	}
> +	ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
> +	value *= (datar[0] << 8) | datar[1];
> +	/* Convert to centidegrees  */
> +	*val = value / 0xFFFF - 27215;
>  	return ret;
>  }
>  
> @@ -375,10 +405,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  {
>  	struct power_supply_config psy_cfg = {};
>  	struct ltc294x_info *info;
> +	struct device_node *np;
>  	int ret;
>  	u32 prescaler_exp;
>  	s32 r_sense;
> -	struct device_node *np;
> +	u8 status;
>  
>  	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
>  	if (info == NULL)
> @@ -421,6 +452,20 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  				(128 / (1 << prescaler_exp));
>  	}
>  
> +	/* Read status register to check for LTC2942 */
> +	if (info->id == LTC2941_ID || info->id == LTC2942_ID) {
> +		ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1);
> +		if (ret < 0) {
> +			dev_err(&client->dev,
> +				"Could not read status register\n");
> +			return ret;
> +		}
> +		if (status & LTC2941_REG_STATUS_CHIP_ID)
> +			info->id = LTC2941_ID;
> +		else
> +			info->id = LTC2942_ID;
> +	}
> +
>  	info->client = client;
>  	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
>  	info->supply_desc.properties = ltc294x_properties;
> @@ -429,6 +474,10 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  		info->supply_desc.num_properties =
>  			ARRAY_SIZE(ltc294x_properties);
>  		break;
> +	case LTC2942_ID:
> +		info->supply_desc.num_properties =
> +			ARRAY_SIZE(ltc294x_properties) - 1;
> +		break;
>  	case LTC2941_ID:
>  	default:
>  		info->supply_desc.num_properties =
> @@ -492,6 +541,7 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
>  
>  static const struct i2c_device_id ltc294x_i2c_id[] = {
>  	{ "ltc2941", LTC2941_ID, },
> +	{ "ltc2942", LTC2942_ID, },
>  	{ "ltc2943", LTC2943_ID, },
>  	{ },
>  };
> @@ -503,6 +553,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
>  		.data = (void *)LTC2941_ID,
>  	},
>  	{
> +		.compatible = "lltc,ltc2942",
> +		.data = (void *)LTC2942_ID,
> +	},
> +	{
>  		.compatible = "lltc,ltc2943",
>  		.data = (void *)LTC2943_ID,
>  	},
> @@ -524,5 +578,5 @@ module_i2c_driver(ltc294x_driver);
>  
>  MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
>  MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
> -MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
> +MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver");
>  MODULE_LICENSE("GPL");


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

* Re: [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support
  2017-07-16  9:35 ` [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support Ladislav Michl
@ 2017-07-17 14:55   ` Bogdan, Dragos
  2017-07-17 19:42   ` Rob Herring
  1 sibling, 0 replies; 9+ messages in thread
From: Bogdan, Dragos @ 2017-07-17 14:55 UTC (permalink / raw)
  To: Ladislav Michl, linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Looijmans, Javier Martinez Canillas, Sebastian Reichel,
	Rob Herring, Mark Rutland

On 07/16/2017 12:35 PM, Ladislav Michl wrote:
> From: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
>
> LTC2944 is compatible with LTC2943, but uses different
> voltage and current computing constants.
>
> Signed-off-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Ladislav Michl <ladis-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>

Tested-by: Dragos Bogdan <dragos.bogdan-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

> ---
>  Changes:
>  - v2: fixed voltage and current conversion
>  - v3: skipped
>  - v4: skipped
>  - v5: fixed voltage conversion overflow, rebased on LTC2942 patchset
>  - v6: fix missing break in the switch statement
>
>  .../devicetree/bindings/power/supply/ltc2941.txt   | 12 +++++-----
>  drivers/power/supply/ltc2941-battery-gauge.c       | 27 ++++++++++++++++++----
>  2 files changed, 28 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> index 8ec10366295d..3b9ba147b041 100644
> --- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> +++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
> @@ -1,14 +1,14 @@
> -binding for LTC2941, LTC2942 and LTC2943 battery gauges
> +binding for LTC2941, LTC2942, LTC2943 and LTC2944 battery gauges
>  
>  All chips measure battery capacity.
>  The LTC2942 is pin compatible with the LTC2941, it adds voltage and
> -temperature monitoring, and is runtime detected. LTC2943 is software
> -compatible, uses a slightly different conversion formula for the
> -charge counter and adds voltage, current and temperature monitoring.
> +temperature monitoring, and is runtime detected. LTC2943 and LTC2944
> +is software compatible, uses a slightly different conversion formula
> +for the charge counter and adds voltage, current and temperature monitoring.
>  
>  Required properties:
> -- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942" or "lltc,ltc2943"
> -    which also indicates the type of I2C chip attached.
> +- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942", "lltc,ltc2943"
> +    or "lltc,ltc2944" which also indicates the type of I2C chip attached.
>  - reg: The 7-bit I2C address.
>  - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit
>      negative value when the battery has been connected to the wrong end of the
> diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
> index 42ff4e3daf35..08e4fd9ee607 100644
> --- a/drivers/power/supply/ltc2941-battery-gauge.c
> +++ b/drivers/power/supply/ltc2941-battery-gauge.c
> @@ -1,6 +1,6 @@
>  /*
> - * I2C client/driver for the Linear Technology LTC2941, LTC2942 and LTC2943
> - * Battery Gas Gauge IC
> + * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943
> + * and LTC2944 Battery Gas Gauge IC
>   *
>   * Copyright (C) 2014 Topic Embedded Systems
>   *
> @@ -48,6 +48,7 @@ enum ltc294x_id {
>  	LTC2941_ID,
>  	LTC2942_ID,
>  	LTC2943_ID,
> +	LTC2944_ID,
>  };
>  
>  #define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
> @@ -153,7 +154,8 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
>  	case LTC2942_ID:	/* 2942 measures every 2 sec */
>  		control |= LTC2942_REG_CONTROL_MODE_SCAN;
>  		break;
> -	case LTC2943_ID:	/* 2943 measures every 10 sec */
> +	case LTC2943_ID:
> +	case LTC2944_ID:	/* 2943 and 2944 measure every 10 sec */
>  		control |= LTC2943_REG_CONTROL_MODE_SCAN;
>  		break;
>  	default:
> @@ -269,6 +271,11 @@ static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
>  		value /= 0xFFFF;
>  		value *= 1000 / 2;
>  		break;
> +	case LTC2944_ID:
> +		value *= 70800 / 5*4;
> +		value /= 0xFFFF;
> +		value *= 1000 * 5/4;
> +		break;
>  	default:
>  		value *= 6000 * 10;
>  		value /= 0xFFFF;
> @@ -289,10 +296,14 @@ static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
>  		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
>  	value = (datar[0] << 8) | datar[1];
>  	value -= 0x7FFF;
> +	if (info->id == LTC2944_ID)
> +		value *= 64000;
> +	else
> +		value *= 60000;
>  	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
>  	 * the formula below keeps everything in s32 range while preserving
>  	 * enough digits */
> -	*val = 1000 * ((60000 * value) / (info->r_sense * 0x7FFF)); /* in uA */
> +	*val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */
>  	return ret;
>  }
>  
> @@ -470,6 +481,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>  	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
>  	info->supply_desc.properties = ltc294x_properties;
>  	switch (info->id) {
> +	case LTC2944_ID:
>  	case LTC2943_ID:
>  		info->supply_desc.num_properties =
>  			ARRAY_SIZE(ltc294x_properties);
> @@ -543,6 +555,7 @@ static const struct i2c_device_id ltc294x_i2c_id[] = {
>  	{ "ltc2941", LTC2941_ID, },
>  	{ "ltc2942", LTC2942_ID, },
>  	{ "ltc2943", LTC2943_ID, },
> +	{ "ltc2944", LTC2944_ID, },
>  	{ },
>  };
>  MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
> @@ -560,6 +573,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
>  		.compatible = "lltc,ltc2943",
>  		.data = (void *)LTC2943_ID,
>  	},
> +	{
> +		.compatible = "lltc,ltc2944",
> +		.data = (void *)LTC2944_ID,
> +	},
>  	{ },
>  };
>  MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
> @@ -578,5 +595,5 @@ module_i2c_driver(ltc294x_driver);
>  
>  MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
>  MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
> -MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943 Battery Gas Gauge IC driver");
> +MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver");
>  MODULE_LICENSE("GPL");


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

* Re: [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support
  2017-07-16  9:35 ` [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support Ladislav Michl
  2017-07-17 14:55   ` Bogdan, Dragos
@ 2017-07-17 19:42   ` Rob Herring
  1 sibling, 0 replies; 9+ messages in thread
From: Rob Herring @ 2017-07-17 19:42 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pm, devicetree, Mike Looijmans, Dragos Bogdan,
	Javier Martinez Canillas, Sebastian Reichel, Mark Rutland

On Sun, Jul 16, 2017 at 11:35:32AM +0200, Ladislav Michl wrote:
> From: Dragos Bogdan <dragos.bogdan@analog.com>
> 
> LTC2944 is compatible with LTC2943, but uses different
> voltage and current computing constants.
> 
> Signed-off-by: Dragos Bogdan <dragos.bogdan@analog.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  - v2: fixed voltage and current conversion
>  - v3: skipped
>  - v4: skipped
>  - v5: fixed voltage conversion overflow, rebased on LTC2942 patchset
>  - v6: fix missing break in the switch statement
> 
>  .../devicetree/bindings/power/supply/ltc2941.txt   | 12 +++++-----

Acked-by: Rob Herring <robh@kernel.org>

>  drivers/power/supply/ltc2941-battery-gauge.c       | 27 ++++++++++++++++++----
>  2 files changed, 28 insertions(+), 11 deletions(-)

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

* Re: [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944
  2017-07-16  9:32 [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Ladislav Michl
                   ` (2 preceding siblings ...)
  2017-07-16  9:35 ` [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support Ladislav Michl
@ 2017-07-25 10:20 ` Sebastian Reichel
  3 siblings, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2017-07-25 10:20 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mike Looijmans, Dragos Bogdan,
	Javier Martinez Canillas, Rob Herring, Mark Rutland

[-- Attachment #1: Type: text/plain, Size: 900 bytes --]

Hi,

On Sun, Jul 16, 2017 at 11:32:02AM +0200, Ladislav Michl wrote:
> This is the 6th version of patch.
> Changelog:
> - v2: reworked voltage computing to not overflow and keep precision
> - v3: update devicetree binding documentation
> - v4: add ltc2942 devicetree compatible
> - v5: reworked to incorporate Dragos' LTC2944 patch
> - v6: fix missing break in the switch statement, move LTC2942 and LTC2944
>       id definitions into respective patches
>  
> LTC2942 is pin compatible with LTC2941 providing few more registers
> holding information about battery voltage and temperature. It can
> be runtime detected using bit A7 in the Status register.
> 
> LTC2944 is compatible with LTC2943, but uses different
> voltage and current computing constants.
> 
> Comments welcome,
> 	ladis

Thanks, queued the whole patchset to power-supply's for-next branch.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

end of thread, other threads:[~2017-07-25 10:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-16  9:32 [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Ladislav Michl
2017-07-16  9:33 ` [PATCH v6 1/3] power: supply: ltc2941-battery-gauge: Prepare for " Ladislav Michl
2017-07-17 14:52   ` Bogdan, Dragos
2017-07-16  9:34 ` [PATCH v6 2/3] power: supply: ltc2941-battery-gauge: Add LTC2942 support Ladislav Michl
2017-07-17 14:53   ` Bogdan, Dragos
2017-07-16  9:35 ` [PATCH v6 3/3] power: supply: ltc2941-battery-gauge: Add LTC2944 support Ladislav Michl
2017-07-17 14:55   ` Bogdan, Dragos
2017-07-17 19:42   ` Rob Herring
2017-07-25 10:20 ` [PATCH v6 0/3] power: supply: ltc2941-battery-gauge: Support LTC2942 and LTC2944 Sebastian Reichel

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.