All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hwmon: Add LTC2990 sensor driver
@ 2016-01-06  8:07 ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-06  8:07 UTC (permalink / raw)
  To: lm-sensors; +Cc: linux, jdelvare, linux-kernel, Mike Looijmans

This adds support for the Linear Technology LTC2990  I2C System Monitor.
The LTC2990 supports a combination of voltage, current and temperature
monitoring, but this driver currently only supports reading two currents
by measuring two differential voltages across series resistors.

This is sufficient to support the Topic Miami SOM which uses this chip
to monitor the currents flowing into the FPGA and the CPU parts.

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
---
 drivers/hwmon/Kconfig   |  15 +++
 drivers/hwmon/Makefile  |   1 +
 drivers/hwmon/ltc2990.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+)
 create mode 100644 drivers/hwmon/ltc2990.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 80a73bf..b3eef31 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -685,6 +685,21 @@ config SENSORS_LTC2945
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2945.
 
+config SENSORS_LTC2990
+	tristate "Linear Technology LTC2990 (current monitoring mode only)"
+	depends on I2C
+	select REGMAP_I2C
+	default n
+	help
+	  If you say yes here you get support for Linear Technology LTC2990
+	  I2C System Monitor. The LTC2990 supports a combination of voltage,
+	  current and temperature monitoring, but this driver currently only
+	  supports reading two currents by measuring two differential voltages
+	  across series resistors.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc2990.
+
 config SENSORS_LTC4151
 	tristate "Linear Technology LTC4151"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 12a3239..e4bd15b 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
 obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
 obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
 obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
+obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
 obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
 obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
new file mode 100644
index 0000000..161d995
--- /dev/null
+++ b/drivers/hwmon/ltc2990.c
@@ -0,0 +1,273 @@
+/*
+ * driver for Linear Technology LTC2990 power monitor
+ *
+ * Copyright (C) 2014 Topic Embedded Products
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * License: GPLv2
+ *
+ * This driver assumes the chip is wired as a dual current monitor, and
+ * reports the voltage drop across two series resistors.
+ */
+
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define LTC2990_STATUS	0x00
+#define LTC2990_CONTROL	0x01
+#define LTC2990_TRIGGER	0x02
+#define LTC2990_TINT_MSB	0x04
+#define LTC2990_TINT_LSB	0x05
+#define LTC2990_V1_MSB	0x06
+#define LTC2990_V1_LSB	0x07
+#define LTC2990_V2_MSB	0x08
+#define LTC2990_V2_LSB	0x09
+#define LTC2990_V3_MSB	0x0A
+#define LTC2990_V3_LSB	0x0B
+#define LTC2990_V4_MSB	0x0C
+#define LTC2990_V4_LSB	0x0D
+#define LTC2990_VCC_MSB	0x0E
+#define LTC2990_VCC_LSB	0x0F
+
+#define LTC2990_STATUS_BUSY	BIT(0)
+#define LTC2990_STATUS_TINT	BIT(1)
+#define LTC2990_STATUS_V1	BIT(2)
+#define LTC2990_STATUS_V2	BIT(3)
+#define LTC2990_STATUS_V3	BIT(4)
+#define LTC2990_STATUS_V4	BIT(5)
+#define LTC2990_STATUS_VCC	BIT(6)
+
+/* Only define control settings we actually use */
+#define LTC2990_CONTROL_KELVIN		BIT(7)
+#define LTC2990_CONTROL_SINGLE		BIT(6)
+#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
+#define LTC2990_CONTROL_MODE_CURRENT	0x06
+#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
+
+struct ltc2990_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	unsigned long last_updated;
+	short values[6];
+	bool valid;
+	u8 update_counter;
+};
+
+static int ltc2990_write(struct i2c_client *i2c, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(i2c, reg, value);
+}
+
+static int ltc2990_read_byte(struct i2c_client *i2c, u8 reg)
+{
+	return i2c_smbus_read_byte_data(i2c, reg);
+}
+
+static int ltc2990_read_word(struct i2c_client *i2c, u8 reg)
+{
+	int result = i2c_smbus_read_word_data(i2c, reg);
+	/* Result is MSB first, but smbus specs say LSB first, so swap the
+	 * result */
+	return result < 0 ? result : swab16(result);
+}
+
+static struct ltc2990_data *ltc2990_update_device(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct ltc2990_data *data = i2c_get_clientdata(i2c);
+	struct ltc2990_data *ret = data;
+	unsigned int timeout;
+
+	mutex_lock(&data->update_lock);
+
+	/* Update about 4 times per second max */
+	if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) {
+		int val;
+		int i;
+
+		/* Trigger ADC, any value will do */
+		val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
+		if (unlikely(val < 0)) {
+			ret = ERR_PTR(val);
+			goto abort;
+		}
+
+		/* Wait for conversion complete */
+		timeout = 200;
+		for (;;) {
+			usleep_range(2000, 4000);
+			val = ltc2990_read_byte(i2c, LTC2990_STATUS);
+			if (unlikely(val < 0)) {
+				ret = ERR_PTR(val);
+				goto abort;
+			}
+			/* Single-shot mode, wait for conversion to complete */
+			if ((val & LTC2990_STATUS_BUSY) == 0)
+				break;
+			if (--timeout == 0) {
+				ret = ERR_PTR(-ETIMEDOUT);
+				goto abort;
+			}
+		}
+
+		/* Read all registers */
+		for (i = 0; i < ARRAY_SIZE(data->values); ++i) {
+			val = ltc2990_read_word(i2c, (i<<1) + LTC2990_TINT_MSB);
+			if (unlikely(val < 0)) {
+				dev_dbg(dev,
+					"Failed to read ADC value: error %d\n",
+					val);
+				ret = ERR_PTR(val);
+				goto abort;
+			}
+			data->values[i] = val & 0x7FFF; /* Strip 'new' bit */
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+		/*
+		 *  Quirk: Second trigger is ignored? After this, the BUSY will
+		 * still be set to "0" and no conversion performed.
+		 */
+		val = ltc2990_write(i2c, LTC2990_TRIGGER, 0);
+	}
+abort:
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+/* Return the converted value from the given register in uV or mC */
+static int ltc2990_get_value(struct ltc2990_data *data, u8 index)
+{
+	s32 result;
+	s16 v;
+
+	if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 12-bit  */
+		v = data->values[index] << 3;
+		result = (s32)v * 1000 >> 7;
+	} else if (index < 5) { /* Vx-Vy, 19.42uV/LSB, 14-bit */
+		v = data->values[index] << 2;
+		result = (s32)v * 1942 / (4 * 100);
+	} else { /* Vcc, 305.18μV/LSB, 2.5V offset, 14-bit */
+		v = data->values[index] << 2;
+		result = (s32)v * 30518 / (4 * 100);
+		result += 2500000;
+	}
+	return result;
+}
+
+static ssize_t ltc2990_show_value(struct device *dev,
+				  struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct ltc2990_data *data = ltc2990_update_device(dev);
+	int value;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	value = ltc2990_get_value(data, attr->index);
+	return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+static SENSOR_DEVICE_ATTR(temp_int, S_IRUGO, ltc2990_show_value, NULL, 0);
+static SENSOR_DEVICE_ATTR(v1v2_diff, S_IRUGO, ltc2990_show_value, NULL, 1);
+static SENSOR_DEVICE_ATTR(v3v4_diff, S_IRUGO, ltc2990_show_value, NULL, 3);
+static SENSOR_DEVICE_ATTR(vcc, S_IRUGO, ltc2990_show_value, NULL, 5);
+
+static struct attribute *ltc2990_attributes[] = {
+	&sensor_dev_attr_temp_int.dev_attr.attr,
+	&sensor_dev_attr_v1v2_diff.dev_attr.attr,
+	&sensor_dev_attr_v3v4_diff.dev_attr.attr,
+	&sensor_dev_attr_vcc.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ltc2990_group = {
+	.attrs = ltc2990_attributes,
+};
+
+static int ltc2990_i2c_probe(
+	struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+	int ret;
+	struct ltc2990_data *ltc2990;
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	ltc2990 = devm_kzalloc(&i2c->dev,
+		sizeof(struct ltc2990_data), GFP_KERNEL);
+	if (ltc2990 == NULL)
+		return -ENOMEM;
+
+	ret = ltc2990_read_byte(i2c, 0);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Could not read LTC2990 on i2c bus.\n");
+		return ret;
+	}
+	ret = ltc2990_write(i2c, LTC2990_CONTROL,
+		LTC2990_CONTROL_SINGLE | LTC2990_CONTROL_MEASURE_ALL |
+		LTC2990_CONTROL_MODE_CURRENT);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
+		return ret;
+	}
+
+	mutex_init(&ltc2990->update_lock);
+	i2c_set_clientdata(i2c, ltc2990);
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&i2c->dev.kobj, &ltc2990_group);
+	if (ret)
+		return ret;
+
+	ltc2990->hwmon_dev = hwmon_device_register(&i2c->dev);
+	if (IS_ERR(ltc2990->hwmon_dev)) {
+		ret = PTR_ERR(ltc2990->hwmon_dev);
+		goto out_hwmon_device_register;
+	}
+
+	return 0;
+
+out_hwmon_device_register:
+	sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
+	return ret;
+}
+
+static int ltc2990_i2c_remove(struct i2c_client *i2c)
+{
+	struct ltc2990_data *ltc2990 = i2c_get_clientdata(i2c);
+
+	hwmon_device_unregister(ltc2990->hwmon_dev);
+	sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
+	return 0;
+}
+
+static const struct i2c_device_id ltc2990_i2c_id[] = {
+	{ "ltc2990", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
+
+static struct i2c_driver ltc2990_i2c_driver = {
+	.driver = {
+		.name = "ltc2990",
+	},
+	.probe    = ltc2990_i2c_probe,
+	.remove   = ltc2990_i2c_remove,
+	.id_table = ltc2990_i2c_id,
+};
+
+module_i2c_driver(ltc2990_i2c_driver);
+
+MODULE_DESCRIPTION("LTC2990 Sensor Driver");
+MODULE_AUTHOR("Topic Embedded Products");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


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

* [lm-sensors] [PATCH] hwmon: Add LTC2990 sensor driver
@ 2016-01-06  8:07 ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-06  8:07 UTC (permalink / raw)
  To: lm-sensors; +Cc: linux, jdelvare, linux-kernel, Mike Looijmans

VGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMg
U3lzdGVtIE1vbml0b3IuClRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9s
dGFnZSwgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUKbW9uaXRvcmluZywgYnV0IHRoaXMgZHJpdmVy
IGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCmJ5IG1lYXN1cmlu
ZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcyBzZXJpZXMgcmVzaXN0b3JzLgoKVGhp
cyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1c2Vz
IHRoaXMgY2hpcAp0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQR0Eg
YW5kIHRoZSBDUFUgcGFydHMuCgpTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5s
b29pam1hbnNAdG9waWMubmw+Ci0tLQogZHJpdmVycy9od21vbi9LY29uZmlnICAgfCAgMTUgKysr
CiBkcml2ZXJzL2h3bW9uL01ha2VmaWxlICB8ICAgMSArCiBkcml2ZXJzL2h3bW9uL2x0YzI5OTAu
YyB8IDI3MyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysK
IDMgZmlsZXMgY2hhbmdlZCwgMjg5IGluc2VydGlvbnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBk
cml2ZXJzL2h3bW9uL2x0YzI5OTAuYwoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZp
ZyBiL2RyaXZlcnMvaHdtb24vS2NvbmZpZwppbmRleCA4MGE3M2JmLi5iM2VlZjMxIDEwMDY0NAot
LS0gYS9kcml2ZXJzL2h3bW9uL0tjb25maWcKKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCkBA
IC02ODUsNiArNjg1LDIxIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKIAkgIFRoaXMgZHJpdmVy
IGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVsZSB3aWxsCiAJ
ICBiZSBjYWxsZWQgbHRjMjk0NS4KIAorY29uZmlnIFNFTlNPUlNfTFRDMjk5MAorCXRyaXN0YXRl
ICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50IG1vbml0b3JpbmcgbW9kZSBvbmx5
KSIKKwlkZXBlbmRzIG9uIEkyQworCXNlbGVjdCBSRUdNQVBfSTJDCisJZGVmYXVsdCBuCisJaGVs
cAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNo
bm9sb2d5IExUQzI5OTAKKwkgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9y
dHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLAorCSAgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUg
bW9uaXRvcmluZywgYnV0IHRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5CisJICBzdXBwb3J0cyBy
ZWFkaW5nIHR3byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbCB2b2x0YWdl
cworCSAgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCisKKwkgIFRoaXMgZHJpdmVyIGNhbiBhbHNv
IGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVsZSB3aWxsCisJICBiZSBjYWxs
ZWQgbHRjMjk5MC4KKwogY29uZmlnIFNFTlNPUlNfTFRDNDE1MQogCXRyaXN0YXRlICJMaW5lYXIg
VGVjaG5vbG9neSBMVEM0MTUxIgogCWRlcGVuZHMgb24gSTJDCmRpZmYgLS1naXQgYS9kcml2ZXJz
L2h3bW9uL01ha2VmaWxlIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQppbmRleCAxMmEzMjM5Li5l
NGJkMTViIDEwMDY0NAotLS0gYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCisrKyBiL2RyaXZlcnMv
aHdtb24vTWFrZWZpbGUKQEAgLTEwMSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09SU19M
TTk1MjM0KQkrPSBsbTk1MjM0Lm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxt
OTUyNDEubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTE05NTI0NSkJKz0gbG05NTI0NS5vCiBvYmot
JChDT05GSUdfU0VOU09SU19MVEMyOTQ1KQkrPSBsdGMyOTQ1Lm8KK29iai0kKENPTkZJR19TRU5T
T1JTX0xUQzI5OTApCSs9IGx0YzI5OTAubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDE1MSkJ
Kz0gbHRjNDE1MS5vCiBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MjE1KQkrPSBsdGM0MjE1Lm8K
IG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMjIpCSs9IGx0YzQyMjIubwpkaWZmIC0tZ2l0IGEv
ZHJpdmVycy9od21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwpuZXcgZmls
ZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjFkOTk1Ci0tLSAvZGV2L251bGwKKysrIGIv
ZHJpdmVycy9od21vbi9sdGMyOTkwLmMKQEAgLTAsMCArMSwyNzMgQEAKKy8qCisgKiBkcml2ZXIg
Zm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgorICoKKyAqIENvcHly
aWdodCAoQykgMjAxNCBUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cworICogQXV0aG9yOiBNaWtlIExv
b2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+CisgKgorICogTGljZW5zZTogR1BMdjIK
KyAqCisgKiBUaGlzIGRyaXZlciBhc3N1bWVzIHRoZSBjaGlwIGlzIHdpcmVkIGFzIGEgZHVhbCBj
dXJyZW50IG1vbml0b3IsIGFuZAorICogcmVwb3J0cyB0aGUgdm9sdGFnZSBkcm9wIGFjcm9zcyB0
d28gc2VyaWVzIHJlc2lzdG9ycy4KKyAqLworCisjaW5jbHVkZSA8bGludXgvYnVnLmg+CisjaW5j
bHVkZSA8bGludXgvZGVsYXkuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKyNpbmNsdWRlIDxs
aW51eC9od21vbi5oPgorI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+CisjaW5jbHVkZSA8
bGludXgvaTJjLmg+CisjaW5jbHVkZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGludXgv
bW9kdWxlLmg+CisjaW5jbHVkZSA8bGludXgvc2xhYi5oPgorCisjZGVmaW5lIExUQzI5OTBfU1RB
VFVTCTB4MDAKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MCTB4MDEKKyNkZWZpbmUgTFRDMjk5MF9U
UklHR0VSCTB4MDIKKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0CisjZGVmaW5lIExUQzI5
OTBfVElOVF9MU0IJMHgwNQorI2RlZmluZSBMVEMyOTkwX1YxX01TQgkweDA2CisjZGVmaW5lIExU
QzI5OTBfVjFfTFNCCTB4MDcKKyNkZWZpbmUgTFRDMjk5MF9WMl9NU0IJMHgwOAorI2RlZmluZSBM
VEMyOTkwX1YyX0xTQgkweDA5CisjZGVmaW5lIExUQzI5OTBfVjNfTVNCCTB4MEEKKyNkZWZpbmUg
TFRDMjk5MF9WM19MU0IJMHgwQgorI2RlZmluZSBMVEMyOTkwX1Y0X01TQgkweDBDCisjZGVmaW5l
IExUQzI5OTBfVjRfTFNCCTB4MEQKKyNkZWZpbmUgTFRDMjk5MF9WQ0NfTVNCCTB4MEUKKyNkZWZp
bmUgTFRDMjk5MF9WQ0NfTFNCCTB4MEYKKworI2RlZmluZSBMVEMyOTkwX1NUQVRVU19CVVNZCUJJ
VCgwKQorI2RlZmluZSBMVEMyOTkwX1NUQVRVU19USU5UCUJJVCgxKQorI2RlZmluZSBMVEMyOTkw
X1NUQVRVU19WMQlCSVQoMikKKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjIJQklUKDMpCisjZGVm
aW5lIExUQzI5OTBfU1RBVFVTX1YzCUJJVCg0KQorI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WNAlC
SVQoNSkKKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVkNDCUJJVCg2KQorCisvKiBPbmx5IGRlZmlu
ZSBjb250cm9sIHNldHRpbmdzIHdlIGFjdHVhbGx5IHVzZSAqLworI2RlZmluZSBMVEMyOTkwX0NP
TlRST0xfS0VMVklOCQlCSVQoNykKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX1NJTkdMRQkJQklU
KDYpCisjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCisjZGVm
aW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQJMHgwNgorI2RlZmluZSBMVEMyOTkwX0NP
TlRST0xfTU9ERV9WT0xUQUdFCTB4MDcKKworc3RydWN0IGx0YzI5OTBfZGF0YSB7CisJc3RydWN0
IGRldmljZSAqaHdtb25fZGV2OworCXN0cnVjdCBtdXRleCB1cGRhdGVfbG9jazsKKwl1bnNpZ25l
ZCBsb25nIGxhc3RfdXBkYXRlZDsKKwlzaG9ydCB2YWx1ZXNbNl07CisJYm9vbCB2YWxpZDsKKwl1
OCB1cGRhdGVfY291bnRlcjsKK307CisKK3N0YXRpYyBpbnQgbHRjMjk5MF93cml0ZShzdHJ1Y3Qg
aTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4IHZhbHVlKQoreworCXJldHVybiBpMmNfc21idXNf
d3JpdGVfYnl0ZV9kYXRhKGkyYywgcmVnLCB2YWx1ZSk7Cit9CisKK3N0YXRpYyBpbnQgbHRjMjk5
MF9yZWFkX2J5dGUoc3RydWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnKQoreworCXJldHVybiBp
MmNfc21idXNfcmVhZF9ieXRlX2RhdGEoaTJjLCByZWcpOworfQorCitzdGF0aWMgaW50IGx0YzI5
OTBfcmVhZF93b3JkKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsIHU4IHJlZykKK3sKKwlpbnQgcmVz
dWx0ID0gaTJjX3NtYnVzX3JlYWRfd29yZF9kYXRhKGkyYywgcmVnKTsKKwkvKiBSZXN1bHQgaXMg
TVNCIGZpcnN0LCBidXQgc21idXMgc3BlY3Mgc2F5IExTQiBmaXJzdCwgc28gc3dhcCB0aGUKKwkg
KiByZXN1bHQgKi8KKwlyZXR1cm4gcmVzdWx0IDwgMCA/IHJlc3VsdCA6IHN3YWIxNihyZXN1bHQp
OworfQorCitzdGF0aWMgc3RydWN0IGx0YzI5OTBfZGF0YSAqbHRjMjk5MF91cGRhdGVfZGV2aWNl
KHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjID0gdG9faTJj
X2NsaWVudChkZXYpOworCXN0cnVjdCBsdGMyOTkwX2RhdGEgKmRhdGEgPSBpMmNfZ2V0X2NsaWVu
dGRhdGEoaTJjKTsKKwlzdHJ1Y3QgbHRjMjk5MF9kYXRhICpyZXQgPSBkYXRhOworCXVuc2lnbmVk
IGludCB0aW1lb3V0OworCisJbXV0ZXhfbG9jaygmZGF0YS0+dXBkYXRlX2xvY2spOworCisJLyog
VXBkYXRlIGFib3V0IDQgdGltZXMgcGVyIHNlY29uZCBtYXggKi8KKwlpZiAodGltZV9hZnRlcihq
aWZmaWVzLCBkYXRhLT5sYXN0X3VwZGF0ZWQgKyBIWiAvIDQpIHx8ICFkYXRhLT52YWxpZCkgewor
CQlpbnQgdmFsOworCQlpbnQgaTsKKworCQkvKiBUcmlnZ2VyIEFEQywgYW55IHZhbHVlIHdpbGwg
ZG8gKi8KKwkJdmFsID0gbHRjMjk5MF93cml0ZShpMmMsIExUQzI5OTBfVFJJR0dFUiwgMSk7CisJ
CWlmICh1bmxpa2VseSh2YWwgPCAwKSkgeworCQkJcmV0ID0gRVJSX1BUUih2YWwpOworCQkJZ290
byBhYm9ydDsKKwkJfQorCisJCS8qIFdhaXQgZm9yIGNvbnZlcnNpb24gY29tcGxldGUgKi8KKwkJ
dGltZW91dCA9IDIwMDsKKwkJZm9yICg7OykgeworCQkJdXNsZWVwX3JhbmdlKDIwMDAsIDQwMDAp
OworCQkJdmFsID0gbHRjMjk5MF9yZWFkX2J5dGUoaTJjLCBMVEMyOTkwX1NUQVRVUyk7CisJCQlp
ZiAodW5saWtlbHkodmFsIDwgMCkpIHsKKwkJCQlyZXQgPSBFUlJfUFRSKHZhbCk7CisJCQkJZ290
byBhYm9ydDsKKwkJCX0KKwkJCS8qIFNpbmdsZS1zaG90IG1vZGUsIHdhaXQgZm9yIGNvbnZlcnNp
b24gdG8gY29tcGxldGUgKi8KKwkJCWlmICgodmFsICYgTFRDMjk5MF9TVEFUVVNfQlVTWSkgPT0g
MCkKKwkJCQlicmVhazsKKwkJCWlmICgtLXRpbWVvdXQgPT0gMCkgeworCQkJCXJldCA9IEVSUl9Q
VFIoLUVUSU1FRE9VVCk7CisJCQkJZ290byBhYm9ydDsKKwkJCX0KKwkJfQorCisJCS8qIFJlYWQg
YWxsIHJlZ2lzdGVycyAqLworCQlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShkYXRhLT52YWx1
ZXMpOyArK2kpIHsKKwkJCXZhbCA9IGx0YzI5OTBfcmVhZF93b3JkKGkyYywgKGk8PDEpICsgTFRD
Mjk5MF9USU5UX01TQik7CisJCQlpZiAodW5saWtlbHkodmFsIDwgMCkpIHsKKwkJCQlkZXZfZGJn
KGRldiwKKwkJCQkJIkZhaWxlZCB0byByZWFkIEFEQyB2YWx1ZTogZXJyb3IgJWRcbiIsCisJCQkJ
CXZhbCk7CisJCQkJcmV0ID0gRVJSX1BUUih2YWwpOworCQkJCWdvdG8gYWJvcnQ7CisJCQl9CisJ
CQlkYXRhLT52YWx1ZXNbaV0gPSB2YWwgJiAweDdGRkY7IC8qIFN0cmlwICduZXcnIGJpdCAqLwor
CQl9CisJCWRhdGEtPmxhc3RfdXBkYXRlZCA9IGppZmZpZXM7CisJCWRhdGEtPnZhbGlkID0gMTsK
KworCQkvKgorCQkgKiAgUXVpcms6IFNlY29uZCB0cmlnZ2VyIGlzIGlnbm9yZWQ/IEFmdGVyIHRo
aXMsIHRoZSBCVVNZIHdpbGwKKwkJICogc3RpbGwgYmUgc2V0IHRvICIwIiBhbmQgbm8gY29udmVy
c2lvbiBwZXJmb3JtZWQuCisJCSAqLworCQl2YWwgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5
MF9UUklHR0VSLCAwKTsKKwl9CithYm9ydDoKKwltdXRleF91bmxvY2soJmRhdGEtPnVwZGF0ZV9s
b2NrKTsKKwlyZXR1cm4gcmV0OworfQorCisvKiBSZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBm
cm9tIHRoZSBnaXZlbiByZWdpc3RlciBpbiB1ViBvciBtQyAqLworc3RhdGljIGludCBsdGMyOTkw
X2dldF92YWx1ZShzdHJ1Y3QgbHRjMjk5MF9kYXRhICpkYXRhLCB1OCBpbmRleCkKK3sKKwlzMzIg
cmVzdWx0OworCXMxNiB2OworCisJaWYgKGluZGV4ID09IDApIHsgLyogaW50ZXJuYWwgdGVtcCwg
MC4wNjI1IGRlZ3JlZXMvTFNCLCAxMi1iaXQgICovCisJCXYgPSBkYXRhLT52YWx1ZXNbaW5kZXhd
IDw8IDM7CisJCXJlc3VsdCA9IChzMzIpdiAqIDEwMDAgPj4gNzsKKwl9IGVsc2UgaWYgKGluZGV4
IDwgNSkgeyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IsIDE0LWJpdCAqLworCQl2ID0gZGF0YS0+dmFs
dWVzW2luZGV4XSA8PCAyOworCQlyZXN1bHQgPSAoczMyKXYgKiAxOTQyIC8gKDQgKiAxMDApOwor
CX0gZWxzZSB7IC8qIFZjYywgMzA1LjE4zrxWL0xTQiwgMi41ViBvZmZzZXQsIDE0LWJpdCAqLwor
CQl2ID0gZGF0YS0+dmFsdWVzW2luZGV4XSA8PCAyOworCQlyZXN1bHQgPSAoczMyKXYgKiAzMDUx
OCAvICg0ICogMTAwKTsKKwkJcmVzdWx0ICs9IDI1MDAwMDA7CisJfQorCXJldHVybiByZXN1bHQ7
Cit9CisKK3N0YXRpYyBzc2l6ZV90IGx0YzI5OTBfc2hvd192YWx1ZShzdHJ1Y3QgZGV2aWNlICpk
ZXYsCisJCQkJICBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGEsIGNoYXIgKmJ1ZikKK3sKKwlz
dHJ1Y3Qgc2Vuc29yX2RldmljZV9hdHRyaWJ1dGUgKmF0dHIgPSB0b19zZW5zb3JfZGV2X2F0dHIo
ZGEpOworCXN0cnVjdCBsdGMyOTkwX2RhdGEgKmRhdGEgPSBsdGMyOTkwX3VwZGF0ZV9kZXZpY2Uo
ZGV2KTsKKwlpbnQgdmFsdWU7CisKKwlpZiAoSVNfRVJSKGRhdGEpKQorCQlyZXR1cm4gUFRSX0VS
UihkYXRhKTsKKworCXZhbHVlID0gbHRjMjk5MF9nZXRfdmFsdWUoZGF0YSwgYXR0ci0+aW5kZXgp
OworCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7Cit9CisK
K3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcF9pbnQsIFNfSVJVR08sIGx0YzI5OTBfc2hv
d192YWx1ZSwgTlVMTCwgMCk7CitzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHYxdjJfZGlmZiwg
U19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLCAxKTsKK3N0YXRpYyBTRU5TT1JfREVW
SUNFX0FUVFIodjN2NF9kaWZmLCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsIDMp
Oworc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih2Y2MsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192
YWx1ZSwgTlVMTCwgNSk7CisKK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpsdGMyOTkwX2F0dHJp
YnV0ZXNbXSA9IHsKKwkmc2Vuc29yX2Rldl9hdHRyX3RlbXBfaW50LmRldl9hdHRyLmF0dHIsCisJ
JnNlbnNvcl9kZXZfYXR0cl92MXYyX2RpZmYuZGV2X2F0dHIuYXR0ciwKKwkmc2Vuc29yX2Rldl9h
dHRyX3YzdjRfZGlmZi5kZXZfYXR0ci5hdHRyLAorCSZzZW5zb3JfZGV2X2F0dHJfdmNjLmRldl9h
dHRyLmF0dHIsCisJTlVMTCwKK307CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dy
b3VwIGx0YzI5OTBfZ3JvdXAgPSB7CisJLmF0dHJzID0gbHRjMjk5MF9hdHRyaWJ1dGVzLAorfTsK
Kworc3RhdGljIGludCBsdGMyOTkwX2kyY19wcm9iZSgKKwlzdHJ1Y3QgaTJjX2NsaWVudCAqaTJj
LCBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCAqaWQpCit7CisJaW50IHJldDsKKwlzdHJ1Y3Qg
bHRjMjk5MF9kYXRhICpsdGMyOTkwOworCisJaWYgKCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0eShp
MmMtPmFkYXB0ZXIsIEkyQ19GVU5DX1NNQlVTX0JZVEVfREFUQSkpCisJCXJldHVybiAtRU5PREVW
OworCisJbHRjMjk5MCA9IGRldm1fa3phbGxvYygmaTJjLT5kZXYsCisJCXNpemVvZihzdHJ1Y3Qg
bHRjMjk5MF9kYXRhKSwgR0ZQX0tFUk5FTCk7CisJaWYgKGx0YzI5OTAgPT0gTlVMTCkKKwkJcmV0
dXJuIC1FTk9NRU07CisKKwlyZXQgPSBsdGMyOTkwX3JlYWRfYnl0ZShpMmMsIDApOworCWlmIChy
ZXQgPCAwKSB7CisJCWRldl9lcnIoJmkyYy0+ZGV2LCAiQ291bGQgbm90IHJlYWQgTFRDMjk5MCBv
biBpMmMgYnVzLlxuIik7CisJCXJldHVybiByZXQ7CisJfQorCXJldCA9IGx0YzI5OTBfd3JpdGUo
aTJjLCBMVEMyOTkwX0NPTlRST0wsCisJCUxUQzI5OTBfQ09OVFJPTF9TSU5HTEUgfCBMVEMyOTkw
X0NPTlRST0xfTUVBU1VSRV9BTEwgfAorCQlMVEMyOTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsK
KwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWlsZWQgdG8g
c2V0IGNvbnRyb2wgbW9kZS5cbiIpOworCQlyZXR1cm4gcmV0OworCX0KKworCW11dGV4X2luaXQo
Jmx0YzI5OTAtPnVwZGF0ZV9sb2NrKTsKKwlpMmNfc2V0X2NsaWVudGRhdGEoaTJjLCBsdGMyOTkw
KTsKKworCS8qIFJlZ2lzdGVyIHN5c2ZzIGhvb2tzICovCisJcmV0ID0gc3lzZnNfY3JlYXRlX2dy
b3VwKCZpMmMtPmRldi5rb2JqLCAmbHRjMjk5MF9ncm91cCk7CisJaWYgKHJldCkKKwkJcmV0dXJu
IHJldDsKKworCWx0YzI5OTAtPmh3bW9uX2RldiA9IGh3bW9uX2RldmljZV9yZWdpc3RlcigmaTJj
LT5kZXYpOworCWlmIChJU19FUlIobHRjMjk5MC0+aHdtb25fZGV2KSkgeworCQlyZXQgPSBQVFJf
RVJSKGx0YzI5OTAtPmh3bW9uX2Rldik7CisJCWdvdG8gb3V0X2h3bW9uX2RldmljZV9yZWdpc3Rl
cjsKKwl9CisKKwlyZXR1cm4gMDsKKworb3V0X2h3bW9uX2RldmljZV9yZWdpc3RlcjoKKwlzeXNm
c19yZW1vdmVfZ3JvdXAoJmkyYy0+ZGV2LmtvYmosICZsdGMyOTkwX2dyb3VwKTsKKwlyZXR1cm4g
cmV0OworfQorCitzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3JlbW92ZShzdHJ1Y3QgaTJjX2NsaWVu
dCAqaTJjKQoreworCXN0cnVjdCBsdGMyOTkwX2RhdGEgKmx0YzI5OTAgPSBpMmNfZ2V0X2NsaWVu
dGRhdGEoaTJjKTsKKworCWh3bW9uX2RldmljZV91bnJlZ2lzdGVyKGx0YzI5OTAtPmh3bW9uX2Rl
dik7CisJc3lzZnNfcmVtb3ZlX2dyb3VwKCZpMmMtPmRldi5rb2JqLCAmbHRjMjk5MF9ncm91cCk7
CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCBsdGMy
OTkwX2kyY19pZFtdID0geworCXsgImx0YzI5OTAiLCAwIH0sCisJe30KK307CitNT0RVTEVfREVW
SUNFX1RBQkxFKGkyYywgbHRjMjk5MF9pMmNfaWQpOworCitzdGF0aWMgc3RydWN0IGkyY19kcml2
ZXIgbHRjMjk5MF9pMmNfZHJpdmVyID0geworCS5kcml2ZXIgPSB7CisJCS5uYW1lID0gImx0YzI5
OTAiLAorCX0sCisJLnByb2JlICAgID0gbHRjMjk5MF9pMmNfcHJvYmUsCisJLnJlbW92ZSAgID0g
bHRjMjk5MF9pMmNfcmVtb3ZlLAorCS5pZF90YWJsZSA9IGx0YzI5OTBfaTJjX2lkLAorfTsKKwor
bW9kdWxlX2kyY19kcml2ZXIobHRjMjk5MF9pMmNfZHJpdmVyKTsKKworTU9EVUxFX0RFU0NSSVBU
SU9OKCJMVEMyOTkwIFNlbnNvciBEcml2ZXIiKTsKK01PRFVMRV9BVVRIT1IoIlRvcGljIEVtYmVk
ZGVkIFByb2R1Y3RzIik7CitNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Ci0tIAoxLjkuMQoKCl9f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxtLXNlbnNvcnMg
bWFpbGluZyBsaXN0CmxtLXNlbnNvcnNAbG0tc2Vuc29ycy5vcmcKaHR0cDovL2xpc3RzLmxtLXNl
bnNvcnMub3JnL21haWxtYW4vbGlzdGluZm8vbG0tc2Vuc29ycw=

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

* Re: [PATCH] hwmon: Add LTC2990 sensor driver
  2016-01-06  8:07 ` [lm-sensors] " Mike Looijmans
  (?)
@ 2016-01-06 15:22 ` Guenter Roeck
  2016-01-07 18:59     ` [lm-sensors] " Mike Looijmans
  -1 siblings, 1 reply; 29+ messages in thread
From: Guenter Roeck @ 2016-01-06 15:22 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

Hello Mike,

On 01/06/2016 12:07 AM, Mike Looijmans wrote:
> This adds support for the Linear Technology LTC2990  I2C System Monitor.

s/  / /

> The LTC2990 supports a combination of voltage, current and temperature
> monitoring, but this driver currently only supports reading two currents
> by measuring two differential voltages across series resistors.
>
Plus VCC, plus the internal temperature.

> This is sufficient to support the Topic Miami SOM which uses this chip
> to monitor the currents flowing into the FPGA and the CPU parts.
>
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
> ---
>   drivers/hwmon/Kconfig   |  15 +++
>   drivers/hwmon/Makefile  |   1 +
>   drivers/hwmon/ltc2990.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++++

Please also provide Documentation/hwmon/ltc2990.

Also, please read and follow Documentation/hwmon/submitting-patches.

>   3 files changed, 289 insertions(+)
>   create mode 100644 drivers/hwmon/ltc2990.c
>
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 80a73bf..b3eef31 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -685,6 +685,21 @@ config SENSORS_LTC2945
>   	  This driver can also be built as a module. If so, the module will
>   	  be called ltc2945.
>
> +config SENSORS_LTC2990
> +	tristate "Linear Technology LTC2990 (current monitoring mode only)"
> +	depends on I2C
> +	select REGMAP_I2C

Using regmap for the driver might be a good idea, but you don't.

> +	default n

Not necessary.

> +	help
> +	  If you say yes here you get support for Linear Technology LTC2990
> +	  I2C System Monitor. The LTC2990 supports a combination of voltage,
> +	  current and temperature monitoring, but this driver currently only
> +	  supports reading two currents by measuring two differential voltages
> +	  across series resistors.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called ltc2990.
> +
>   config SENSORS_LTC4151
>   	tristate "Linear Technology LTC4151"
>   	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 12a3239..e4bd15b 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
>   obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
>   obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
>   obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
> +obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
>   obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
>   obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
>   obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> new file mode 100644
> index 0000000..161d995
> --- /dev/null
> +++ b/drivers/hwmon/ltc2990.c
> @@ -0,0 +1,273 @@
> +/*
> + * driver for Linear Technology LTC2990 power monitor

Driver

> + *
> + * Copyright (C) 2014 Topic Embedded Products

2015 ?

> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
> + *
> + * License: GPLv2
> + *
> + * This driver assumes the chip is wired as a dual current monitor, and
> + * reports the voltage drop across two series resistors.

It also monitors the temperature and VCC.

> + */
> +
> +#include <linux/bug.h>

Is this used anywhere in the driver ?

> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#define LTC2990_STATUS	0x00
> +#define LTC2990_CONTROL	0x01
> +#define LTC2990_TRIGGER	0x02
> +#define LTC2990_TINT_MSB	0x04
> +#define LTC2990_TINT_LSB	0x05
> +#define LTC2990_V1_MSB	0x06
> +#define LTC2990_V1_LSB	0x07
> +#define LTC2990_V2_MSB	0x08
> +#define LTC2990_V2_LSB	0x09
> +#define LTC2990_V3_MSB	0x0A
> +#define LTC2990_V3_LSB	0x0B
> +#define LTC2990_V4_MSB	0x0C
> +#define LTC2990_V4_LSB	0x0D
> +#define LTC2990_VCC_MSB	0x0E
> +#define LTC2990_VCC_LSB	0x0F
> +
> +#define LTC2990_STATUS_BUSY	BIT(0)
> +#define LTC2990_STATUS_TINT	BIT(1)
> +#define LTC2990_STATUS_V1	BIT(2)
> +#define LTC2990_STATUS_V2	BIT(3)
> +#define LTC2990_STATUS_V3	BIT(4)
> +#define LTC2990_STATUS_V4	BIT(5)
> +#define LTC2990_STATUS_VCC	BIT(6)
> +
> +/* Only define control settings we actually use */
> +#define LTC2990_CONTROL_KELVIN		BIT(7)
> +#define LTC2990_CONTROL_SINGLE		BIT(6)
> +#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
> +#define LTC2990_CONTROL_MODE_CURRENT	0x06
> +#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
> +
> +struct ltc2990_data {
> +	struct device *hwmon_dev;
> +	struct mutex update_lock;
> +	unsigned long last_updated;
> +	short values[6];

u16 ?

> +	bool valid;
> +	u8 update_counter;

Not used anywhere.

> +};
> +
> +static int ltc2990_write(struct i2c_client *i2c, u8 reg, u8 value)
> +{
> +	return i2c_smbus_write_byte_data(i2c, reg, value);
> +}
> +
> +static int ltc2990_read_byte(struct i2c_client *i2c, u8 reg)
> +{
> +	return i2c_smbus_read_byte_data(i2c, reg);
> +}
> +

Useless shim functions.

> +static int ltc2990_read_word(struct i2c_client *i2c, u8 reg)
> +{
> +	int result = i2c_smbus_read_word_data(i2c, reg);
> +	/* Result is MSB first, but smbus specs say LSB first, so swap the
> +	 * result */

Bad multi-line comment.

> +	return result < 0 ? result : swab16(result);

Please use i2c_smbus_read_word_swapped() and drop the shim function.

> +}
> +
> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
> +{
> +	struct i2c_client *i2c = to_i2c_client(dev);
> +	struct ltc2990_data *data = i2c_get_clientdata(i2c);
> +	struct ltc2990_data *ret = data;
> +	unsigned int timeout;
> +
> +	mutex_lock(&data->update_lock);
> +
> +	/* Update about 4 times per second max */
> +	if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) {
> +		int val;
> +		int i;
> +

Please consider using continuous conversion. This would simplify the code significantly
and reduce read delays.

> +		/* Trigger ADC, any value will do */
> +		val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
> +		if (unlikely(val < 0)) {
> +			ret = ERR_PTR(val);
> +			goto abort;
> +		}
> +
> +		/* Wait for conversion complete */
> +		timeout = 200;
> +		for (;;) {
> +			usleep_range(2000, 4000);
> +			val = ltc2990_read_byte(i2c, LTC2990_STATUS);
> +			if (unlikely(val < 0)) {
> +				ret = ERR_PTR(val);
> +				goto abort;
> +			}
> +			/* Single-shot mode, wait for conversion to complete */
> +			if ((val & LTC2990_STATUS_BUSY) == 0)

			if (!(...))

> +				break;
> +			if (--timeout == 0) {
> +				ret = ERR_PTR(-ETIMEDOUT);
> +				goto abort;
> +			}
> +		}

Again, please consider using continuous conversion mode.

If this is not feasible for some reason, you might as well just wait for the
minimum conversion time before trying to read for the first time. If so,
please use a fixed timeout by comparing the elapsed time instead of looping
for a maximum number of times. Not even counting the time for executing the
code, the maximum delay is between 400 ms and 800 ms, which is way too high
(chip spec says 167 ms worst case, if three temperature sensors are configured).

> +
> +		/* Read all registers */
> +		for (i = 0; i < ARRAY_SIZE(data->values); ++i) {
> +			val = ltc2990_read_word(i2c, (i<<1) + LTC2990_TINT_MSB);

Missing spaces around <<

> +			if (unlikely(val < 0)) {
> +				dev_dbg(dev,
> +					"Failed to read ADC value: error %d\n",
> +					val);
> +				ret = ERR_PTR(val);
> +				goto abort;
> +			}
> +			data->values[i] = val & 0x7FFF; /* Strip 'new' bit */

The bit is never evaluated, so you might as well store the raw value.

> +		}
> +		data->last_updated = jiffies;
> +		data->valid = 1;

	= true;

> +
> +		/*
> +		 *  Quirk: Second trigger is ignored? After this, the BUSY will
> +		 * still be set to "0" and no conversion performed.
> +		 */
> +		val = ltc2990_write(i2c, LTC2990_TRIGGER, 0);
> +	}
> +abort:
> +	mutex_unlock(&data->update_lock);
> +	return ret;
> +}
> +
> +/* Return the converted value from the given register in uV or mC */
> +static int ltc2990_get_value(struct ltc2990_data *data, u8 index)
> +{
> +	s32 result;
> +	s16 v;
> +
> +	if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 12-bit  */
> +		v = data->values[index] << 3;
> +		result = (s32)v * 1000 >> 7;
> +	} else if (index < 5) { /* Vx-Vy, 19.42uV/LSB, 14-bit */
> +		v = data->values[index] << 2;

Datasheet says that the sign bit is in bit 14, so this drops the sign bit.

> +		result = (s32)v * 1942 / (4 * 100);
> +	} else { /* Vcc, 305.18μV/LSB, 2.5V offset, 14-bit */
> +		v = data->values[index] << 2;
> +		result = (s32)v * 30518 / (4 * 100);
> +		result += 2500000;
> +	}
> +	return result;
> +}
> +
> +static ssize_t ltc2990_show_value(struct device *dev,
> +				  struct device_attribute *da, char *buf)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +	struct ltc2990_data *data = ltc2990_update_device(dev);
> +	int value;
> +
> +	if (IS_ERR(data))
> +		return PTR_ERR(data);
> +
> +	value = ltc2990_get_value(data, attr->index);
> +	return snprintf(buf, PAGE_SIZE, "%d\n", value);
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp_int, S_IRUGO, ltc2990_show_value, NULL, 0);
> +static SENSOR_DEVICE_ATTR(v1v2_diff, S_IRUGO, ltc2990_show_value, NULL, 1);
> +static SENSOR_DEVICE_ATTR(v3v4_diff, S_IRUGO, ltc2990_show_value, NULL, 3);
> +static SENSOR_DEVICE_ATTR(vcc, S_IRUGO, ltc2990_show_value, NULL, 5);
> +

Please use standard attribute names (and units) as per Documentation/hwmon/sysfs-interface.

> +static struct attribute *ltc2990_attributes[] = {
> +	&sensor_dev_attr_temp_int.dev_attr.attr,
> +	&sensor_dev_attr_v1v2_diff.dev_attr.attr,
> +	&sensor_dev_attr_v3v4_diff.dev_attr.attr,
> +	&sensor_dev_attr_vcc.dev_attr.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group ltc2990_group = {
> +	.attrs = ltc2990_attributes,
> +};
> +

Please use the ATTRIBUTE_GROUPS() macro. Also see below.

> +static int ltc2990_i2c_probe(
> +	struct i2c_client *i2c, const struct i2c_device_id *id)

Please split as

static int ltc2990_i2c_probe(struct i2c_client *i2c,
			     const struct i2c_device_id *id)

> +{
> +	int ret;
> +	struct ltc2990_data *ltc2990;
> +
> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
> +		return -ENODEV;
> +
> +	ltc2990 = devm_kzalloc(&i2c->dev,
> +		sizeof(struct ltc2990_data), GFP_KERNEL);

Please align continuation lines with '('.

> +	if (ltc2990 == NULL)
> +		return -ENOMEM;
> +
> +	ret = ltc2990_read_byte(i2c, 0);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Could not read LTC2990 on i2c bus.\n");
> +		return ret;
> +	}

The write below would also return an error if the chip isn't there,
so this additional read does not provide any real value.

> +	ret = ltc2990_write(i2c, LTC2990_CONTROL,
> +		LTC2990_CONTROL_SINGLE | LTC2990_CONTROL_MEASURE_ALL |
> +		LTC2990_CONTROL_MODE_CURRENT);

I'll have to think about this. While it addresses your use case,
it limits the scope of this driver significantly. Looking into the board
specifications, you might as well do it right and determine (and set)
the correct configuration using devicetree data instead of forcing your
use case on everyone.

Sure, you may argue that you don't care, but we will be the ones who will have
to handle error reports that the driver unexpectedly changes the configuration
in other use cases (where, for example, the mode may have been pre-set by
the BIOS or ROMMON).

> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
> +		return ret;
> +	}
> +
> +	mutex_init(&ltc2990->update_lock);
> +	i2c_set_clientdata(i2c, ltc2990);
> +
> +	/* Register sysfs hooks */
> +	ret = sysfs_create_group(&i2c->dev.kobj, &ltc2990_group);
> +	if (ret)
> +		return ret;
> +
> +	ltc2990->hwmon_dev = hwmon_device_register(&i2c->dev);

Please use devm_hwmon_device_register_with_groups().

> +	if (IS_ERR(ltc2990->hwmon_dev)) {
> +		ret = PTR_ERR(ltc2990->hwmon_dev);
> +		goto out_hwmon_device_register;
> +	}
> +
> +	return 0;
> +
> +out_hwmon_device_register:
> +	sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
> +	return ret;
> +}
> +
> +static int ltc2990_i2c_remove(struct i2c_client *i2c)
> +{
> +	struct ltc2990_data *ltc2990 = i2c_get_clientdata(i2c);
> +
> +	hwmon_device_unregister(ltc2990->hwmon_dev);
> +	sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
> +	return 0;
> +}
> +
> +static const struct i2c_device_id ltc2990_i2c_id[] = {
> +	{ "ltc2990", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
> +
> +static struct i2c_driver ltc2990_i2c_driver = {
> +	.driver = {
> +		.name = "ltc2990",
> +	},
> +	.probe    = ltc2990_i2c_probe,
> +	.remove   = ltc2990_i2c_remove,
> +	.id_table = ltc2990_i2c_id,
> +};
> +
> +module_i2c_driver(ltc2990_i2c_driver);
> +
> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
> +MODULE_AUTHOR("Topic Embedded Products");
> +MODULE_LICENSE("GPL v2");
>


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

* Re: [PATCH] hwmon: Add LTC2990 sensor driver
  2016-01-06 15:22 ` Guenter Roeck
@ 2016-01-07 18:59     ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-07 18:59 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

Thank you very much for your review comments, I'll update the driver and 
post a v2 patch.

Inlined some replies below. Assume that I "will do" for all comments I 
didn't comment on inline...

On 06-01-16 16:22, Guenter Roeck wrote:
> Hello Mike,
>
> On 01/06/2016 12:07 AM, Mike Looijmans wrote:
>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>
> s/  / /
>
>> The LTC2990 supports a combination of voltage, current and temperature
>> monitoring, but this driver currently only supports reading two currents
>> by measuring two differential voltages across series resistors.
>>
> Plus VCC, plus the internal temperature.

Yeah, I should give myself more credit :) I'll add that in Kconfig too.

>> This is sufficient to support the Topic Miami SOM which uses this chip
>> to monitor the currents flowing into the FPGA and the CPU parts.
>>
>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>> ---
>>   drivers/hwmon/Kconfig   |  15 +++
>>   drivers/hwmon/Makefile  |   1 +
>>   drivers/hwmon/ltc2990.c | 273
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>
> Please also provide Documentation/hwmon/ltc2990.
>
> Also, please read and follow Documentation/hwmon/submitting-patches.
>
>>   3 files changed, 289 insertions(+)
>>   create mode 100644 drivers/hwmon/ltc2990.c
>>
>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
>> index 80a73bf..b3eef31 100644
>> --- a/drivers/hwmon/Kconfig
>> +++ b/drivers/hwmon/Kconfig
>> @@ -685,6 +685,21 @@ config SENSORS_LTC2945
>>         This driver can also be built as a module. If so, the module will
>>         be called ltc2945.
>>
>> +config SENSORS_LTC2990
>> +    tristate "Linear Technology LTC2990 (current monitoring mode only)"
>> +    depends on I2C
>> +    select REGMAP_I2C
>
> Using regmap for the driver might be a good idea, but you don't.

Looking at the regmap, the driver only writes the one cachable register 
once, the "control". All the other registers cannot be cached, are 
either read-only or write-only. Don't think regmap will help, so I'll 
remove the "select" here.

>> +    default n
>
> Not necessary.
>
>> +    help
>> +      If you say yes here you get support for Linear Technology LTC2990
>> +      I2C System Monitor. The LTC2990 supports a combination of voltage,
>> +      current and temperature monitoring, but this driver currently only
>> +      supports reading two currents by measuring two differential
>> voltages
>> +      across series resistors.
>> +
>> +      This driver can also be built as a module. If so, the module will
>> +      be called ltc2990.
>> +
>>   config SENSORS_LTC4151
>>       tristate "Linear Technology LTC4151"
>>       depends on I2C
>> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
>> index 12a3239..e4bd15b 100644
>> --- a/drivers/hwmon/Makefile
>> +++ b/drivers/hwmon/Makefile
>> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)    += lm95234.o
>>   obj-$(CONFIG_SENSORS_LM95241)    += lm95241.o
>>   obj-$(CONFIG_SENSORS_LM95245)    += lm95245.o
>>   obj-$(CONFIG_SENSORS_LTC2945)    += ltc2945.o
>> +obj-$(CONFIG_SENSORS_LTC2990)    += ltc2990.o
>>   obj-$(CONFIG_SENSORS_LTC4151)    += ltc4151.o
>>   obj-$(CONFIG_SENSORS_LTC4215)    += ltc4215.o
>>   obj-$(CONFIG_SENSORS_LTC4222)    += ltc4222.o
>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>> new file mode 100644
>> index 0000000..161d995
>> --- /dev/null
>> +++ b/drivers/hwmon/ltc2990.c
>> @@ -0,0 +1,273 @@
>> +/*
>> + * driver for Linear Technology LTC2990 power monitor
>
> Driver
>
>> + *
>> + * Copyright (C) 2014 Topic Embedded Products
>
> 2015 ?

I wrote the driver early last year. I only did some cosmetic cleanup and 
rebase on master before submitting.

>
>> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
>> + *
>> + * License: GPLv2
>> + *
>> + * This driver assumes the chip is wired as a dual current monitor, and
>> + * reports the voltage drop across two series resistors.
>
> It also monitors the temperature and VCC.
>
>> + */
>> +
>> +#include <linux/bug.h>
>
> Is this used anywhere in the driver ?

Not any more...

>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/hwmon.h>
>> +#include <linux/hwmon-sysfs.h>
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +
>> +#define LTC2990_STATUS    0x00
>> +#define LTC2990_CONTROL    0x01
>> +#define LTC2990_TRIGGER    0x02
>> +#define LTC2990_TINT_MSB    0x04
>> +#define LTC2990_TINT_LSB    0x05
>> +#define LTC2990_V1_MSB    0x06
>> +#define LTC2990_V1_LSB    0x07
>> +#define LTC2990_V2_MSB    0x08
>> +#define LTC2990_V2_LSB    0x09
>> +#define LTC2990_V3_MSB    0x0A
>> +#define LTC2990_V3_LSB    0x0B
>> +#define LTC2990_V4_MSB    0x0C
>> +#define LTC2990_V4_LSB    0x0D
>> +#define LTC2990_VCC_MSB    0x0E
>> +#define LTC2990_VCC_LSB    0x0F
>> +
>> +#define LTC2990_STATUS_BUSY    BIT(0)
>> +#define LTC2990_STATUS_TINT    BIT(1)
>> +#define LTC2990_STATUS_V1    BIT(2)
>> +#define LTC2990_STATUS_V2    BIT(3)
>> +#define LTC2990_STATUS_V3    BIT(4)
>> +#define LTC2990_STATUS_V4    BIT(5)
>> +#define LTC2990_STATUS_VCC    BIT(6)
>> +
>> +/* Only define control settings we actually use */
>> +#define LTC2990_CONTROL_KELVIN        BIT(7)
>> +#define LTC2990_CONTROL_SINGLE        BIT(6)
>> +#define LTC2990_CONTROL_MEASURE_ALL    (0x3 << 3)
>> +#define LTC2990_CONTROL_MODE_CURRENT    0x06
>> +#define LTC2990_CONTROL_MODE_VOLTAGE    0x07
>> +
>> +struct ltc2990_data {
>> +    struct device *hwmon_dev;
>> +    struct mutex update_lock;
>> +    unsigned long last_updated;
>> +    short values[6];
>
> u16 ?
>
>> +    bool valid;
>> +    u8 update_counter;
>
> Not used anywhere.
>
>> +};
>> +
>> +static int ltc2990_write(struct i2c_client *i2c, u8 reg, u8 value)
>> +{
>> +    return i2c_smbus_write_byte_data(i2c, reg, value);
>> +}
>> +
>> +static int ltc2990_read_byte(struct i2c_client *i2c, u8 reg)
>> +{
>> +    return i2c_smbus_read_byte_data(i2c, reg);
>> +}
>> +
>
> Useless shim functions.

True, should have removed them after refactoring them into one-liners.
They were convenient early on.

>
>> +static int ltc2990_read_word(struct i2c_client *i2c, u8 reg)
>> +{
>> +    int result = i2c_smbus_read_word_data(i2c, reg);
>> +    /* Result is MSB first, but smbus specs say LSB first, so swap the
>> +     * result */
>
> Bad multi-line comment.
>
>> +    return result < 0 ? result : swab16(result);
>
> Please use i2c_smbus_read_word_swapped() and drop the shim function.
>
>> +}
>> +
>> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
>> +{
>> +    struct i2c_client *i2c = to_i2c_client(dev);
>> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);
>> +    struct ltc2990_data *ret = data;
>> +    unsigned int timeout;
>> +
>> +    mutex_lock(&data->update_lock);
>> +
>> +    /* Update about 4 times per second max */
>> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||
>> !data->valid) {
>> +        int val;
>> +        int i;
>> +
>
> Please consider using continuous conversion. This would simplify the
> code significantly
> and reduce read delays.

It might increase power consumption though, as typically some user 
program would poll this every 10 seconds or so. I'll check the data sheet.

>> +        /* Trigger ADC, any value will do */
>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
>> +        if (unlikely(val < 0)) {
>> +            ret = ERR_PTR(val);
>> +            goto abort;
>> +        }
>> +
>> +        /* Wait for conversion complete */
>> +        timeout = 200;
>> +        for (;;) {
>> +            usleep_range(2000, 4000);
>> +            val = ltc2990_read_byte(i2c, LTC2990_STATUS);
>> +            if (unlikely(val < 0)) {
>> +                ret = ERR_PTR(val);
>> +                goto abort;
>> +            }
>> +            /* Single-shot mode, wait for conversion to complete */
>> +            if ((val & LTC2990_STATUS_BUSY) == 0)
>
>              if (!(...))
>
>> +                break;
>> +            if (--timeout == 0) {
>> +                ret = ERR_PTR(-ETIMEDOUT);
>> +                goto abort;
>> +            }
>> +        }
>
> Again, please consider using continuous conversion mode.
>
> If this is not feasible for some reason, you might as well just wait for
> the
> minimum conversion time before trying to read for the first time. If so,
> please use a fixed timeout by comparing the elapsed time instead of looping
> for a maximum number of times. Not even counting the time for executing the
> code, the maximum delay is between 400 ms and 800 ms, which is way too high
> (chip spec says 167 ms worst case, if three temperature sensors are
> configured).

Or maybe I should just sleep for 167ms and be done with it. Though I 
think I'l got with your minimal time first suggestion.

>> +
>> +        /* Read all registers */
>> +        for (i = 0; i < ARRAY_SIZE(data->values); ++i) {
>> +            val = ltc2990_read_word(i2c, (i<<1) + LTC2990_TINT_MSB);
>
> Missing spaces around <<
>
>> +            if (unlikely(val < 0)) {
>> +                dev_dbg(dev,
>> +                    "Failed to read ADC value: error %d\n",
>> +                    val);
>> +                ret = ERR_PTR(val);
>> +                goto abort;
>> +            }
>> +            data->values[i] = val & 0x7FFF; /* Strip 'new' bit */
>
> The bit is never evaluated, so you might as well store the raw value.
>
>> +        }
>> +        data->last_updated = jiffies;
>> +        data->valid = 1;
>
>      = true;
>
>> +
>> +        /*
>> +         *  Quirk: Second trigger is ignored? After this, the BUSY will
>> +         * still be set to "0" and no conversion performed.
>> +         */
>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 0);
>> +    }
>> +abort:
>> +    mutex_unlock(&data->update_lock);
>> +    return ret;
>> +}
>> +
>> +/* Return the converted value from the given register in uV or mC */
>> +static int ltc2990_get_value(struct ltc2990_data *data, u8 index)
>> +{
>> +    s32 result;
>> +    s16 v;
>> +
>> +    if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 12-bit  */
>> +        v = data->values[index] << 3;
>> +        result = (s32)v * 1000 >> 7;
>> +    } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB, 14-bit */
>> +        v = data->values[index] << 2;
>
> Datasheet says that the sign bit is in bit 14, so this drops the sign bit.

I'll check the data sheet, would not have noticed this since current 
doesn't tend to run from the CPU back into the battery :)

>> +        result = (s32)v * 1942 / (4 * 100);
>> +    } else { /* Vcc, 305.18μV/LSB, 2.5V offset, 14-bit */
>> +        v = data->values[index] << 2;
>> +        result = (s32)v * 30518 / (4 * 100);
>> +        result += 2500000;
>> +    }
>> +    return result;
>> +}
>> +
>> +static ssize_t ltc2990_show_value(struct device *dev,
>> +                  struct device_attribute *da, char *buf)
>> +{
>> +    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>> +    struct ltc2990_data *data = ltc2990_update_device(dev);
>> +    int value;
>> +
>> +    if (IS_ERR(data))
>> +        return PTR_ERR(data);
>> +
>> +    value = ltc2990_get_value(data, attr->index);
>> +    return snprintf(buf, PAGE_SIZE, "%d\n", value);
>> +}
>> +
>> +static SENSOR_DEVICE_ATTR(temp_int, S_IRUGO, ltc2990_show_value,
>> NULL, 0);
>> +static SENSOR_DEVICE_ATTR(v1v2_diff, S_IRUGO, ltc2990_show_value,
>> NULL, 1);
>> +static SENSOR_DEVICE_ATTR(v3v4_diff, S_IRUGO, ltc2990_show_value,
>> NULL, 3);
>> +static SENSOR_DEVICE_ATTR(vcc, S_IRUGO, ltc2990_show_value, NULL, 5);
>> +
>
> Please use standard attribute names (and units) as per
> Documentation/hwmon/sysfs-interface.
>
>> +static struct attribute *ltc2990_attributes[] = {
>> +    &sensor_dev_attr_temp_int.dev_attr.attr,
>> +    &sensor_dev_attr_v1v2_diff.dev_attr.attr,
>> +    &sensor_dev_attr_v3v4_diff.dev_attr.attr,
>> +    &sensor_dev_attr_vcc.dev_attr.attr,
>> +    NULL,
>> +};
>> +
>> +static const struct attribute_group ltc2990_group = {
>> +    .attrs = ltc2990_attributes,
>> +};
>> +
>
> Please use the ATTRIBUTE_GROUPS() macro. Also see below.

Okay, will RTFM.

>
>> +static int ltc2990_i2c_probe(
>> +    struct i2c_client *i2c, const struct i2c_device_id *id)
>
> Please split as
>
> static int ltc2990_i2c_probe(struct i2c_client *i2c,
>                   const struct i2c_device_id *id)
>
>> +{
>> +    int ret;
>> +    struct ltc2990_data *ltc2990;
>> +
>> +    if (!i2c_check_functionality(i2c->adapter,
>> I2C_FUNC_SMBUS_BYTE_DATA))
>> +        return -ENODEV;
>> +
>> +    ltc2990 = devm_kzalloc(&i2c->dev,
>> +        sizeof(struct ltc2990_data), GFP_KERNEL);
>
> Please align continuation lines with '('.
>
>> +    if (ltc2990 == NULL)
>> +        return -ENOMEM;
>> +
>> +    ret = ltc2990_read_byte(i2c, 0);
>> +    if (ret < 0) {
>> +        dev_err(&i2c->dev, "Could not read LTC2990 on i2c bus.\n");
>> +        return ret;
>> +    }
>
> The write below would also return an error if the chip isn't there,
> so this additional read does not provide any real value.
>
>> +    ret = ltc2990_write(i2c, LTC2990_CONTROL,
>> +        LTC2990_CONTROL_SINGLE | LTC2990_CONTROL_MEASURE_ALL |
>> +        LTC2990_CONTROL_MODE_CURRENT);
>
> I'll have to think about this. While it addresses your use case,
> it limits the scope of this driver significantly. Looking into the board
> specifications, you might as well do it right and determine (and set)
> the correct configuration using devicetree data instead of forcing your
> use case on everyone.
>
> Sure, you may argue that you don't care, but we will be the ones who
> will have
> to handle error reports that the driver unexpectedly changes the
> configuration
> in other use cases (where, for example, the mode may have been pre-set by
> the BIOS or ROMMON).

The reason I didn't submit the driver last year was that I was still 
thinking about it. On the other hand, a limited driver is still much 
better than no driver at all, so that made me post it, with the added 
remarks about the driver being limited.

Adding the other functions it quite a bit more work than just writing 
this register. It also changes the properties to be exported to sysfs, 
and the calculation of the end values.

>
>> +    if (ret < 0) {
>> +        dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
>> +        return ret;
>> +    }
>> +
>> +    mutex_init(&ltc2990->update_lock);
>> +    i2c_set_clientdata(i2c, ltc2990);
>> +
>> +    /* Register sysfs hooks */
>> +    ret = sysfs_create_group(&i2c->dev.kobj, &ltc2990_group);
>> +    if (ret)
>> +        return ret;
>> +
>> +    ltc2990->hwmon_dev = hwmon_device_register(&i2c->dev);
>
> Please use devm_hwmon_device_register_with_groups().
>
>> +    if (IS_ERR(ltc2990->hwmon_dev)) {
>> +        ret = PTR_ERR(ltc2990->hwmon_dev);
>> +        goto out_hwmon_device_register;
>> +    }
>> +
>> +    return 0;
>> +
>> +out_hwmon_device_register:
>> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
>> +    return ret;
>> +}
>> +
>> +static int ltc2990_i2c_remove(struct i2c_client *i2c)
>> +{
>> +    struct ltc2990_data *ltc2990 = i2c_get_clientdata(i2c);
>> +
>> +    hwmon_device_unregister(ltc2990->hwmon_dev);
>> +    sysfs_remove_group(&i2c->dev.kobj, &ltc2990_group);
>> +    return 0;
>> +}
>> +
>> +static const struct i2c_device_id ltc2990_i2c_id[] = {
>> +    { "ltc2990", 0 },
>> +    {}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
>> +
>> +static struct i2c_driver ltc2990_i2c_driver = {
>> +    .driver = {
>> +        .name = "ltc2990",
>> +    },
>> +    .probe    = ltc2990_i2c_probe,
>> +    .remove   = ltc2990_i2c_remove,
>> +    .id_table = ltc2990_i2c_id,
>> +};
>> +
>> +module_i2c_driver(ltc2990_i2c_driver);
>> +
>> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
>> +MODULE_AUTHOR("Topic Embedded Products");
>> +MODULE_LICENSE("GPL v2");
>>
>


-- 
Mike Looijmans

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

* Re: [lm-sensors] [PATCH] hwmon: Add LTC2990 sensor driver
@ 2016-01-07 18:59     ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-07 18:59 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

VGhhbmsgeW91IHZlcnkgbXVjaCBmb3IgeW91ciByZXZpZXcgY29tbWVudHMsIEknbGwgdXBkYXRl
IHRoZSBkcml2ZXIgYW5kIApwb3N0IGEgdjIgcGF0Y2guCgpJbmxpbmVkIHNvbWUgcmVwbGllcyBi
ZWxvdy4gQXNzdW1lIHRoYXQgSSAid2lsbCBkbyIgZm9yIGFsbCBjb21tZW50cyBJIApkaWRuJ3Qg
Y29tbWVudCBvbiBpbmxpbmUuLi4KCk9uIDA2LTAxLTE2IDE2OjIyLCBHdWVudGVyIFJvZWNrIHdy
b3RlOgo+IEhlbGxvIE1pa2UsCj4KPiBPbiAwMS8wNi8yMDE2IDEyOjA3IEFNLCBNaWtlIExvb2lq
bWFucyB3cm90ZToKPj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9n
eSBMVEMyOTkwICBJMkMgU3lzdGVtIE1vbml0b3IuCj4KPiBzLyAgLyAvCj4KPj4gVGhlIExUQzI5
OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBjdXJyZW50IGFuZCB0ZW1wZXJh
dHVyZQo+PiBtb25pdG9yaW5nLCBidXQgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9y
dHMgcmVhZGluZyB0d28gY3VycmVudHMKPj4gYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwg
dm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+Cj4gUGx1cyBWQ0MsIHBsdXMgdGhl
IGludGVybmFsIHRlbXBlcmF0dXJlLgoKWWVhaCwgSSBzaG91bGQgZ2l2ZSBteXNlbGYgbW9yZSBj
cmVkaXQgOikgSSdsbCBhZGQgdGhhdCBpbiBLY29uZmlnIHRvby4KCj4+IFRoaXMgaXMgc3VmZmlj
aWVudCB0byBzdXBwb3J0IHRoZSBUb3BpYyBNaWFtaSBTT00gd2hpY2ggdXNlcyB0aGlzIGNoaXAK
Pj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRoZSBGUEdBIGFuZCB0aGUg
Q1BVIHBhcnRzLgo+Pgo+PiBTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29p
am1hbnNAdG9waWMubmw+Cj4+IC0tLQo+PiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgIHwgIDE1
ICsrKwo+PiAgIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3
bW9uL2x0YzI5OTAuYyB8IDI3Mwo+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysKPgo+IFBsZWFzZSBhbHNvIHByb3ZpZGUgRG9jdW1lbnRhdGlvbi9od21v
bi9sdGMyOTkwLgo+Cj4gQWxzbywgcGxlYXNlIHJlYWQgYW5kIGZvbGxvdyBEb2N1bWVudGF0aW9u
L2h3bW9uL3N1Ym1pdHRpbmctcGF0Y2hlcy4KPgo+PiAgIDMgZmlsZXMgY2hhbmdlZCwgMjg5IGlu
c2VydGlvbnMoKykKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9od21vbi9sdGMyOTkw
LmMKPj4KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt
b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi5iM2VlZjMxIDEwMDY0NAo+PiAtLS0gYS9kcml2
ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02
ODUsNiArNjg1LDIxIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy
aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls
bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD
Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50
IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIHNl
bGVjdCBSRUdNQVBfSTJDCj4KPiBVc2luZyByZWdtYXAgZm9yIHRoZSBkcml2ZXIgbWlnaHQgYmUg
YSBnb29kIGlkZWEsIGJ1dCB5b3UgZG9uJ3QuCgpMb29raW5nIGF0IHRoZSByZWdtYXAsIHRoZSBk
cml2ZXIgb25seSB3cml0ZXMgdGhlIG9uZSBjYWNoYWJsZSByZWdpc3RlciAKb25jZSwgdGhlICJj
b250cm9sIi4gQWxsIHRoZSBvdGhlciByZWdpc3RlcnMgY2Fubm90IGJlIGNhY2hlZCwgYXJlIApl
aXRoZXIgcmVhZC1vbmx5IG9yIHdyaXRlLW9ubHkuIERvbid0IHRoaW5rIHJlZ21hcCB3aWxsIGhl
bHAsIHNvIEknbGwgCnJlbW92ZSB0aGUgInNlbGVjdCIgaGVyZS4KCj4+ICsgICAgZGVmYXVsdCBu
Cj4KPiBOb3QgbmVjZXNzYXJ5Lgo+Cj4+ICsgICAgaGVscAo+PiArICAgICAgSWYgeW91IHNheSB5
ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4g
KyAgICAgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5h
dGlvbiBvZiB2b2x0YWdlLAo+PiArICAgICAgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUgbW9uaXRv
cmluZywgYnV0IHRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5Cj4+ICsgICAgICBzdXBwb3J0cyBy
ZWFkaW5nIHR3byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbAo+PiB2b2x0
YWdlcwo+PiArICAgICAgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMuCj4+ICsKPj4gKyAgICAgIFRo
aXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVs
ZSB3aWxsCj4+ICsgICAgICBiZSBjYWxsZWQgbHRjMjk5MC4KPj4gKwo+PiAgIGNvbmZpZyBTRU5T
T1JTX0xUQzQxNTEKPj4gICAgICAgdHJpc3RhdGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEi
Cj4+ICAgICAgIGRlcGVuZHMgb24gSTJDCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01h
a2VmaWxlIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBpbmRleCAxMmEzMjM5Li5lNGJkMTVi
IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMv
aHdtb24vTWFrZWZpbGUKPj4gQEAgLTEwMSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09S
U19MTTk1MjM0KSAgICArPSBsbTk1MjM0Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1
MjQxKSAgICArPSBsbTk1MjQxLm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjQ1KSAg
ICArPSBsbTk1MjQ1Lm8KPj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1KSAgICArPSBs
dGMyOTQ1Lm8KPj4gK29iai0kKENPTkZJR19TRU5TT1JTX0xUQzI5OTApICAgICs9IGx0YzI5OTAu
bwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpICAgICs9IGx0YzQxNTEubwo+PiAg
IG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpICAgICs9IGx0YzQyMTUubwo+PiAgIG9iai0k
KENPTkZJR19TRU5TT1JTX0xUQzQyMjIpICAgICs9IGx0YzQyMjIubwo+PiBkaWZmIC0tZ2l0IGEv
ZHJpdmVycy9od21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+PiBuZXcg
ZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwLi4xNjFkOTk1Cj4+IC0tLSAvZGV2L251
bGwKPj4gKysrIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPj4gQEAgLTAsMCArMSwyNzMgQEAK
Pj4gKy8qCj4+ICsgKiBkcml2ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIg
bW9uaXRvcgo+Cj4gRHJpdmVyCj4KPj4gKyAqCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9w
aWMgRW1iZWRkZWQgUHJvZHVjdHMKPgo+IDIwMTUgPwoKSSB3cm90ZSB0aGUgZHJpdmVyIGVhcmx5
IGxhc3QgeWVhci4gSSBvbmx5IGRpZCBzb21lIGNvc21ldGljIGNsZWFudXAgYW5kIApyZWJhc2Ug
b24gbWFzdGVyIGJlZm9yZSBzdWJtaXR0aW5nLgoKPgo+PiArICogQXV0aG9yOiBNaWtlIExvb2lq
bWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4+ICsgKgo+PiArICogTGljZW5zZTogR1BM
djIKPj4gKyAqCj4+ICsgKiBUaGlzIGRyaXZlciBhc3N1bWVzIHRoZSBjaGlwIGlzIHdpcmVkIGFz
IGEgZHVhbCBjdXJyZW50IG1vbml0b3IsIGFuZAo+PiArICogcmVwb3J0cyB0aGUgdm9sdGFnZSBk
cm9wIGFjcm9zcyB0d28gc2VyaWVzIHJlc2lzdG9ycy4KPgo+IEl0IGFsc28gbW9uaXRvcnMgdGhl
IHRlbXBlcmF0dXJlIGFuZCBWQ0MuCj4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgv
YnVnLmg+Cj4KPiBJcyB0aGlzIHVzZWQgYW55d2hlcmUgaW4gdGhlIGRyaXZlciA/CgpOb3QgYW55
IG1vcmUuLi4KCj4KPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUgPGxp
bnV4L2Vyci5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLmg+Cj4+ICsjaW5jbHVkZSA8bGlu
dXgvaHdtb24tc3lzZnMuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPj4gKyNpbmNsdWRl
IDxsaW51eC9rZXJuZWwuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gKyNpbmNs
dWRlIDxsaW51eC9zbGFiLmg+Cj4+ICsKPj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVMgICAgMHgw
MAo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wgICAgMHgwMQo+PiArI2RlZmluZSBMVEMyOTkw
X1RSSUdHRVIgICAgMHgwMgo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTVNCICAgIDB4MDQKPj4g
KyNkZWZpbmUgTFRDMjk5MF9USU5UX0xTQiAgICAweDA1Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjFf
TVNCICAgIDB4MDYKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMV9MU0IgICAgMHgwNwo+PiArI2RlZmlu
ZSBMVEMyOTkwX1YyX01TQiAgICAweDA4Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjJfTFNCICAgIDB4
MDkKPj4gKyNkZWZpbmUgTFRDMjk5MF9WM19NU0IgICAgMHgwQQo+PiArI2RlZmluZSBMVEMyOTkw
X1YzX0xTQiAgICAweDBCCj4+ICsjZGVmaW5lIExUQzI5OTBfVjRfTVNCICAgIDB4MEMKPj4gKyNk
ZWZpbmUgTFRDMjk5MF9WNF9MU0IgICAgMHgwRAo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19NU0Ig
ICAgMHgwRQo+PiArI2RlZmluZSBMVEMyOTkwX1ZDQ19MU0IgICAgMHgwRgo+PiArCj4+ICsjZGVm
aW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RB
VFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1YxICAgIEJJVCgy
KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4gKyNkZWZpbmUgTFRD
Mjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1Y0ICAg
IEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklUKDYpCj4+ICsKPj4g
Ky8qIE9ubHkgZGVmaW5lIGNvbnRyb2wgc2V0dGluZ3Mgd2UgYWN0dWFsbHkgdXNlICovCj4+ICsj
ZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxWSU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBM
VEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAgICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9D
T05UUk9MX01FQVNVUkVfQUxMICAgICgweDMgPDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05U
Uk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RF
X1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICtzdHJ1Y3QgbHRjMjk5MF9kYXRhIHsKPj4gKyAgICBz
dHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7Cj4+ICsgICAgc3RydWN0IG11dGV4IHVwZGF0ZV9sb2Nr
Owo+PiArICAgIHVuc2lnbmVkIGxvbmcgbGFzdF91cGRhdGVkOwo+PiArICAgIHNob3J0IHZhbHVl
c1s2XTsKPgo+IHUxNiA/Cj4KPj4gKyAgICBib29sIHZhbGlkOwo+PiArICAgIHU4IHVwZGF0ZV9j
b3VudGVyOwo+Cj4gTm90IHVzZWQgYW55d2hlcmUuCj4KPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBp
bnQgbHRjMjk5MF93cml0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4IHZhbHVl
KQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgcmVn
LCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX2J5dGUoc3Ry
dWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnKQo+PiArewo+PiArICAgIHJldHVybiBpMmNfc21i
dXNfcmVhZF9ieXRlX2RhdGEoaTJjLCByZWcpOwo+PiArfQo+PiArCj4KPiBVc2VsZXNzIHNoaW0g
ZnVuY3Rpb25zLgoKVHJ1ZSwgc2hvdWxkIGhhdmUgcmVtb3ZlZCB0aGVtIGFmdGVyIHJlZmFjdG9y
aW5nIHRoZW0gaW50byBvbmUtbGluZXJzLgpUaGV5IHdlcmUgY29udmVuaWVudCBlYXJseSBvbi4K
Cj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9yZWFkX3dvcmQoc3RydWN0IGkyY19jbGllbnQgKmky
YywgdTggcmVnKQo+PiArewo+PiArICAgIGludCByZXN1bHQgPSBpMmNfc21idXNfcmVhZF93b3Jk
X2RhdGEoaTJjLCByZWcpOwo+PiArICAgIC8qIFJlc3VsdCBpcyBNU0IgZmlyc3QsIGJ1dCBzbWJ1
cyBzcGVjcyBzYXkgTFNCIGZpcnN0LCBzbyBzd2FwIHRoZQo+PiArICAgICAqIHJlc3VsdCAqLwo+
Cj4gQmFkIG11bHRpLWxpbmUgY29tbWVudC4KPgo+PiArICAgIHJldHVybiByZXN1bHQgPCAwID8g
cmVzdWx0IDogc3dhYjE2KHJlc3VsdCk7Cj4KPiBQbGVhc2UgdXNlIGkyY19zbWJ1c19yZWFkX3dv
cmRfc3dhcHBlZCgpIGFuZCBkcm9wIHRoZSBzaGltIGZ1bmN0aW9uLgo+Cj4+ICt9Cj4+ICsKPj4g
K3N0YXRpYyBzdHJ1Y3QgbHRjMjk5MF9kYXRhICpsdGMyOTkwX3VwZGF0ZV9kZXZpY2Uoc3RydWN0
IGRldmljZSAqZGV2KQo+PiArewo+PiArICAgIHN0cnVjdCBpMmNfY2xpZW50ICppMmMgPSB0b19p
MmNfY2xpZW50KGRldik7Cj4+ICsgICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGkyY19n
ZXRfY2xpZW50ZGF0YShpMmMpOwo+PiArICAgIHN0cnVjdCBsdGMyOTkwX2RhdGEgKnJldCA9IGRh
dGE7Cj4+ICsgICAgdW5zaWduZWQgaW50IHRpbWVvdXQ7Cj4+ICsKPj4gKyAgICBtdXRleF9sb2Nr
KCZkYXRhLT51cGRhdGVfbG9jayk7Cj4+ICsKPj4gKyAgICAvKiBVcGRhdGUgYWJvdXQgNCB0aW1l
cyBwZXIgc2Vjb25kIG1heCAqLwo+PiArICAgIGlmICh0aW1lX2FmdGVyKGppZmZpZXMsIGRhdGEt
Pmxhc3RfdXBkYXRlZCArIEhaIC8gNCkgfHwKPj4gIWRhdGEtPnZhbGlkKSB7Cj4+ICsgICAgICAg
IGludCB2YWw7Cj4+ICsgICAgICAgIGludCBpOwo+PiArCj4KPiBQbGVhc2UgY29uc2lkZXIgdXNp
bmcgY29udGludW91cyBjb252ZXJzaW9uLiBUaGlzIHdvdWxkIHNpbXBsaWZ5IHRoZQo+IGNvZGUg
c2lnbmlmaWNhbnRseQo+IGFuZCByZWR1Y2UgcmVhZCBkZWxheXMuCgpJdCBtaWdodCBpbmNyZWFz
ZSBwb3dlciBjb25zdW1wdGlvbiB0aG91Z2gsIGFzIHR5cGljYWxseSBzb21lIHVzZXIgCnByb2dy
YW0gd291bGQgcG9sbCB0aGlzIGV2ZXJ5IDEwIHNlY29uZHMgb3Igc28uIEknbGwgY2hlY2sgdGhl
IGRhdGEgc2hlZXQuCgo+PiArICAgICAgICAvKiBUcmlnZ2VyIEFEQywgYW55IHZhbHVlIHdpbGwg
ZG8gKi8KPj4gKyAgICAgICAgdmFsID0gbHRjMjk5MF93cml0ZShpMmMsIExUQzI5OTBfVFJJR0dF
UiwgMSk7Cj4+ICsgICAgICAgIGlmICh1bmxpa2VseSh2YWwgPCAwKSkgewo+PiArICAgICAgICAg
ICAgcmV0ID0gRVJSX1BUUih2YWwpOwo+PiArICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAg
ICAgICAgfQo+PiArCj4+ICsgICAgICAgIC8qIFdhaXQgZm9yIGNvbnZlcnNpb24gY29tcGxldGUg
Ki8KPj4gKyAgICAgICAgdGltZW91dCA9IDIwMDsKPj4gKyAgICAgICAgZm9yICg7Oykgewo+PiAr
ICAgICAgICAgICAgdXNsZWVwX3JhbmdlKDIwMDAsIDQwMDApOwo+PiArICAgICAgICAgICAgdmFs
ID0gbHRjMjk5MF9yZWFkX2J5dGUoaTJjLCBMVEMyOTkwX1NUQVRVUyk7Cj4+ICsgICAgICAgICAg
ICBpZiAodW5saWtlbHkodmFsIDwgMCkpIHsKPj4gKyAgICAgICAgICAgICAgICByZXQgPSBFUlJf
UFRSKHZhbCk7Cj4+ICsgICAgICAgICAgICAgICAgZ290byBhYm9ydDsKPj4gKyAgICAgICAgICAg
IH0KPj4gKyAgICAgICAgICAgIC8qIFNpbmdsZS1zaG90IG1vZGUsIHdhaXQgZm9yIGNvbnZlcnNp
b24gdG8gY29tcGxldGUgKi8KPj4gKyAgICAgICAgICAgIGlmICgodmFsICYgTFRDMjk5MF9TVEFU
VVNfQlVTWSkgPT0gMCkKPgo+ICAgICAgICAgICAgICBpZiAoISguLi4pKQo+Cj4+ICsgICAgICAg
ICAgICAgICAgYnJlYWs7Cj4+ICsgICAgICAgICAgICBpZiAoLS10aW1lb3V0ID09IDApIHsKPj4g
KyAgICAgICAgICAgICAgICByZXQgPSBFUlJfUFRSKC1FVElNRURPVVQpOwo+PiArICAgICAgICAg
ICAgICAgIGdvdG8gYWJvcnQ7Cj4+ICsgICAgICAgICAgICB9Cj4+ICsgICAgICAgIH0KPgo+IEFn
YWluLCBwbGVhc2UgY29uc2lkZXIgdXNpbmcgY29udGludW91cyBjb252ZXJzaW9uIG1vZGUuCj4K
PiBJZiB0aGlzIGlzIG5vdCBmZWFzaWJsZSBmb3Igc29tZSByZWFzb24sIHlvdSBtaWdodCBhcyB3
ZWxsIGp1c3Qgd2FpdCBmb3IKPiB0aGUKPiBtaW5pbXVtIGNvbnZlcnNpb24gdGltZSBiZWZvcmUg
dHJ5aW5nIHRvIHJlYWQgZm9yIHRoZSBmaXJzdCB0aW1lLiBJZiBzbywKPiBwbGVhc2UgdXNlIGEg
Zml4ZWQgdGltZW91dCBieSBjb21wYXJpbmcgdGhlIGVsYXBzZWQgdGltZSBpbnN0ZWFkIG9mIGxv
b3BpbmcKPiBmb3IgYSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcy4gTm90IGV2ZW4gY291bnRpbmcg
dGhlIHRpbWUgZm9yIGV4ZWN1dGluZyB0aGUKPiBjb2RlLCB0aGUgbWF4aW11bSBkZWxheSBpcyBi
ZXR3ZWVuIDQwMCBtcyBhbmQgODAwIG1zLCB3aGljaCBpcyB3YXkgdG9vIGhpZ2gKPiAoY2hpcCBz
cGVjIHNheXMgMTY3IG1zIHdvcnN0IGNhc2UsIGlmIHRocmVlIHRlbXBlcmF0dXJlIHNlbnNvcnMg
YXJlCj4gY29uZmlndXJlZCkuCgpPciBtYXliZSBJIHNob3VsZCBqdXN0IHNsZWVwIGZvciAxNjdt
cyBhbmQgYmUgZG9uZSB3aXRoIGl0LiBUaG91Z2ggSSAKdGhpbmsgSSdsIGdvdCB3aXRoIHlvdXIg
bWluaW1hbCB0aW1lIGZpcnN0IHN1Z2dlc3Rpb24uCgo+PiArCj4+ICsgICAgICAgIC8qIFJlYWQg
YWxsIHJlZ2lzdGVycyAqLwo+PiArICAgICAgICBmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShk
YXRhLT52YWx1ZXMpOyArK2kpIHsKPj4gKyAgICAgICAgICAgIHZhbCA9IGx0YzI5OTBfcmVhZF93
b3JkKGkyYywgKGk8PDEpICsgTFRDMjk5MF9USU5UX01TQik7Cj4KPiBNaXNzaW5nIHNwYWNlcyBh
cm91bmQgPDwKPgo+PiArICAgICAgICAgICAgaWYgKHVubGlrZWx5KHZhbCA8IDApKSB7Cj4+ICsg
ICAgICAgICAgICAgICAgZGV2X2RiZyhkZXYsCj4+ICsgICAgICAgICAgICAgICAgICAgICJGYWls
ZWQgdG8gcmVhZCBBREMgdmFsdWU6IGVycm9yICVkXG4iLAo+PiArICAgICAgICAgICAgICAgICAg
ICB2YWwpOwo+PiArICAgICAgICAgICAgICAgIHJldCA9IEVSUl9QVFIodmFsKTsKPj4gKyAgICAg
ICAgICAgICAgICBnb3RvIGFib3J0Owo+PiArICAgICAgICAgICAgfQo+PiArICAgICAgICAgICAg
ZGF0YS0+dmFsdWVzW2ldID0gdmFsICYgMHg3RkZGOyAvKiBTdHJpcCAnbmV3JyBiaXQgKi8KPgo+
IFRoZSBiaXQgaXMgbmV2ZXIgZXZhbHVhdGVkLCBzbyB5b3UgbWlnaHQgYXMgd2VsbCBzdG9yZSB0
aGUgcmF3IHZhbHVlLgo+Cj4+ICsgICAgICAgIH0KPj4gKyAgICAgICAgZGF0YS0+bGFzdF91cGRh
dGVkID0gamlmZmllczsKPj4gKyAgICAgICAgZGF0YS0+dmFsaWQgPSAxOwo+Cj4gICAgICA9IHRy
dWU7Cj4KPj4gKwo+PiArICAgICAgICAvKgo+PiArICAgICAgICAgKiAgUXVpcms6IFNlY29uZCB0
cmlnZ2VyIGlzIGlnbm9yZWQ/IEFmdGVyIHRoaXMsIHRoZSBCVVNZIHdpbGwKPj4gKyAgICAgICAg
ICogc3RpbGwgYmUgc2V0IHRvICIwIiBhbmQgbm8gY29udmVyc2lvbiBwZXJmb3JtZWQuCj4+ICsg
ICAgICAgICAqLwo+PiArICAgICAgICB2YWwgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5MF9U
UklHR0VSLCAwKTsKPj4gKyAgICB9Cj4+ICthYm9ydDoKPj4gKyAgICBtdXRleF91bmxvY2soJmRh
dGEtPnVwZGF0ZV9sb2NrKTsKPj4gKyAgICByZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICsvKiBS
ZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBmcm9tIHRoZSBnaXZlbiByZWdpc3RlciBpbiB1ViBv
ciBtQyAqLwo+PiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgbHRjMjk5MF9k
YXRhICpkYXRhLCB1OCBpbmRleCkKPj4gK3sKPj4gKyAgICBzMzIgcmVzdWx0Owo+PiArICAgIHMx
NiB2Owo+PiArCj4+ICsgICAgaWYgKGluZGV4ID09IDApIHsgLyogaW50ZXJuYWwgdGVtcCwgMC4w
NjI1IGRlZ3JlZXMvTFNCLCAxMi1iaXQgICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNb
aW5kZXhdIDw8IDM7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDEwMDAgPj4gNzsKPj4g
KyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkgeyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IsIDE0LWJp
dCAqLwo+PiArICAgICAgICB2ID0gZGF0YS0+dmFsdWVzW2luZGV4XSA8PCAyOwo+Cj4gRGF0YXNo
ZWV0IHNheXMgdGhhdCB0aGUgc2lnbiBiaXQgaXMgaW4gYml0IDE0LCBzbyB0aGlzIGRyb3BzIHRo
ZSBzaWduIGJpdC4KCkknbGwgY2hlY2sgdGhlIGRhdGEgc2hlZXQsIHdvdWxkIG5vdCBoYXZlIG5v
dGljZWQgdGhpcyBzaW5jZSBjdXJyZW50IApkb2Vzbid0IHRlbmQgdG8gcnVuIGZyb20gdGhlIENQ
VSBiYWNrIGludG8gdGhlIGJhdHRlcnkgOikKCj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAq
IDE5NDIgLyAoNCAqIDEwMCk7Cj4+ICsgICAgfSBlbHNlIHsgLyogVmNjLCAzMDUuMTjOvFYvTFNC
LCAyLjVWIG9mZnNldCwgMTQtYml0ICovCj4+ICsgICAgICAgIHYgPSBkYXRhLT52YWx1ZXNbaW5k
ZXhdIDw8IDI7Cj4+ICsgICAgICAgIHJlc3VsdCA9IChzMzIpdiAqIDMwNTE4IC8gKDQgKiAxMDAp
Owo+PiArICAgICAgICByZXN1bHQgKz0gMjUwMDAwMDsKPj4gKyAgICB9Cj4+ICsgICAgcmV0dXJu
IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl
KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf
YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2
aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgc3Ry
dWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGx0YzI5OTBfdXBkYXRlX2RldmljZShkZXYpOwo+PiAr
ICAgIGludCB2YWx1ZTsKPj4gKwo+PiArICAgIGlmIChJU19FUlIoZGF0YSkpCj4+ICsgICAgICAg
IHJldHVybiBQVFJfRVJSKGRhdGEpOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92
YWx1ZShkYXRhLCBhdHRyLT5pbmRleCk7Cj4+ICsgICAgcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFH
RV9TSVpFLCAiJWRcbiIsIHZhbHVlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIFNFTlNPUl9ERVZJ
Q0VfQVRUUih0ZW1wX2ludCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLAo+PiBOVUxMLCAw
KTsKPj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodjF2Ml9kaWZmLCBTX0lSVUdPLCBsdGMy
OTkwX3Nob3dfdmFsdWUsCj4+IE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU
Uih2M3Y0X2RpZmYsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwKPj4gTlVMTCwgMyk7Cj4+
ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHZjYywgU19JUlVHTywgbHRjMjk5MF9zaG93X3Zh
bHVlLCBOVUxMLCA1KTsKPj4gKwo+Cj4gUGxlYXNlIHVzZSBzdGFuZGFyZCBhdHRyaWJ1dGUgbmFt
ZXMgKGFuZCB1bml0cykgYXMgcGVyCj4gRG9jdW1lbnRhdGlvbi9od21vbi9zeXNmcy1pbnRlcmZh
Y2UuCj4KPj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpsdGMyOTkwX2F0dHJpYnV0ZXNbXSA9
IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3RlbXBfaW50LmRldl9hdHRyLmF0dHIsCj4+ICsg
ICAgJnNlbnNvcl9kZXZfYXR0cl92MXYyX2RpZmYuZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vu
c29yX2Rldl9hdHRyX3YzdjRfZGlmZi5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2
X2F0dHJfdmNjLmRldl9hdHRyLmF0dHIsCj4+ICsgICAgTlVMTCwKPj4gK307Cj4+ICsKPj4gK3N0
YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGx0YzI5OTBfZ3JvdXAgPSB7Cj4+ICsg
ICAgLmF0dHJzID0gbHRjMjk5MF9hdHRyaWJ1dGVzLAo+PiArfTsKPj4gKwo+Cj4gUGxlYXNlIHVz
ZSB0aGUgQVRUUklCVVRFX0dST1VQUygpIG1hY3JvLiBBbHNvIHNlZSBiZWxvdy4KCk9rYXksIHdp
bGwgUlRGTS4KCj4KPj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9pMmNfcHJvYmUoCj4+ICsgICAgc3Ry
dWN0IGkyY19jbGllbnQgKmkyYywgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQo+Cj4g
UGxlYXNlIHNwbGl0IGFzCj4KPiBzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3Byb2JlKHN0cnVjdCBp
MmNfY2xpZW50ICppMmMsCj4gICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGkyY19kZXZp
Y2VfaWQgKmlkKQo+Cj4+ICt7Cj4+ICsgICAgaW50IHJldDsKPj4gKyAgICBzdHJ1Y3QgbHRjMjk5
MF9kYXRhICpsdGMyOTkwOwo+PiArCj4+ICsgICAgaWYgKCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0
eShpMmMtPmFkYXB0ZXIsCj4+IEkyQ19GVU5DX1NNQlVTX0JZVEVfREFUQSkpCj4+ICsgICAgICAg
IHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgbHRjMjk5MCA9IGRldm1fa3phbGxvYygmaTJj
LT5kZXYsCj4+ICsgICAgICAgIHNpemVvZihzdHJ1Y3QgbHRjMjk5MF9kYXRhKSwgR0ZQX0tFUk5F
TCk7Cj4KPiBQbGVhc2UgYWxpZ24gY29udGludWF0aW9uIGxpbmVzIHdpdGggJygnLgo+Cj4+ICsg
ICAgaWYgKGx0YzI5OTAgPT0gTlVMTCkKPj4gKyAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4+ICsK
Pj4gKyAgICByZXQgPSBsdGMyOTkwX3JlYWRfYnl0ZShpMmMsIDApOwo+PiArICAgIGlmIChyZXQg
PCAwKSB7Cj4+ICsgICAgICAgIGRldl9lcnIoJmkyYy0+ZGV2LCAiQ291bGQgbm90IHJlYWQgTFRD
Mjk5MCBvbiBpMmMgYnVzLlxuIik7Cj4+ICsgICAgICAgIHJldHVybiByZXQ7Cj4+ICsgICAgfQo+
Cj4gVGhlIHdyaXRlIGJlbG93IHdvdWxkIGFsc28gcmV0dXJuIGFuIGVycm9yIGlmIHRoZSBjaGlw
IGlzbid0IHRoZXJlLAo+IHNvIHRoaXMgYWRkaXRpb25hbCByZWFkIGRvZXMgbm90IHByb3ZpZGUg
YW55IHJlYWwgdmFsdWUuCj4KPj4gKyAgICByZXQgPSBsdGMyOTkwX3dyaXRlKGkyYywgTFRDMjk5
MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMyOTkwX0NPTlRST0xfU0lOR0xFIHwgTFRDMjk5MF9D
T05UUk9MX01FQVNVUkVfQUxMIHwKPj4gKyAgICAgICAgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VS
UkVOVCk7Cj4KPiBJJ2xsIGhhdmUgdG8gdGhpbmsgYWJvdXQgdGhpcy4gV2hpbGUgaXQgYWRkcmVz
c2VzIHlvdXIgdXNlIGNhc2UsCj4gaXQgbGltaXRzIHRoZSBzY29wZSBvZiB0aGlzIGRyaXZlciBz
aWduaWZpY2FudGx5LiBMb29raW5nIGludG8gdGhlIGJvYXJkCj4gc3BlY2lmaWNhdGlvbnMsIHlv
dSBtaWdodCBhcyB3ZWxsIGRvIGl0IHJpZ2h0IGFuZCBkZXRlcm1pbmUgKGFuZCBzZXQpCj4gdGhl
IGNvcnJlY3QgY29uZmlndXJhdGlvbiB1c2luZyBkZXZpY2V0cmVlIGRhdGEgaW5zdGVhZCBvZiBm
b3JjaW5nIHlvdXIKPiB1c2UgY2FzZSBvbiBldmVyeW9uZS4KPgo+IFN1cmUsIHlvdSBtYXkgYXJn
dWUgdGhhdCB5b3UgZG9uJ3QgY2FyZSwgYnV0IHdlIHdpbGwgYmUgdGhlIG9uZXMgd2hvCj4gd2ls
bCBoYXZlCj4gdG8gaGFuZGxlIGVycm9yIHJlcG9ydHMgdGhhdCB0aGUgZHJpdmVyIHVuZXhwZWN0
ZWRseSBjaGFuZ2VzIHRoZQo+IGNvbmZpZ3VyYXRpb24KPiBpbiBvdGhlciB1c2UgY2FzZXMgKHdo
ZXJlLCBmb3IgZXhhbXBsZSwgdGhlIG1vZGUgbWF5IGhhdmUgYmVlbiBwcmUtc2V0IGJ5Cj4gdGhl
IEJJT1Mgb3IgUk9NTU9OKS4KClRoZSByZWFzb24gSSBkaWRuJ3Qgc3VibWl0IHRoZSBkcml2ZXIg
bGFzdCB5ZWFyIHdhcyB0aGF0IEkgd2FzIHN0aWxsIAp0aGlua2luZyBhYm91dCBpdC4gT24gdGhl
IG90aGVyIGhhbmQsIGEgbGltaXRlZCBkcml2ZXIgaXMgc3RpbGwgbXVjaCAKYmV0dGVyIHRoYW4g
bm8gZHJpdmVyIGF0IGFsbCwgc28gdGhhdCBtYWRlIG1lIHBvc3QgaXQsIHdpdGggdGhlIGFkZGVk
IApyZW1hcmtzIGFib3V0IHRoZSBkcml2ZXIgYmVpbmcgbGltaXRlZC4KCkFkZGluZyB0aGUgb3Ro
ZXIgZnVuY3Rpb25zIGl0IHF1aXRlIGEgYml0IG1vcmUgd29yayB0aGFuIGp1c3Qgd3JpdGluZyAK
dGhpcyByZWdpc3Rlci4gSXQgYWxzbyBjaGFuZ2VzIHRoZSBwcm9wZXJ0aWVzIHRvIGJlIGV4cG9y
dGVkIHRvIHN5c2ZzLCAKYW5kIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgZW5kIHZhbHVlcy4KCj4K
Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy
cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g
cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIG11dGV4X2luaXQoJmx0YzI5OTAtPnVwZGF0ZV9s
b2NrKTsKPj4gKyAgICBpMmNfc2V0X2NsaWVudGRhdGEoaTJjLCBsdGMyOTkwKTsKPj4gKwo+PiAr
ICAgIC8qIFJlZ2lzdGVyIHN5c2ZzIGhvb2tzICovCj4+ICsgICAgcmV0ID0gc3lzZnNfY3JlYXRl
X2dyb3VwKCZpMmMtPmRldi5rb2JqLCAmbHRjMjk5MF9ncm91cCk7Cj4+ICsgICAgaWYgKHJldCkK
Pj4gKyAgICAgICAgcmV0dXJuIHJldDsKPj4gKwo+PiArICAgIGx0YzI5OTAtPmh3bW9uX2RldiA9
IGh3bW9uX2RldmljZV9yZWdpc3RlcigmaTJjLT5kZXYpOwo+Cj4gUGxlYXNlIHVzZSBkZXZtX2h3
bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygpLgo+Cj4+ICsgICAgaWYgKElTX0VSUihs
dGMyOTkwLT5od21vbl9kZXYpKSB7Cj4+ICsgICAgICAgIHJldCA9IFBUUl9FUlIobHRjMjk5MC0+
aHdtb25fZGV2KTsKPj4gKyAgICAgICAgZ290byBvdXRfaHdtb25fZGV2aWNlX3JlZ2lzdGVyOwo+
PiArICAgIH0KPj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArCj4+ICtvdXRfaHdtb25fZGV2aWNl
X3JlZ2lzdGVyOgo+PiArICAgIHN5c2ZzX3JlbW92ZV9ncm91cCgmaTJjLT5kZXYua29iaiwgJmx0
YzI5OTBfZ3JvdXApOwo+PiArICAgIHJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBp
bnQgbHRjMjk5MF9pMmNfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMpCj4+ICt7Cj4+ICsg
ICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqbHRjMjk5MCA9IGkyY19nZXRfY2xpZW50ZGF0YShpMmMp
Owo+PiArCj4+ICsgICAgaHdtb25fZGV2aWNlX3VucmVnaXN0ZXIobHRjMjk5MC0+aHdtb25fZGV2
KTsKPj4gKyAgICBzeXNmc19yZW1vdmVfZ3JvdXAoJmkyYy0+ZGV2LmtvYmosICZsdGMyOTkwX2dy
b3VwKTsKPj4gKyAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVj
dCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10gPSB7Cj4+ICsgICAgeyAibHRjMjk5MCIs
IDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMy
OTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2ky
Y19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsKPj4gKyAgICAgICAgLm5hbWUgPSAibHRj
Mjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUgICAgPSBsdGMyOTkwX2kyY19wcm9iZSwK
Pj4gKyAgICAucmVtb3ZlICAgPSBsdGMyOTkwX2kyY19yZW1vdmUsCj4+ICsgICAgLmlkX3RhYmxl
ID0gbHRjMjk5MF9pMmNfaWQsCj4+ICt9Owo+PiArCj4+ICttb2R1bGVfaTJjX2RyaXZlcihsdGMy
OTkwX2kyY19kcml2ZXIpOwo+PiArCj4+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkxUQzI5OTAgU2Vu
c29yIERyaXZlciIpOwo+PiArTU9EVUxFX0FVVEhPUigiVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMi
KTsKPj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPj4KPgoKCi0tIApNaWtlIExvb2lqbWFu
cwoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vu
c29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMu
bG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz

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

* Re: [PATCH] hwmon: Add LTC2990 sensor driver
  2016-01-07 18:59     ` [lm-sensors] " Mike Looijmans
@ 2016-01-08 15:09       ` Guenter Roeck
  -1 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-08 15:09 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/07/2016 10:59 AM, Mike Looijmans wrote:
> Thank you very much for your review comments, I'll update the driver and post a v2 patch.
>
> Inlined some replies below. Assume that I "will do" for all comments I didn't comment on inline...
>
> On 06-01-16 16:22, Guenter Roeck wrote:
>> Hello Mike,
>>
>> On 01/06/2016 12:07 AM, Mike Looijmans wrote:
>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>
>> s/  / /
>>
>>> The LTC2990 supports a combination of voltage, current and temperature
>>> monitoring, but this driver currently only supports reading two currents
>>> by measuring two differential voltages across series resistors.
>>>
>> Plus VCC, plus the internal temperature.
>
> Yeah, I should give myself more credit :) I'll add that in Kconfig too.
>
>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>
>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>> ---
>>>   drivers/hwmon/Kconfig   |  15 +++
>>>   drivers/hwmon/Makefile  |   1 +
>>>   drivers/hwmon/ltc2990.c | 273
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>

[ ... ]

>>> +}
>>> +
>>> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
>>> +{
>>> +    struct i2c_client *i2c = to_i2c_client(dev);
>>> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);
>>> +    struct ltc2990_data *ret = data;
>>> +    unsigned int timeout;
>>> +
>>> +    mutex_lock(&data->update_lock);
>>> +
>>> +    /* Update about 4 times per second max */
>>> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||
>>> !data->valid) {
>>> +        int val;
>>> +        int i;
>>> +
>>
>> Please consider using continuous conversion. This would simplify the
>> code significantly
>> and reduce read delays.
>
> It might increase power consumption though, as typically some user program would poll this every 10 seconds or so. I'll check the data sheet.
>

I suspect that the power savings will be less than the added power
consumed by the CPU due to the more complex code.

Really, unless you have an application where a few mW power savings
are essential and warrant the additional code complexity, this is
the wrong approach.

>>> +        /* Trigger ADC, any value will do */
>>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
>>> +        if (unlikely(val < 0)) {
>>> +            ret = ERR_PTR(val);
>>> +            goto abort;
>>> +        }
>>> +
>>> +        /* Wait for conversion complete */
>>> +        timeout = 200;
>>> +        for (;;) {
>>> +            usleep_range(2000, 4000);
>>> +            val = ltc2990_read_byte(i2c, LTC2990_STATUS);
>>> +            if (unlikely(val < 0)) {
>>> +                ret = ERR_PTR(val);
>>> +                goto abort;
>>> +            }
>>> +            /* Single-shot mode, wait for conversion to complete */
>>> +            if ((val & LTC2990_STATUS_BUSY) == 0)
>>
>>              if (!(...))
>>
>>> +                break;
>>> +            if (--timeout == 0) {
>>> +                ret = ERR_PTR(-ETIMEDOUT);
>>> +                goto abort;
>>> +            }
>>> +        }
>>
>> Again, please consider using continuous conversion mode.
>>
>> If this is not feasible for some reason, you might as well just wait for
>> the
>> minimum conversion time before trying to read for the first time. If so,
>> please use a fixed timeout by comparing the elapsed time instead of looping
>> for a maximum number of times. Not even counting the time for executing the
>> code, the maximum delay is between 400 ms and 800 ms, which is way too high
>> (chip spec says 167 ms worst case, if three temperature sensors are
>> configured).
>
> Or maybe I should just sleep for 167ms and be done with it. Though I think I'l got with your minimal time first suggestion.
>

Keep in mind that any user space program using this driver would effectively
go to sleep for the wait time. Maybe that doesn't matter in your application,
but it may be a problem for others. A fixed large delay would make the situation
even worse.

Guenter

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

* Re: [lm-sensors] [PATCH] hwmon: Add LTC2990 sensor driver
@ 2016-01-08 15:09       ` Guenter Roeck
  0 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-08 15:09 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/07/2016 10:59 AM, Mike Looijmans wrote:
> Thank you very much for your review comments, I'll update the driver and post a v2 patch.
>
> Inlined some replies below. Assume that I "will do" for all comments I didn't comment on inline...
>
> On 06-01-16 16:22, Guenter Roeck wrote:
>> Hello Mike,
>>
>> On 01/06/2016 12:07 AM, Mike Looijmans wrote:
>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>
>> s/  / /
>>
>>> The LTC2990 supports a combination of voltage, current and temperature
>>> monitoring, but this driver currently only supports reading two currents
>>> by measuring two differential voltages across series resistors.
>>>
>> Plus VCC, plus the internal temperature.
>
> Yeah, I should give myself more credit :) I'll add that in Kconfig too.
>
>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>
>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>> ---
>>>   drivers/hwmon/Kconfig   |  15 +++
>>>   drivers/hwmon/Makefile  |   1 +
>>>   drivers/hwmon/ltc2990.c | 273
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>

[ ... ]

>>> +}
>>> +
>>> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
>>> +{
>>> +    struct i2c_client *i2c = to_i2c_client(dev);
>>> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);
>>> +    struct ltc2990_data *ret = data;
>>> +    unsigned int timeout;
>>> +
>>> +    mutex_lock(&data->update_lock);
>>> +
>>> +    /* Update about 4 times per second max */
>>> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||
>>> !data->valid) {
>>> +        int val;
>>> +        int i;
>>> +
>>
>> Please consider using continuous conversion. This would simplify the
>> code significantly
>> and reduce read delays.
>
> It might increase power consumption though, as typically some user program would poll this every 10 seconds or so. I'll check the data sheet.
>

I suspect that the power savings will be less than the added power
consumed by the CPU due to the more complex code.

Really, unless you have an application where a few mW power savings
are essential and warrant the additional code complexity, this is
the wrong approach.

>>> +        /* Trigger ADC, any value will do */
>>> +        val = ltc2990_write(i2c, LTC2990_TRIGGER, 1);
>>> +        if (unlikely(val < 0)) {
>>> +            ret = ERR_PTR(val);
>>> +            goto abort;
>>> +        }
>>> +
>>> +        /* Wait for conversion complete */
>>> +        timeout = 200;
>>> +        for (;;) {
>>> +            usleep_range(2000, 4000);
>>> +            val = ltc2990_read_byte(i2c, LTC2990_STATUS);
>>> +            if (unlikely(val < 0)) {
>>> +                ret = ERR_PTR(val);
>>> +                goto abort;
>>> +            }
>>> +            /* Single-shot mode, wait for conversion to complete */
>>> +            if ((val & LTC2990_STATUS_BUSY) = 0)
>>
>>              if (!(...))
>>
>>> +                break;
>>> +            if (--timeout = 0) {
>>> +                ret = ERR_PTR(-ETIMEDOUT);
>>> +                goto abort;
>>> +            }
>>> +        }
>>
>> Again, please consider using continuous conversion mode.
>>
>> If this is not feasible for some reason, you might as well just wait for
>> the
>> minimum conversion time before trying to read for the first time. If so,
>> please use a fixed timeout by comparing the elapsed time instead of looping
>> for a maximum number of times. Not even counting the time for executing the
>> code, the maximum delay is between 400 ms and 800 ms, which is way too high
>> (chip spec says 167 ms worst case, if three temperature sensors are
>> configured).
>
> Or maybe I should just sleep for 167ms and be done with it. Though I think I'l got with your minimal time first suggestion.
>

Keep in mind that any user space program using this driver would effectively
go to sleep for the wait time. Maybe that doesn't matter in your application,
but it may be a problem for others. A fixed large delay would make the situation
even worse.

Guenter


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* [PATCH v2] hwmon: Add LTC2990 sensor driver
  2016-01-06  8:07 ` [lm-sensors] " Mike Looijmans
@ 2016-01-13 11:05   ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 11:05 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

This adds support for the Linear Technology LTC2990  I2C System Monitor.
The LTC2990 supports a combination of voltage, current and temperature
monitoring. This driver currently only supports reading two currents
by measuring two differential voltages across series resistors, in
addition to the Vcc supply voltage and internal temperature.

This is sufficient to support the Topic Miami SOM which uses this chip
to monitor the currents flowing into the FPGA and the CPU parts.

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
---
v2: Processed all review comments.
    Put chip into continuous measurement mode.
    Added ducumentation.
    Use standard hwmon interfaces and macros.

 Documentation/hwmon/ltc2990 |  44 ++++++++++++
 drivers/hwmon/Kconfig       |  14 ++++
 drivers/hwmon/Makefile      |   1 +
 drivers/hwmon/ltc2990.c     | 160 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/hwmon/ltc2990
 create mode 100644 drivers/hwmon/ltc2990.c

diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
new file mode 100644
index 0000000..838b74e
--- /dev/null
+++ b/Documentation/hwmon/ltc2990
@@ -0,0 +1,44 @@
+Kernel driver ltc2990
+=====================
+
+Supported chips:
+  * Linear Technology LTC2990
+    Prefix: 'ltc2990'
+    Addresses scanned: -
+    Datasheet: http://www.linear.com/product/ltc2990
+
+Author: Mike Looijmans <mike.looijmans@topic.nl>
+
+
+Description
+-----------
+
+LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
+The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
+can be combined to measure a differential voltage, which is typically used to
+measure current through a series resistor, or a temperature.
+
+This driver currently uses the 2x differential mode only. In order to support
+other modes, the driver will need to be expanded.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have to instantiate
+devices explicitly.
+
+
+Sysfs attributes
+----------------
+
+The "curr*_input" measurements actually report the voltage drop across the
+input pins in microvolts. This is equivalent to the current through a 1mOhm
+sense resistor. Divide the reported value by the actual sense resistor value
+in mOhm to get the actual value.
+
+in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
+temp1_input   Internal chip temperature in millidegrees Celcius
+curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
+curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
+
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 80a73bf..8a31d64 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -685,6 +685,20 @@ config SENSORS_LTC2945
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2945.
 
+config SENSORS_LTC2990
+	tristate "Linear Technology LTC2990 (current monitoring mode only)"
+	depends on I2C
+	help
+	  If you say yes here you get support for Linear Technology LTC2990
+	  I2C System Monitor. The LTC2990 supports a combination of voltage,
+	  current and temperature monitoring, but in addition to the Vcc supply
+	  voltage and chip temperature, this driver currently only supports
+	  reading two currents by measuring two differential voltages across
+	  series resistors.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc2990.
+
 config SENSORS_LTC4151
 	tristate "Linear Technology LTC4151"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 12a3239..e4bd15b 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
 obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
 obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
 obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
+obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
 obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
 obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
new file mode 100644
index 0000000..3720ff7
--- /dev/null
+++ b/drivers/hwmon/ltc2990.c
@@ -0,0 +1,160 @@
+/*
+ * Driver for Linear Technology LTC2990 power monitor
+ *
+ * Copyright (C) 2014 Topic Embedded Products
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * License: GPLv2
+ *
+ * This driver assumes the chip is wired as a dual current monitor, and
+ * reports the voltage drop across two series resistors. It also reports
+ * the chip's internal temperature and Vcc power supply voltage.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define LTC2990_STATUS	0x00
+#define LTC2990_CONTROL	0x01
+#define LTC2990_TRIGGER	0x02
+#define LTC2990_TINT_MSB	0x04
+#define LTC2990_TINT_LSB	0x05
+#define LTC2990_V1_MSB	0x06
+#define LTC2990_V1_LSB	0x07
+#define LTC2990_V2_MSB	0x08
+#define LTC2990_V2_LSB	0x09
+#define LTC2990_V3_MSB	0x0A
+#define LTC2990_V3_LSB	0x0B
+#define LTC2990_V4_MSB	0x0C
+#define LTC2990_V4_LSB	0x0D
+#define LTC2990_VCC_MSB	0x0E
+#define LTC2990_VCC_LSB	0x0F
+
+#define LTC2990_STATUS_BUSY	BIT(0)
+#define LTC2990_STATUS_TINT	BIT(1)
+#define LTC2990_STATUS_V1	BIT(2)
+#define LTC2990_STATUS_V2	BIT(3)
+#define LTC2990_STATUS_V3	BIT(4)
+#define LTC2990_STATUS_V4	BIT(5)
+#define LTC2990_STATUS_VCC	BIT(6)
+
+/* Only define control settings we actually use */
+#define LTC2990_CONTROL_KELVIN		BIT(7)
+#define LTC2990_CONTROL_SINGLE		BIT(6)
+#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
+#define LTC2990_CONTROL_MODE_CURRENT	0x06
+#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
+
+/* convert raw register value to sign-extended integer in 16-bit range */
+static int ltc2990_voltage_to_int(int raw)
+{
+	if (raw & BIT(14)) {
+		return -(0x4000 - (raw & 0x3FFF)) << 2;
+	} else {
+		return (raw & 0x3FFF) << 2;
+	}
+}
+
+/* Return the converted value from the given register in uV or mC */
+static int ltc2990_get_value(struct i2c_client *i2c, u8 index)
+{
+	int val;
+	int result;
+
+	val = i2c_smbus_read_word_swapped(i2c, (index << 1) + LTC2990_TINT_MSB);
+	if (unlikely(val < 0))
+		return val;
+
+	if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 13-bit  */
+		val = (val & 0x1FFF) << 3;
+		result = (val * 1000) >> 7;
+	} else if (index < 5) { /* Vx-Vy, 19.42uV/LSB */
+		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
+	} else { /* Vcc, 305.18μV/LSB, 2.5V offset */
+		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
+		result += 2500;
+	}
+
+	return result;
+}
+
+static ssize_t ltc2990_show_value(struct device *dev,
+				  struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	int value;
+
+	value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);
+	return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, 0);
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, 1);
+static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, 3);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, 5);
+
+static struct attribute *ltc2990_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr2_input.dev_attr.attr,
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(ltc2990);
+
+static int ltc2990_i2c_probe(struct i2c_client *i2c,
+	const struct i2c_device_id *id)
+{
+	int ret;
+	struct device *hwmon_dev;
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	/* Setup continuous mode, current monitor */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
+		LTC2990_CONTROL_MEASURE_ALL | LTC2990_CONTROL_MODE_CURRENT);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
+		return ret;
+	}
+	/* Trigger once to start continuous conversion */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to start aquisition.\n");
+		return ret;
+	}
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
+							   i2c->name,
+							   i2c,
+							   ltc2990_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id ltc2990_i2c_id[] = {
+	{ "ltc2990", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
+
+static struct i2c_driver ltc2990_i2c_driver = {
+	.driver = {
+		.name = "ltc2990",
+	},
+	.probe    = ltc2990_i2c_probe,
+	.id_table = ltc2990_i2c_id,
+};
+
+module_i2c_driver(ltc2990_i2c_driver);
+
+MODULE_DESCRIPTION("LTC2990 Sensor Driver");
+MODULE_AUTHOR("Topic Embedded Products");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 11:05   ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 11:05 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

VGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMg
U3lzdGVtIE1vbml0b3IuClRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9s
dGFnZSwgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUKbW9uaXRvcmluZy4gVGhpcyBkcml2ZXIgY3Vy
cmVudGx5IG9ubHkgc3VwcG9ydHMgcmVhZGluZyB0d28gY3VycmVudHMKYnkgbWVhc3VyaW5nIHR3
byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCmFkZGl0
aW9uIHRvIHRoZSBWY2Mgc3VwcGx5IHZvbHRhZ2UgYW5kIGludGVybmFsIHRlbXBlcmF0dXJlLgoK
VGhpcyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1
c2VzIHRoaXMgY2hpcAp0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ
R0EgYW5kIHRoZSBDUFUgcGFydHMuCgpTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlr
ZS5sb29pam1hbnNAdG9waWMubmw+Ci0tLQp2MjogUHJvY2Vzc2VkIGFsbCByZXZpZXcgY29tbWVu
dHMuCiAgICBQdXQgY2hpcCBpbnRvIGNvbnRpbnVvdXMgbWVhc3VyZW1lbnQgbW9kZS4KICAgIEFk
ZGVkIGR1Y3VtZW50YXRpb24uCiAgICBVc2Ugc3RhbmRhcmQgaHdtb24gaW50ZXJmYWNlcyBhbmQg
bWFjcm9zLgoKIERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MCB8ICA0NCArKysrKysrKysrKysK
IGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCiBkcml2ZXJzL2h3bW9uL01h
a2VmaWxlICAgICAgfCAgIDEgKwogZHJpdmVycy9od21vbi9sdGMyOTkwLmMgICAgIHwgMTYwICsr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiA0IGZpbGVzIGNoYW5n
ZWQsIDIxOSBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9o
d21vbi9sdGMyOTkwCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9od21vbi9sdGMyOTkwLmMK
CmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAgYi9Eb2N1bWVudGF0aW9u
L2h3bW9uL2x0YzI5OTAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM4Yjc0
ZQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MApAQCAtMCww
ICsxLDQ0IEBACitLZXJuZWwgZHJpdmVyIGx0YzI5OTAKKz09PT09PT09PT09PT09PT09PT09PQor
CitTdXBwb3J0ZWQgY2hpcHM6CisgICogTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MAorICAgIFBy
ZWZpeDogJ2x0YzI5OTAnCisgICAgQWRkcmVzc2VzIHNjYW5uZWQ6IC0KKyAgICBEYXRhc2hlZXQ6
IGh0dHA6Ly93d3cubGluZWFyLmNvbS9wcm9kdWN0L2x0YzI5OTAKKworQXV0aG9yOiBNaWtlIExv
b2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+CisKKworRGVzY3JpcHRpb24KKy0tLS0t
LS0tLS0tCisKK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdlLCBDdXJyZW50IGFuZCBUZW1w
ZXJhdHVyZSBNb25pdG9yLgorVGhlIGNoaXAncyBpbnB1dHMgY2FuIG1lYXN1cmUgNCB2b2x0YWdl
cywgb3IgdHdvIGlucHV0cyB0b2dldGhlciAoMSsyIGFuZCAzKzQpCitjYW4gYmUgY29tYmluZWQg
dG8gbWVhc3VyZSBhIGRpZmZlcmVudGlhbCB2b2x0YWdlLCB3aGljaCBpcyB0eXBpY2FsbHkgdXNl
ZCB0bworbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBzZXJpZXMgcmVzaXN0b3IsIG9yIGEgdGVt
cGVyYXR1cmUuCisKK1RoaXMgZHJpdmVyIGN1cnJlbnRseSB1c2VzIHRoZSAyeCBkaWZmZXJlbnRp
YWwgbW9kZSBvbmx5LiBJbiBvcmRlciB0byBzdXBwb3J0CitvdGhlciBtb2RlcywgdGhlIGRyaXZl
ciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQuCisKKworVXNhZ2UgTm90ZXMKKy0tLS0tLS0tLS0t
CisKK1RoaXMgZHJpdmVyIGRvZXMgbm90IHByb2JlIGZvciBQTUJ1cyBkZXZpY2VzLiBZb3Ugd2ls
bCBoYXZlIHRvIGluc3RhbnRpYXRlCitkZXZpY2VzIGV4cGxpY2l0bHkuCisKKworU3lzZnMgYXR0
cmlidXRlcworLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgImN1cnIqX2lucHV0IiBtZWFzdXJlbWVu
dHMgYWN0dWFsbHkgcmVwb3J0IHRoZSB2b2x0YWdlIGRyb3AgYWNyb3NzIHRoZQoraW5wdXQgcGlu
cyBpbiBtaWNyb3ZvbHRzLiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGN1cnJlbnQgdGhyb3Vn
aCBhIDFtT2htCitzZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSByZXBvcnRlZCB2YWx1ZSBieSB0
aGUgYWN0dWFsIHNlbnNlIHJlc2lzdG9yIHZhbHVlCitpbiBtT2htIHRvIGdldCB0aGUgYWN0dWFs
IHZhbHVlLgorCitpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNjIHBpbiBpbiBtaWxsaXZvbHQg
KHJhbmdlIDIuNVYgdG8gNVYpCit0ZW1wMV9pbnB1dCAgIEludGVybmFsIGNoaXAgdGVtcGVyYXR1
cmUgaW4gbWlsbGlkZWdyZWVzIENlbGNpdXMKK2N1cnIxX2lucHV0ICAgQ3VycmVudCBpbiBtQSBh
Y3Jvc3MgdjEtdjIgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNpc3Rvci4KK2N1cnIyX2lucHV0
ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNp
c3Rvci4KKwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9od21v
bi9LY29uZmlnCmluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdt
b24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKQEAgLTY4NSw2ICs2ODUsMjAg
QEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQogCSAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUgYnVp
bHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKIAkgIGJlIGNhbGxlZCBsdGMy
OTQ1LgogCitjb25maWcgU0VOU09SU19MVEMyOTkwCisJdHJpc3RhdGUgIkxpbmVhciBUZWNobm9s
b2d5IExUQzI5OTAgKGN1cnJlbnQgbW9uaXRvcmluZyBtb2RlIG9ubHkpIgorCWRlcGVuZHMgb24g
STJDCisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExp
bmVhciBUZWNobm9sb2d5IExUQzI5OTAKKwkgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5
OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLAorCSAgY3VycmVudCBhbmQgdGVt
cGVyYXR1cmUgbW9uaXRvcmluZywgYnV0IGluIGFkZGl0aW9uIHRvIHRoZSBWY2Mgc3VwcGx5CisJ
ICB2b2x0YWdlIGFuZCBjaGlwIHRlbXBlcmF0dXJlLCB0aGlzIGRyaXZlciBjdXJyZW50bHkgb25s
eSBzdXBwb3J0cworCSAgcmVhZGluZyB0d28gY3VycmVudHMgYnkgbWVhc3VyaW5nIHR3byBkaWZm
ZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzCisJICBzZXJpZXMgcmVzaXN0b3JzLgorCisJICBUaGlz
IGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUg
d2lsbAorCSAgYmUgY2FsbGVkIGx0YzI5OTAuCisKIGNvbmZpZyBTRU5TT1JTX0xUQzQxNTEKIAl0
cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKIAlkZXBlbmRzIG9uIEkyQwpkaWZm
IC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUK
aW5kZXggMTJhMzIzOS4uZTRiZDE1YiAxMDA2NDQKLS0tIGEvZHJpdmVycy9od21vbi9NYWtlZmls
ZQorKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCkBAIC0xMDEsNiArMTAxLDcgQEAgb2JqLSQo
Q09ORklHX1NFTlNPUlNfTE05NTIzNCkJKz0gbG05NTIzNC5vCiBvYmotJChDT05GSUdfU0VOU09S
U19MTTk1MjQxKQkrPSBsbTk1MjQxLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDUpCSs9
IGxtOTUyNDUubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk0NSkJKz0gbHRjMjk0NS5vCitv
YmotJChDT05GSUdfU0VOU09SU19MVEMyOTkwKQkrPSBsdGMyOTkwLm8KIG9iai0kKENPTkZJR19T
RU5TT1JTX0xUQzQxNTEpCSs9IGx0YzQxNTEubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIx
NSkJKz0gbHRjNDIxNS5vCiBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MjIyKQkrPSBsdGM0MjIy
Lm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jIGIvZHJpdmVycy9od21vbi9s
dGMyOTkwLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcyMGZmNwotLS0g
L2Rldi9udWxsCisrKyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jCkBAIC0wLDAgKzEsMTYwIEBA
CisvKgorICogRHJpdmVyIGZvciBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIHBvd2VyIG1vbml0
b3IKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMKKyAq
IEF1dGhvcjogTWlrZSBMb29pam1hbnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgorICoKKyAq
IExpY2Vuc2U6IEdQTHYyCisgKgorICogVGhpcyBkcml2ZXIgYXNzdW1lcyB0aGUgY2hpcCBpcyB3
aXJlZCBhcyBhIGR1YWwgY3VycmVudCBtb25pdG9yLCBhbmQKKyAqIHJlcG9ydHMgdGhlIHZvbHRh
Z2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0IGFsc28gcmVwb3J0cworICog
dGhlIGNoaXAncyBpbnRlcm5hbCB0ZW1wZXJhdHVyZSBhbmQgVmNjIHBvd2VyIHN1cHBseSB2b2x0
YWdlLgorICovCisKKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgorI2luY2x1ZGUgPGxpbnV4L2Vy
ci5oPgorI2luY2x1ZGUgPGxpbnV4L2h3bW9uLmg+CisjaW5jbHVkZSA8bGludXgvaHdtb24tc3lz
ZnMuaD4KKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4K
KyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CisKKyNk
ZWZpbmUgTFRDMjk5MF9TVEFUVVMJMHgwMAorI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQor
I2RlZmluZSBMVEMyOTkwX1RSSUdHRVIJMHgwMgorI2RlZmluZSBMVEMyOTkwX1RJTlRfTVNCCTB4
MDQKKyNkZWZpbmUgTFRDMjk5MF9USU5UX0xTQgkweDA1CisjZGVmaW5lIExUQzI5OTBfVjFfTVNC
CTB4MDYKKyNkZWZpbmUgTFRDMjk5MF9WMV9MU0IJMHgwNworI2RlZmluZSBMVEMyOTkwX1YyX01T
QgkweDA4CisjZGVmaW5lIExUQzI5OTBfVjJfTFNCCTB4MDkKKyNkZWZpbmUgTFRDMjk5MF9WM19N
U0IJMHgwQQorI2RlZmluZSBMVEMyOTkwX1YzX0xTQgkweDBCCisjZGVmaW5lIExUQzI5OTBfVjRf
TVNCCTB4MEMKKyNkZWZpbmUgTFRDMjk5MF9WNF9MU0IJMHgwRAorI2RlZmluZSBMVEMyOTkwX1ZD
Q19NU0IJMHgwRQorI2RlZmluZSBMVEMyOTkwX1ZDQ19MU0IJMHgwRgorCisjZGVmaW5lIExUQzI5
OTBfU1RBVFVTX0JVU1kJQklUKDApCisjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1RJTlQJQklUKDEp
CisjZGVmaW5lIExUQzI5OTBfU1RBVFVTX1YxCUJJVCgyKQorI2RlZmluZSBMVEMyOTkwX1NUQVRV
U19WMglCSVQoMykKKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjMJQklUKDQpCisjZGVmaW5lIExU
QzI5OTBfU1RBVFVTX1Y0CUJJVCg1KQorI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MJQklUKDYp
CisKKy8qIE9ubHkgZGVmaW5lIGNvbnRyb2wgc2V0dGluZ3Mgd2UgYWN0dWFsbHkgdXNlICovCisj
ZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxWSU4JCUJJVCg3KQorI2RlZmluZSBMVEMyOTkwX0NP
TlRST0xfU0lOR0xFCQlCSVQoNikKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01FQVNVUkVfQUxM
CSgweDMgPDwgMykKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkweDA2Cisj
ZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UJMHgwNworCisvKiBjb252ZXJ0IHJh
dyByZWdpc3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0IHJhbmdl
ICovCitzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50IHJhdykKK3sKKwlpZiAo
cmF3ICYgQklUKDE0KSkgeworCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwg
MjsKKwl9IGVsc2UgeworCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKKwl9Cit9CisKKy8q
IFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdpdmVuIHJlZ2lzdGVyIGluIHVW
IG9yIG1DICovCitzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBpMmNfY2xpZW50
ICppMmMsIHU4IGluZGV4KQoreworCWludCB2YWw7CisJaW50IHJlc3VsdDsKKworCXZhbCA9IGky
Y19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChpMmMsIChpbmRleCA8PCAxKSArIExUQzI5OTBfVElO
VF9NU0IpOworCWlmICh1bmxpa2VseSh2YWwgPCAwKSkKKwkJcmV0dXJuIHZhbDsKKworCWlmIChp
bmRleCA9PSAwKSB7IC8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0
ICAqLworCQl2YWwgPSAodmFsICYgMHgxRkZGKSA8PCAzOworCQlyZXN1bHQgPSAodmFsICogMTAw
MCkgPj4gNzsKKwl9IGVsc2UgaWYgKGluZGV4IDwgNSkgeyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0Ig
Ki8KKwkJcmVzdWx0ID0gbHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICog
MTAwKTsKKwl9IGVsc2UgeyAvKiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCisJ
CXJlc3VsdCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAg
KiAxMDAwKTsKKwkJcmVzdWx0ICs9IDI1MDA7CisJfQorCisJcmV0dXJuIHJlc3VsdDsKK30KKwor
c3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVlKHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJ
CQkgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQoreworCXN0cnVjdCBz
ZW5zb3JfZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7CisJ
aW50IHZhbHVlOworCisJdmFsdWUgPSBsdGMyOTkwX2dldF92YWx1ZShkZXZfZ2V0X2RydmRhdGEo
ZGV2KSwgYXR0ci0+aW5kZXgpOworCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVk
XG4iLCB2YWx1ZSk7Cit9CisKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfaW5wdXQs
IFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwgMCk7CitzdGF0aWMgU0VOU09SX0RF
VklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEws
IDEpOworc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRj
Mjk5MF9zaG93X3ZhbHVlLCBOVUxMLCAzKTsKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4w
X2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsIDUpOworCitzdGF0aWMg
c3RydWN0IGF0dHJpYnV0ZSAqbHRjMjk5MF9hdHRyc1tdID0geworCSZzZW5zb3JfZGV2X2F0dHJf
dGVtcDFfaW5wdXQuZGV2X2F0dHIuYXR0ciwKKwkmc2Vuc29yX2Rldl9hdHRyX2N1cnIxX2lucHV0
LmRldl9hdHRyLmF0dHIsCisJJnNlbnNvcl9kZXZfYXR0cl9jdXJyMl9pbnB1dC5kZXZfYXR0ci5h
dHRyLAorCSZzZW5zb3JfZGV2X2F0dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCisJTlVMTCwK
K307CitBVFRSSUJVVEVfR1JPVVBTKGx0YzI5OTApOworCitzdGF0aWMgaW50IGx0YzI5OTBfaTJj
X3Byb2JlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsCisJY29uc3Qgc3RydWN0IGkyY19kZXZpY2Vf
aWQgKmlkKQoreworCWludCByZXQ7CisJc3RydWN0IGRldmljZSAqaHdtb25fZGV2OworCisJaWYg
KCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0eShpMmMtPmFkYXB0ZXIsIEkyQ19GVU5DX1NNQlVTX0JZ
VEVfREFUQSkpCisJCXJldHVybiAtRU5PREVWOworCisJLyogU2V0dXAgY29udGludW91cyBtb2Rl
LCBjdXJyZW50IG1vbml0b3IgKi8KKwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGky
YywgTFRDMjk5MF9DT05UUk9MLAorCQlMVEMyOTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfCBMVEMy
OTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKCZp
MmMtPmRldiwgIkVycm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOworCQlyZXR1
cm4gcmV0OworCX0KKwkvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBjb252ZXJz
aW9uICovCisJcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShpMmMsIExUQzI5OTBfVFJJ
R0dFUiwgMSk7CisJaWYgKHJldCA8IDApIHsKKwkJZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjog
RmFpbGVkIHRvIHN0YXJ0IGFxdWlzaXRpb24uXG4iKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlo
d21vbl9kZXYgPSBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygmaTJjLT5k
ZXYsCisJCQkJCQkJICAgaTJjLT5uYW1lLAorCQkJCQkJCSAgIGkyYywKKwkJCQkJCQkgICBsdGMy
OTkwX2dyb3Vwcyk7CisKKwlyZXR1cm4gUFRSX0VSUl9PUl9aRVJPKGh3bW9uX2Rldik7Cit9CisK
K3N0YXRpYyBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCBsdGMyOTkwX2kyY19pZFtdID0gewor
CXsgImx0YzI5OTAiLCAwIH0sCisJe30KK307CitNT0RVTEVfREVWSUNFX1RBQkxFKGkyYywgbHRj
Mjk5MF9pMmNfaWQpOworCitzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgbHRjMjk5MF9pMmNfZHJp
dmVyID0geworCS5kcml2ZXIgPSB7CisJCS5uYW1lID0gImx0YzI5OTAiLAorCX0sCisJLnByb2Jl
ICAgID0gbHRjMjk5MF9pMmNfcHJvYmUsCisJLmlkX3RhYmxlID0gbHRjMjk5MF9pMmNfaWQsCit9
OworCittb2R1bGVfaTJjX2RyaXZlcihsdGMyOTkwX2kyY19kcml2ZXIpOworCitNT0RVTEVfREVT
Q1JJUFRJT04oIkxUQzI5OTAgU2Vuc29yIERyaXZlciIpOworTU9EVUxFX0FVVEhPUigiVG9waWMg
RW1iZWRkZWQgUHJvZHVjdHMiKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKLS0gCjEuOS4x
CgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vu
c29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMu
bG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz

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

* Re: [PATCH] hwmon: Add LTC2990 sensor driver
  2016-01-08 15:09       ` [lm-sensors] " Guenter Roeck
@ 2016-01-13 11:22         ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 11:22 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

On 08-01-16 16:09, Guenter Roeck wrote:
> On 01/07/2016 10:59 AM, Mike Looijmans wrote:
>> Thank you very much for your review comments, I'll update the driver and
>> post a v2 patch.
>>
>> Inlined some replies below. Assume that I "will do" for all comments I
>> didn't comment on inline...
>>
>> On 06-01-16 16:22, Guenter Roeck wrote:
>>> Hello Mike,
>>>
>>> On 01/06/2016 12:07 AM, Mike Looijmans wrote:
>>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>>
>>> s/  / /
>>>
>>>> The LTC2990 supports a combination of voltage, current and temperature
>>>> monitoring, but this driver currently only supports reading two currents
>>>> by measuring two differential voltages across series resistors.
>>>>
>>> Plus VCC, plus the internal temperature.
>>
>> Yeah, I should give myself more credit :) I'll add that in Kconfig too.
>>
>>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>>
>>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>>> ---
>>>>   drivers/hwmon/Kconfig   |  15 +++
>>>>   drivers/hwmon/Makefile  |   1 +
>>>>   drivers/hwmon/ltc2990.c | 273
>>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>
>
> [ ... ]
>
>>>> +}
>>>> +
>>>> +static struct ltc2990_data *ltc2990_update_device(struct device *dev)
>>>> +{
>>>> +    struct i2c_client *i2c = to_i2c_client(dev);
>>>> +    struct ltc2990_data *data = i2c_get_clientdata(i2c);
>>>> +    struct ltc2990_data *ret = data;
>>>> +    unsigned int timeout;
>>>> +
>>>> +    mutex_lock(&data->update_lock);
>>>> +
>>>> +    /* Update about 4 times per second max */
>>>> +    if (time_after(jiffies, data->last_updated + HZ / 4) ||
>>>> !data->valid) {
>>>> +        int val;
>>>> +        int i;
>>>> +
>>>
>>> Please consider using continuous conversion. This would simplify the
>>> code significantly
>>> and reduce read delays.
>>
>> It might increase power consumption though, as typically some user program
>> would poll this every 10 seconds or so. I'll check the data sheet.
>>
>
> I suspect that the power savings will be less than the added power
> consumed by the CPU due to the more complex code.
>
> Really, unless you have an application where a few mW power savings
> are essential and warrant the additional code complexity, this is
> the wrong approach.

Yeah, you're right, checked the datasheet and it reports a 1mA typical power 
usage when converting. Not worth the trouble.

Continuous conversion made the driver a LOT simpler, could even completely 
drop the private data structure.

I sent v2 already, but just noticed that some of the #includes were no longer
needed, so I'll send a v3 to fix that.

...


Kind regards,

Mike Looijmans
System Expert

TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

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

* Re: [lm-sensors] [PATCH] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 11:22         ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 11:22 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

77u/T24gMDgtMDEtMTYgMTY6MDksIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gMDEvMDcvMjAx
NiAxMDo1OSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IFRoYW5rIHlvdSB2ZXJ5IG11Y2gg
Zm9yIHlvdXIgcmV2aWV3IGNvbW1lbnRzLCBJJ2xsIHVwZGF0ZSB0aGUgZHJpdmVyIGFuZAo+PiBw
b3N0IGEgdjIgcGF0Y2guCj4+Cj4+IElubGluZWQgc29tZSByZXBsaWVzIGJlbG93LiBBc3N1bWUg
dGhhdCBJICJ3aWxsIGRvIiBmb3IgYWxsIGNvbW1lbnRzIEkKPj4gZGlkbid0IGNvbW1lbnQgb24g
aW5saW5lLi4uCj4+Cj4+IE9uIDA2LTAxLTE2IDE2OjIyLCBHdWVudGVyIFJvZWNrIHdyb3RlOgo+
Pj4gSGVsbG8gTWlrZSwKPj4+Cj4+PiBPbiAwMS8wNi8yMDE2IDEyOjA3IEFNLCBNaWtlIExvb2lq
bWFucyB3cm90ZToKPj4+PiBUaGlzIGFkZHMgc3VwcG9ydCBmb3IgdGhlIExpbmVhciBUZWNobm9s
b2d5IExUQzI5OTAgIEkyQyBTeXN0ZW0gTW9uaXRvci4KPj4+Cj4+PiBzLyAgLyAvCj4+Pgo+Pj4+
IFRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9sdGFnZSwgY3VycmVudCBh
bmQgdGVtcGVyYXR1cmUKPj4+PiBtb25pdG9yaW5nLCBidXQgdGhpcyBkcml2ZXIgY3VycmVudGx5
IG9ubHkgc3VwcG9ydHMgcmVhZGluZyB0d28gY3VycmVudHMKPj4+PiBieSBtZWFzdXJpbmcgdHdv
IGRpZmZlcmVudGlhbCB2b2x0YWdlcyBhY3Jvc3Mgc2VyaWVzIHJlc2lzdG9ycy4KPj4+Pgo+Pj4g
UGx1cyBWQ0MsIHBsdXMgdGhlIGludGVybmFsIHRlbXBlcmF0dXJlLgo+Pgo+PiBZZWFoLCBJIHNo
b3VsZCBnaXZlIG15c2VsZiBtb3JlIGNyZWRpdCA6KSBJJ2xsIGFkZCB0aGF0IGluIEtjb25maWcg
dG9vLgo+Pgo+Pj4+IFRoaXMgaXMgc3VmZmljaWVudCB0byBzdXBwb3J0IHRoZSBUb3BpYyBNaWFt
aSBTT00gd2hpY2ggdXNlcyB0aGlzIGNoaXAKPj4+PiB0byBtb25pdG9yIHRoZSBjdXJyZW50cyBm
bG93aW5nIGludG8gdGhlIEZQR0EgYW5kIHRoZSBDUFUgcGFydHMuCj4+Pj4KPj4+PiBTaWduZWQt
b2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4+Pj4gLS0t
Cj4+Pj4gICBkcml2ZXJzL2h3bW9uL0tjb25maWcgICB8ICAxNSArKysKPj4+PiAgIGRyaXZlcnMv
aHdtb24vTWFrZWZpbGUgIHwgICAxICsKPj4+PiAgIGRyaXZlcnMvaHdtb24vbHRjMjk5MC5jIHwg
MjczCj4+Pj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
Cj4+Pgo+Cj4gWyAuLi4gXQo+Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3N0YXRpYyBzdHJ1Y3QgbHRj
Mjk5MF9kYXRhICpsdGMyOTkwX3VwZGF0ZV9kZXZpY2Uoc3RydWN0IGRldmljZSAqZGV2KQo+Pj4+
ICt7Cj4+Pj4gKyAgICBzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjID0gdG9faTJjX2NsaWVudChkZXYp
Owo+Pj4+ICsgICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqZGF0YSA9IGkyY19nZXRfY2xpZW50ZGF0
YShpMmMpOwo+Pj4+ICsgICAgc3RydWN0IGx0YzI5OTBfZGF0YSAqcmV0ID0gZGF0YTsKPj4+PiAr
ICAgIHVuc2lnbmVkIGludCB0aW1lb3V0Owo+Pj4+ICsKPj4+PiArICAgIG11dGV4X2xvY2soJmRh
dGEtPnVwZGF0ZV9sb2NrKTsKPj4+PiArCj4+Pj4gKyAgICAvKiBVcGRhdGUgYWJvdXQgNCB0aW1l
cyBwZXIgc2Vjb25kIG1heCAqLwo+Pj4+ICsgICAgaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgZGF0
YS0+bGFzdF91cGRhdGVkICsgSFogLyA0KSB8fAo+Pj4+ICFkYXRhLT52YWxpZCkgewo+Pj4+ICsg
ICAgICAgIGludCB2YWw7Cj4+Pj4gKyAgICAgICAgaW50IGk7Cj4+Pj4gKwo+Pj4KPj4+IFBsZWFz
ZSBjb25zaWRlciB1c2luZyBjb250aW51b3VzIGNvbnZlcnNpb24uIFRoaXMgd291bGQgc2ltcGxp
ZnkgdGhlCj4+PiBjb2RlIHNpZ25pZmljYW50bHkKPj4+IGFuZCByZWR1Y2UgcmVhZCBkZWxheXMu
Cj4+Cj4+IEl0IG1pZ2h0IGluY3JlYXNlIHBvd2VyIGNvbnN1bXB0aW9uIHRob3VnaCwgYXMgdHlw
aWNhbGx5IHNvbWUgdXNlciBwcm9ncmFtCj4+IHdvdWxkIHBvbGwgdGhpcyBldmVyeSAxMCBzZWNv
bmRzIG9yIHNvLiBJJ2xsIGNoZWNrIHRoZSBkYXRhIHNoZWV0Lgo+Pgo+Cj4gSSBzdXNwZWN0IHRo
YXQgdGhlIHBvd2VyIHNhdmluZ3Mgd2lsbCBiZSBsZXNzIHRoYW4gdGhlIGFkZGVkIHBvd2VyCj4g
Y29uc3VtZWQgYnkgdGhlIENQVSBkdWUgdG8gdGhlIG1vcmUgY29tcGxleCBjb2RlLgo+Cj4gUmVh
bGx5LCB1bmxlc3MgeW91IGhhdmUgYW4gYXBwbGljYXRpb24gd2hlcmUgYSBmZXcgbVcgcG93ZXIg
c2F2aW5ncwo+IGFyZSBlc3NlbnRpYWwgYW5kIHdhcnJhbnQgdGhlIGFkZGl0aW9uYWwgY29kZSBj
b21wbGV4aXR5LCB0aGlzIGlzCj4gdGhlIHdyb25nIGFwcHJvYWNoLgoKWWVhaCwgeW91J3JlIHJp
Z2h0LCBjaGVja2VkIHRoZSBkYXRhc2hlZXQgYW5kIGl0IHJlcG9ydHMgYSAxbUEgdHlwaWNhbCBw
b3dlciAKdXNhZ2Ugd2hlbiBjb252ZXJ0aW5nLiBOb3Qgd29ydGggdGhlIHRyb3VibGUuCgpDb250
aW51b3VzIGNvbnZlcnNpb24gbWFkZSB0aGUgZHJpdmVyIGEgTE9UIHNpbXBsZXIsIGNvdWxkIGV2
ZW4gY29tcGxldGVseSAKZHJvcCB0aGUgcHJpdmF0ZSBkYXRhIHN0cnVjdHVyZS4KCkkgc2VudCB2
MiBhbHJlYWR5LCBidXQganVzdCBub3RpY2VkIHRoYXQgc29tZSBvZiB0aGUgI2luY2x1ZGVzIHdl
cmUgbm8gbG9uZ2VyCm5lZWRlZCwgc28gSSdsbCBzZW5kIGEgdjMgdG8gZml4IHRoYXQuCgouLi4K
CgpLaW5kIHJlZ2FyZHMsCgpNaWtlIExvb2lqbWFucwpTeXN0ZW0gRXhwZXJ0CgpUT1BJQyBFbWJl
ZGRlZCBQcm9kdWN0cwpFaW5kaG92ZW5zZXdlZyAzMi1DLCBOTC01NjgzIEtIIEJlc3QKUG9zdGJ1
cyA0NDAsIE5MLTU2ODAgQUsgQmVzdApUZWxlZm9vbjogKzMxICgwKSA0OTkgMzMgNjkgNzkKRS1t
YWlsOiBtaWtlLmxvb2lqbWFuc0B0b3BpY3Byb2R1Y3RzLmNvbQpXZWJzaXRlOiB3d3cudG9waWNw
cm9kdWN0cy5jb20KClBsZWFzZSBjb25zaWRlciB0aGUgZW52aXJvbm1lbnQgYmVmb3JlIHByaW50
aW5nIHRoaXMgZS1tYWlsCgoKCgoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fCmxtLXNlbnNvcnMgbWFpbGluZyBsaXN0CmxtLXNlbnNvcnNAbG0tc2Vuc29y
cy5vcmcKaHR0cDovL2xpc3RzLmxtLXNlbnNvcnMub3JnL21haWxtYW4vbGlzdGluZm8vbG0tc2Vu
c29ycw=

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

* Re: [PATCH v2] hwmon: Add LTC2990 sensor driver
  2016-01-13 11:05   ` [lm-sensors] " Mike Looijmans
@ 2016-01-13 13:24     ` Guenter Roeck
  -1 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-13 13:24 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/13/2016 03:05 AM, Mike Looijmans wrote:
> This adds support for the Linear Technology LTC2990  I2C System Monitor.
> The LTC2990 supports a combination of voltage, current and temperature
> monitoring. This driver currently only supports reading two currents
> by measuring two differential voltages across series resistors, in
> addition to the Vcc supply voltage and internal temperature.
>
> This is sufficient to support the Topic Miami SOM which uses this chip
> to monitor the currents flowing into the FPGA and the CPU parts.
>
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>

Mike,

That looks much better. Can you send me the output of i2cdump for the chip ?
That would help me writing module test code for it.

Thanks,
Guenter

> ---
> v2: Processed all review comments.
>      Put chip into continuous measurement mode.
>      Added ducumentation.
>      Use standard hwmon interfaces and macros.
>
>   Documentation/hwmon/ltc2990 |  44 ++++++++++++
>   drivers/hwmon/Kconfig       |  14 ++++
>   drivers/hwmon/Makefile      |   1 +
>   drivers/hwmon/ltc2990.c     | 160 ++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 219 insertions(+)
>   create mode 100644 Documentation/hwmon/ltc2990
>   create mode 100644 drivers/hwmon/ltc2990.c
>
> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
> new file mode 100644
> index 0000000..838b74e
> --- /dev/null
> +++ b/Documentation/hwmon/ltc2990
> @@ -0,0 +1,44 @@
> +Kernel driver ltc2990
> +=====================
> +
> +Supported chips:
> +  * Linear Technology LTC2990
> +    Prefix: 'ltc2990'
> +    Addresses scanned: -
> +    Datasheet: http://www.linear.com/product/ltc2990
> +
> +Author: Mike Looijmans <mike.looijmans@topic.nl>
> +
> +
> +Description
> +-----------
> +
> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
> +can be combined to measure a differential voltage, which is typically used to
> +measure current through a series resistor, or a temperature.
> +
> +This driver currently uses the 2x differential mode only. In order to support
> +other modes, the driver will need to be expanded.
> +
> +
> +Usage Notes
> +-----------
> +
> +This driver does not probe for PMBus devices. You will have to instantiate
> +devices explicitly.
> +
> +
> +Sysfs attributes
> +----------------
> +
> +The "curr*_input" measurements actually report the voltage drop across the
> +input pins in microvolts. This is equivalent to the current through a 1mOhm
> +sense resistor. Divide the reported value by the actual sense resistor value
> +in mOhm to get the actual value.
> +
> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
> +temp1_input   Internal chip temperature in millidegrees Celcius
> +curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
> +curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
> +
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 80a73bf..8a31d64 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -685,6 +685,20 @@ config SENSORS_LTC2945
>   	  This driver can also be built as a module. If so, the module will
>   	  be called ltc2945.
>
> +config SENSORS_LTC2990
> +	tristate "Linear Technology LTC2990 (current monitoring mode only)"
> +	depends on I2C
> +	help
> +	  If you say yes here you get support for Linear Technology LTC2990
> +	  I2C System Monitor. The LTC2990 supports a combination of voltage,
> +	  current and temperature monitoring, but in addition to the Vcc supply
> +	  voltage and chip temperature, this driver currently only supports
> +	  reading two currents by measuring two differential voltages across
> +	  series resistors.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called ltc2990.
> +
>   config SENSORS_LTC4151
>   	tristate "Linear Technology LTC4151"
>   	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 12a3239..e4bd15b 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
>   obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
>   obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
>   obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
> +obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
>   obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
>   obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
>   obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> new file mode 100644
> index 0000000..3720ff7
> --- /dev/null
> +++ b/drivers/hwmon/ltc2990.c
> @@ -0,0 +1,160 @@
> +/*
> + * Driver for Linear Technology LTC2990 power monitor
> + *
> + * Copyright (C) 2014 Topic Embedded Products
> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
> + *
> + * License: GPLv2
> + *
> + * This driver assumes the chip is wired as a dual current monitor, and
> + * reports the voltage drop across two series resistors. It also reports
> + * the chip's internal temperature and Vcc power supply voltage.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#define LTC2990_STATUS	0x00
> +#define LTC2990_CONTROL	0x01
> +#define LTC2990_TRIGGER	0x02
> +#define LTC2990_TINT_MSB	0x04
> +#define LTC2990_TINT_LSB	0x05
> +#define LTC2990_V1_MSB	0x06
> +#define LTC2990_V1_LSB	0x07
> +#define LTC2990_V2_MSB	0x08
> +#define LTC2990_V2_LSB	0x09
> +#define LTC2990_V3_MSB	0x0A
> +#define LTC2990_V3_LSB	0x0B
> +#define LTC2990_V4_MSB	0x0C
> +#define LTC2990_V4_LSB	0x0D
> +#define LTC2990_VCC_MSB	0x0E
> +#define LTC2990_VCC_LSB	0x0F
> +

LSB not used.

> +#define LTC2990_STATUS_BUSY	BIT(0)
> +#define LTC2990_STATUS_TINT	BIT(1)
> +#define LTC2990_STATUS_V1	BIT(2)
> +#define LTC2990_STATUS_V2	BIT(3)
> +#define LTC2990_STATUS_V3	BIT(4)
> +#define LTC2990_STATUS_V4	BIT(5)
> +#define LTC2990_STATUS_VCC	BIT(6)
> +
No longer used ?

> +/* Only define control settings we actually use */

Hmmm ... but not all are used.

> +#define LTC2990_CONTROL_KELVIN		BIT(7)
> +#define LTC2990_CONTROL_SINGLE		BIT(6)
> +#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
> +#define LTC2990_CONTROL_MODE_CURRENT	0x06
> +#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
> +
> +/* convert raw register value to sign-extended integer in 16-bit range */
> +static int ltc2990_voltage_to_int(int raw)
> +{
> +	if (raw & BIT(14)) {
> +		return -(0x4000 - (raw & 0x3FFF)) << 2;
> +	} else {
> +		return (raw & 0x3FFF) << 2;
> +	}
> +}
> +
> +/* Return the converted value from the given register in uV or mC */
> +static int ltc2990_get_value(struct i2c_client *i2c, u8 index)
> +{
> +	int val;
> +	int result;
> +
> +	val = i2c_smbus_read_word_swapped(i2c, (index << 1) + LTC2990_TINT_MSB);
> +	if (unlikely(val < 0))
> +		return val;
> +
> +	if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 13-bit  */
> +		val = (val & 0x1FFF) << 3;
> +		result = (val * 1000) >> 7;
> +	} else if (index < 5) { /* Vx-Vy, 19.42uV/LSB */
> +		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
> +	} else { /* Vcc, 305.18μV/LSB, 2.5V offset */
> +		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
> +		result += 2500;
> +	}
> +
With the register in index (see below) this could be

	val = i2c_smbus_read_word_swapped(i2c, index);

	switch (index) {
	case LTC2990_TINT_MSB:
		val = (val & 0x1FFF) << 3;
		result = (val * 1000) >> 7;
		break;
	case LTC2990_V1_MSB:
	case LTC2990_V2_MSB:
		...
		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
		break;
	case LTC2990_VCC_MSB:
		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
		result += 2500;
		break;
	default:
		result = 0;	/* won't happen, makes compiler happy */
		break;
	}

which I think would be easier to understand.
	
> +	return result;
> +}
> +
> +static ssize_t ltc2990_show_value(struct device *dev,
> +				  struct device_attribute *da, char *buf)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +	int value;
> +
> +	value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);
> +	return snprintf(buf, PAGE_SIZE, "%d\n", value);
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, 0);
> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, 1);
> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, 3);
> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, 5);

Consider providing the register MSB in index.

Example:
	static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, LTC2990_TINT_MSB);




> +
> +static struct attribute *ltc2990_attrs[] = {
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr2_input.dev_attr.attr,
> +	&sensor_dev_attr_in0_input.dev_attr.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(ltc2990);
> +
> +static int ltc2990_i2c_probe(struct i2c_client *i2c,
> +	const struct i2c_device_id *id)

Please align continuation lines with '('.

> +{
> +	int ret;
> +	struct device *hwmon_dev;
> +
> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))

Also need capability to read words.

> +		return -ENODEV;
> +
> +	/* Setup continuous mode, current monitor */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
> +		LTC2990_CONTROL_MEASURE_ALL | LTC2990_CONTROL_MODE_CURRENT);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
> +		return ret;
> +	}
> +	/* Trigger once to start continuous conversion */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to start aquisition.\n");

s/aquisition/acquisition/

> +		return ret;
> +	}
> +
> +	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
> +							   i2c->name,
> +							   i2c,
> +							   ltc2990_groups);
> +
> +	return PTR_ERR_OR_ZERO(hwmon_dev);
> +}
> +
> +static const struct i2c_device_id ltc2990_i2c_id[] = {
> +	{ "ltc2990", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
> +
> +static struct i2c_driver ltc2990_i2c_driver = {
> +	.driver = {
> +		.name = "ltc2990",
> +	},
> +	.probe    = ltc2990_i2c_probe,
> +	.id_table = ltc2990_i2c_id,
> +};
> +
> +module_i2c_driver(ltc2990_i2c_driver);
> +
> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
> +MODULE_AUTHOR("Topic Embedded Products");
> +MODULE_LICENSE("GPL v2");
>

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

* Re: [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 13:24     ` Guenter Roeck
  0 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-13 13:24 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

T24gMDEvMTMvMjAxNiAwMzowNSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4gVGhpcyBhZGRz
IHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMgU3lzdGVtIE1v
bml0b3IuCj4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBj
dXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRs
eSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4gYnkgbWVhc3VyaW5nIHR3byBk
aWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCj4gYWRkaXRp
b24gdG8gdGhlIFZjYyBzdXBwbHkgdm9sdGFnZSBhbmQgaW50ZXJuYWwgdGVtcGVyYXR1cmUuCj4K
PiBUaGlzIGlzIHN1ZmZpY2llbnQgdG8gc3VwcG9ydCB0aGUgVG9waWMgTWlhbWkgU09NIHdoaWNo
IHVzZXMgdGhpcyBjaGlwCj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRo
ZSBGUEdBIGFuZCB0aGUgQ1BVIHBhcnRzLgo+Cj4gU2lnbmVkLW9mZi1ieTogTWlrZSBMb29pam1h
bnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgoKTWlrZSwKClRoYXQgbG9va3MgbXVjaCBiZXR0
ZXIuIENhbiB5b3Ugc2VuZCBtZSB0aGUgb3V0cHV0IG9mIGkyY2R1bXAgZm9yIHRoZSBjaGlwID8K
VGhhdCB3b3VsZCBoZWxwIG1lIHdyaXRpbmcgbW9kdWxlIHRlc3QgY29kZSBmb3IgaXQuCgpUaGFu
a3MsCkd1ZW50ZXIKCj4gLS0tCj4gdjI6IFByb2Nlc3NlZCBhbGwgcmV2aWV3IGNvbW1lbnRzLgo+
ICAgICAgUHV0IGNoaXAgaW50byBjb250aW51b3VzIG1lYXN1cmVtZW50IG1vZGUuCj4gICAgICBB
ZGRlZCBkdWN1bWVudGF0aW9uLgo+ICAgICAgVXNlIHN0YW5kYXJkIGh3bW9uIGludGVyZmFjZXMg
YW5kIG1hY3Jvcy4KPgo+ICAgRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIHwgIDQ0ICsrKysr
KysrKysrKwo+ICAgZHJpdmVycy9od21vbi9LY29uZmlnICAgICAgIHwgIDE0ICsrKysKPiAgIGRy
aXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICB8ICAgMSArCj4gICBkcml2ZXJzL2h3bW9uL2x0YzI5
OTAuYyAgICAgfCAxNjAgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysKPiAgIDQgZmlsZXMgY2hhbmdlZCwgMjE5IGluc2VydGlvbnMoKykKPiAgIGNyZWF0ZSBtb2Rl
IDEwMDY0NCBEb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiAgIGNyZWF0ZSBtb2RlIDEwMDY0
NCBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+Cj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24v
aHdtb24vbHRjMjk5MCBiL0RvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MAo+IG5ldyBmaWxlIG1v
ZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uODM4Yjc0ZQo+IC0tLSAvZGV2L251bGwKPiArKysg
Yi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiBAQCAtMCwwICsxLDQ0IEBACj4gK0tlcm5l
bCBkcml2ZXIgbHRjMjk5MAo+ICs9PT09PT09PT09PT09PT09PT09PT0KPiArCj4gK1N1cHBvcnRl
ZCBjaGlwczoKPiArICAqIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPiArICAgIFByZWZpeDog
J2x0YzI5OTAnCj4gKyAgICBBZGRyZXNzZXMgc2Nhbm5lZDogLQo+ICsgICAgRGF0YXNoZWV0OiBo
dHRwOi8vd3d3LmxpbmVhci5jb20vcHJvZHVjdC9sdGMyOTkwCj4gKwo+ICtBdXRob3I6IE1pa2Ug
TG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPiArCj4gKwo+ICtEZXNjcmlwdGlv
bgo+ICstLS0tLS0tLS0tLQo+ICsKPiArTFRDMjk5MCBpcyBhIFF1YWQgSTJDIFZvbHRhZ2UsIEN1
cnJlbnQgYW5kIFRlbXBlcmF0dXJlIE1vbml0b3IuCj4gK1RoZSBjaGlwJ3MgaW5wdXRzIGNhbiBt
ZWFzdXJlIDQgdm9sdGFnZXMsIG9yIHR3byBpbnB1dHMgdG9nZXRoZXIgKDErMiBhbmQgMys0KQo+
ICtjYW4gYmUgY29tYmluZWQgdG8gbWVhc3VyZSBhIGRpZmZlcmVudGlhbCB2b2x0YWdlLCB3aGlj
aCBpcyB0eXBpY2FsbHkgdXNlZCB0bwo+ICttZWFzdXJlIGN1cnJlbnQgdGhyb3VnaCBhIHNlcmll
cyByZXNpc3Rvciwgb3IgYSB0ZW1wZXJhdHVyZS4KPiArCj4gK1RoaXMgZHJpdmVyIGN1cnJlbnRs
eSB1c2VzIHRoZSAyeCBkaWZmZXJlbnRpYWwgbW9kZSBvbmx5LiBJbiBvcmRlciB0byBzdXBwb3J0
Cj4gK290aGVyIG1vZGVzLCB0aGUgZHJpdmVyIHdpbGwgbmVlZCB0byBiZSBleHBhbmRlZC4KPiAr
Cj4gKwo+ICtVc2FnZSBOb3Rlcwo+ICstLS0tLS0tLS0tLQo+ICsKPiArVGhpcyBkcml2ZXIgZG9l
cyBub3QgcHJvYmUgZm9yIFBNQnVzIGRldmljZXMuIFlvdSB3aWxsIGhhdmUgdG8gaW5zdGFudGlh
dGUKPiArZGV2aWNlcyBleHBsaWNpdGx5Lgo+ICsKPiArCj4gK1N5c2ZzIGF0dHJpYnV0ZXMKPiAr
LS0tLS0tLS0tLS0tLS0tLQo+ICsKPiArVGhlICJjdXJyKl9pbnB1dCIgbWVhc3VyZW1lbnRzIGFj
dHVhbGx5IHJlcG9ydCB0aGUgdm9sdGFnZSBkcm9wIGFjcm9zcyB0aGUKPiAraW5wdXQgcGlucyBp
biBtaWNyb3ZvbHRzLiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGN1cnJlbnQgdGhyb3VnaCBh
IDFtT2htCj4gK3NlbnNlIHJlc2lzdG9yLiBEaXZpZGUgdGhlIHJlcG9ydGVkIHZhbHVlIGJ5IHRo
ZSBhY3R1YWwgc2Vuc2UgcmVzaXN0b3IgdmFsdWUKPiAraW4gbU9obSB0byBnZXQgdGhlIGFjdHVh
bCB2YWx1ZS4KPiArCj4gK2luMF9pbnB1dCAgICAgVm9sdGFnZSBhdCBWY2MgcGluIGluIG1pbGxp
dm9sdCAocmFuZ2UgMi41ViB0byA1VikKPiArdGVtcDFfaW5wdXQgICBJbnRlcm5hbCBjaGlwIHRl
bXBlcmF0dXJlIGluIG1pbGxpZGVncmVlcyBDZWxjaXVzCj4gK2N1cnIxX2lucHV0ICAgQ3VycmVu
dCBpbiBtQSBhY3Jvc3MgdjEtdjIgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNpc3Rvci4KPiAr
Y3VycjJfaW5wdXQgICBDdXJyZW50IGluIG1BIGFjcm9zcyB2My12NCBhc3N1bWluZyBhIDFtT2ht
IHNlbnNlIHJlc2lzdG9yLgo+ICsKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29uZmln
IGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gaW5kZXggODBhNzNiZi4uOGEzMWQ2NCAxMDA2NDQK
PiAtLS0gYS9kcml2ZXJzL2h3bW9uL0tjb25maWcKPiArKysgYi9kcml2ZXJzL2h3bW9uL0tjb25m
aWcKPiBAQCAtNjg1LDYgKzY4NSwyMCBAQCBjb25maWcgU0VOU09SU19MVEMyOTQ1Cj4gICAJICBU
aGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1
bGUgd2lsbAo+ICAgCSAgYmUgY2FsbGVkIGx0YzI5NDUuCj4KPiArY29uZmlnIFNFTlNPUlNfTFRD
Mjk5MAo+ICsJdHJpc3RhdGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgKGN1cnJlbnQgbW9u
aXRvcmluZyBtb2RlIG9ubHkpIgo+ICsJZGVwZW5kcyBvbiBJMkMKPiArCWhlbHAKPiArCSAgSWYg
eW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNobm9sb2d5IExU
QzI5OTAKPiArCSAgSTJDIFN5c3RlbSBNb25pdG9yLiBUaGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNv
bWJpbmF0aW9uIG9mIHZvbHRhZ2UsCj4gKwkgIGN1cnJlbnQgYW5kIHRlbXBlcmF0dXJlIG1vbml0
b3JpbmcsIGJ1dCBpbiBhZGRpdGlvbiB0byB0aGUgVmNjIHN1cHBseQo+ICsJICB2b2x0YWdlIGFu
ZCBjaGlwIHRlbXBlcmF0dXJlLCB0aGlzIGRyaXZlciBjdXJyZW50bHkgb25seSBzdXBwb3J0cwo+
ICsJICByZWFkaW5nIHR3byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbCB2
b2x0YWdlcyBhY3Jvc3MKPiArCSAgc2VyaWVzIHJlc2lzdG9ycy4KPiArCj4gKwkgIFRoaXMgZHJp
dmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVsZSB3aWxs
Cj4gKwkgIGJlIGNhbGxlZCBsdGMyOTkwLgo+ICsKPiAgIGNvbmZpZyBTRU5TT1JTX0xUQzQxNTEK
PiAgIAl0cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKPiAgIAlkZXBlbmRzIG9u
IEkyQwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlIGIvZHJpdmVycy9od21v
bi9NYWtlZmlsZQo+IGluZGV4IDEyYTMyMzkuLmU0YmQxNWIgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVy
cy9od21vbi9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKPiBAQCAtMTAx
LDYgKzEwMSw3IEBAIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyMzQpCSs9IGxtOTUyMzQubwo+
ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTE05NTI0MSkJKz0gbG05NTI0MS5vCj4gICBvYmotJChD
T05GSUdfU0VOU09SU19MTTk1MjQ1KQkrPSBsbTk1MjQ1Lm8KPiAgIG9iai0kKENPTkZJR19TRU5T
T1JTX0xUQzI5NDUpCSs9IGx0YzI5NDUubwo+ICtvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTkw
KQkrPSBsdGMyOTkwLm8KPiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpCSs9IGx0YzQx
NTEubwo+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIxNSkJKz0gbHRjNDIxNS5vCj4gICBv
YmotJChDT05GSUdfU0VOU09SU19MVEM0MjIyKQkrPSBsdGM0MjIyLm8KPiBkaWZmIC0tZ2l0IGEv
ZHJpdmVycy9od21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+IG5ldyBm
aWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uMzcyMGZmNwo+IC0tLSAvZGV2L251bGwK
PiArKysgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+IEBAIC0wLDAgKzEsMTYwIEBACj4gKy8q
Cj4gKyAqIERyaXZlciBmb3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCBwb3dlciBtb25pdG9y
Cj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNCBUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cwo+
ICsgKiBBdXRob3I6IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPiAr
ICoKPiArICogTGljZW5zZTogR1BMdjIKPiArICoKPiArICogVGhpcyBkcml2ZXIgYXNzdW1lcyB0
aGUgY2hpcCBpcyB3aXJlZCBhcyBhIGR1YWwgY3VycmVudCBtb25pdG9yLCBhbmQKPiArICogcmVw
b3J0cyB0aGUgdm9sdGFnZSBkcm9wIGFjcm9zcyB0d28gc2VyaWVzIHJlc2lzdG9ycy4gSXQgYWxz
byByZXBvcnRzCj4gKyAqIHRoZSBjaGlwJ3MgaW50ZXJuYWwgdGVtcGVyYXR1cmUgYW5kIFZjYyBw
b3dlciBzdXBwbHkgdm9sdGFnZS4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvZGVsYXku
aD4KPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVkZSA8bGludXgvaHdtb24uaD4K
PiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9pMmMu
aD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxl
Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfU1RB
VFVTCTB4MDAKPiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQo+ICsjZGVmaW5lIExUQzI5
OTBfVFJJR0dFUgkweDAyCj4gKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0Cj4gKyNkZWZp
bmUgTFRDMjk5MF9USU5UX0xTQgkweDA1Cj4gKyNkZWZpbmUgTFRDMjk5MF9WMV9NU0IJMHgwNgo+
ICsjZGVmaW5lIExUQzI5OTBfVjFfTFNCCTB4MDcKPiArI2RlZmluZSBMVEMyOTkwX1YyX01TQgkw
eDA4Cj4gKyNkZWZpbmUgTFRDMjk5MF9WMl9MU0IJMHgwOQo+ICsjZGVmaW5lIExUQzI5OTBfVjNf
TVNCCTB4MEEKPiArI2RlZmluZSBMVEMyOTkwX1YzX0xTQgkweDBCCj4gKyNkZWZpbmUgTFRDMjk5
MF9WNF9NU0IJMHgwQwo+ICsjZGVmaW5lIExUQzI5OTBfVjRfTFNCCTB4MEQKPiArI2RlZmluZSBM
VEMyOTkwX1ZDQ19NU0IJMHgwRQo+ICsjZGVmaW5lIExUQzI5OTBfVkNDX0xTQgkweDBGCj4gKwoK
TFNCIG5vdCB1c2VkLgoKPiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19CVVNZCUJJVCgwKQo+ICsj
ZGVmaW5lIExUQzI5OTBfU1RBVFVTX1RJTlQJQklUKDEpCj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFU
VVNfVjEJQklUKDIpCj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjIJQklUKDMpCj4gKyNkZWZp
bmUgTFRDMjk5MF9TVEFUVVNfVjMJQklUKDQpCj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjQJ
QklUKDUpCj4gKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVkNDCUJJVCg2KQo+ICsKTm8gbG9uZ2Vy
IHVzZWQgPwoKPiArLyogT25seSBkZWZpbmUgY29udHJvbCBzZXR0aW5ncyB3ZSBhY3R1YWxseSB1
c2UgKi8KCkhtbW0gLi4uIGJ1dCBub3QgYWxsIGFyZSB1c2VkLgoKPiArI2RlZmluZSBMVEMyOTkw
X0NPTlRST0xfS0VMVklOCQlCSVQoNykKPiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfU0lOR0xF
CQlCSVQoNikKPiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfTUVBU1VSRV9BTEwJKDB4MyA8PCAz
KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQJMHgwNgo+ICsjZGVmaW5l
IExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UJMHgwNwo+ICsKPiArLyogY29udmVydCByYXcg
cmVnaXN0ZXIgdmFsdWUgdG8gc2lnbi1leHRlbmRlZCBpbnRlZ2VyIGluIDE2LWJpdCByYW5nZSAq
Lwo+ICtzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50IHJhdykKPiArewo+ICsJ
aWYgKHJhdyAmIEJJVCgxNCkpIHsKPiArCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZG
KSkgPDwgMjsKPiArCX0gZWxzZSB7Cj4gKwkJcmV0dXJuIChyYXcgJiAweDNGRkYpIDw8IDI7Cj4g
Kwl9Cj4gK30KPiArCj4gKy8qIFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdp
dmVuIHJlZ2lzdGVyIGluIHVWIG9yIG1DICovCj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9nZXRfdmFs
dWUoc3RydWN0IGkyY19jbGllbnQgKmkyYywgdTggaW5kZXgpCj4gK3sKPiArCWludCB2YWw7Cj4g
KwlpbnQgcmVzdWx0Owo+ICsKPiArCXZhbCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChp
MmMsIChpbmRleCA8PCAxKSArIExUQzI5OTBfVElOVF9NU0IpOwo+ICsJaWYgKHVubGlrZWx5KHZh
bCA8IDApKQo+ICsJCXJldHVybiB2YWw7Cj4gKwo+ICsJaWYgKGluZGV4ID09IDApIHsgLyogaW50
ZXJuYWwgdGVtcCwgMC4wNjI1IGRlZ3JlZXMvTFNCLCAxMy1iaXQgICovCj4gKwkJdmFsID0gKHZh
bCAmIDB4MUZGRikgPDwgMzsKPiArCQlyZXN1bHQgPSAodmFsICogMTAwMCkgPj4gNzsKPiArCX0g
ZWxzZSBpZiAoaW5kZXggPCA1KSB7IC8qIFZ4LVZ5LCAxOS40MnVWL0xTQiAqLwo+ICsJCXJlc3Vs
dCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDE5NDIgLyAoNCAqIDEwMCk7Cj4gKwl9
IGVsc2UgeyAvKiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCj4gKwkJcmVzdWx0
ID0gbHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMzA1MTggLyAoNCAqIDEwMCAqIDEwMDAp
Owo+ICsJCXJlc3VsdCArPSAyNTAwOwo+ICsJfQo+ICsKV2l0aCB0aGUgcmVnaXN0ZXIgaW4gaW5k
ZXggKHNlZSBiZWxvdykgdGhpcyBjb3VsZCBiZQoKCXZhbCA9IGkyY19zbWJ1c19yZWFkX3dvcmRf
c3dhcHBlZChpMmMsIGluZGV4KTsKCglzd2l0Y2ggKGluZGV4KSB7CgljYXNlIExUQzI5OTBfVElO
VF9NU0I6CgkJdmFsID0gKHZhbCAmIDB4MUZGRikgPDwgMzsKCQlyZXN1bHQgPSAodmFsICogMTAw
MCkgPj4gNzsKCQlicmVhazsKCWNhc2UgTFRDMjk5MF9WMV9NU0I6CgljYXNlIExUQzI5OTBfVjJf
TVNCOgoJCS4uLgoJCXJlc3VsdCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDE5NDIg
LyAoNCAqIDEwMCk7CgkJYnJlYWs7CgljYXNlIExUQzI5OTBfVkNDX01TQjoKCQlyZXN1bHQgPSBs
dGMyOTkwX3ZvbHRhZ2VfdG9faW50KHZhbCkgKiAzMDUxOCAvICg0ICogMTAwICogMTAwMCk7CgkJ
cmVzdWx0ICs9IDI1MDA7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJlc3VsdCA9IDA7CS8qIHdvbid0
IGhhcHBlbiwgbWFrZXMgY29tcGlsZXIgaGFwcHkgKi8KCQlicmVhazsKCX0KCndoaWNoIEkgdGhp
bmsgd291bGQgYmUgZWFzaWVyIHRvIHVuZGVyc3RhbmQuCgkKPiArCXJldHVybiByZXN1bHQ7Cj4g
K30KPiArCj4gK3N0YXRpYyBzc2l6ZV90IGx0YzI5OTBfc2hvd192YWx1ZShzdHJ1Y3QgZGV2aWNl
ICpkZXYsCj4gKwkJCQkgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+
ICt7Cj4gKwlzdHJ1Y3Qgc2Vuc29yX2RldmljZV9hdHRyaWJ1dGUgKmF0dHIgPSB0b19zZW5zb3Jf
ZGV2X2F0dHIoZGEpOwo+ICsJaW50IHZhbHVlOwo+ICsKPiArCXZhbHVlID0gbHRjMjk5MF9nZXRf
dmFsdWUoZGV2X2dldF9kcnZkYXRhKGRldiksIGF0dHItPmluZGV4KTsKPiArCXJldHVybiBzbnBy
aW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBT
RU5TT1JfREVWSUNFX0FUVFIodGVtcDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1
ZSwgTlVMTCwgMCk7Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoY3VycjFfaW5wdXQsIFNf
SVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwgMSk7Cj4gK3N0YXRpYyBTRU5TT1JfREVW
SUNFX0FUVFIoY3VycjJfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwg
Myk7Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBTX0lSVUdPLCBsdGMy
OTkwX3Nob3dfdmFsdWUsIE5VTEwsIDUpOwoKQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWdpc3Rl
ciBNU0IgaW4gaW5kZXguCgpFeGFtcGxlOgoJc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih0ZW1w
MV9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLCBMVEMyOTkwX1RJTlRf
TVNCKTsKCgoKCj4gKwo+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqbHRjMjk5MF9hdHRyc1td
ID0gewo+ICsJJnNlbnNvcl9kZXZfYXR0cl90ZW1wMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJ
JnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9k
ZXZfYXR0cl9jdXJyMl9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9p
bjBfaW5wdXQuZGV2X2F0dHIuYXR0ciwKPiArCU5VTEwsCj4gK307Cj4gK0FUVFJJQlVURV9HUk9V
UFMobHRjMjk5MCk7Cj4gKwo+ICtzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3Byb2JlKHN0cnVjdCBp
MmNfY2xpZW50ICppMmMsCj4gKwljb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCAqaWQpCgpQbGVh
c2UgYWxpZ24gY29udGludWF0aW9uIGxpbmVzIHdpdGggJygnLgoKPiArewo+ICsJaW50IHJldDsK
PiArCXN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsKPiArCj4gKwlpZiAoIWkyY19jaGVja19mdW5j
dGlvbmFsaXR5KGkyYy0+YWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBKSkKCkFsc28g
bmVlZCBjYXBhYmlsaXR5IHRvIHJlYWQgd29yZHMuCgo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsK
PiArCS8qIFNldHVwIGNvbnRpbnVvdXMgbW9kZSwgY3VycmVudCBtb25pdG9yICovCj4gKwlyZXQg
PSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+ICsJCUxU
QzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTCB8IExUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQp
Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWls
ZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwkv
KiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBjb252ZXJzaW9uICovCj4gKwlyZXQg
PSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9UUklHR0VSLCAxKTsKPiAr
CWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRv
IHN0YXJ0IGFxdWlzaXRpb24uXG4iKTsKCnMvYXF1aXNpdGlvbi9hY3F1aXNpdGlvbi8KCj4gKwkJ
cmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlod21vbl9kZXYgPSBkZXZtX2h3bW9uX2RldmljZV9y
ZWdpc3Rlcl93aXRoX2dyb3VwcygmaTJjLT5kZXYsCj4gKwkJCQkJCQkgICBpMmMtPm5hbWUsCj4g
KwkJCQkJCQkgICBpMmMsCj4gKwkJCQkJCQkgICBsdGMyOTkwX2dyb3Vwcyk7Cj4gKwo+ICsJcmV0
dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9kZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qg
c3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5MF9pMmNfaWRbXSA9IHsKPiArCXsgImx0YzI5OTAi
LCAwIH0sCj4gKwl7fQo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKGkyYywgbHRjMjk5MF9p
MmNfaWQpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVyIGx0YzI5OTBfaTJjX2RyaXZl
ciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAibHRjMjk5MCIsCj4gKwl9LAo+ICsJ
LnByb2JlICAgID0gbHRjMjk5MF9pMmNfcHJvYmUsCj4gKwkuaWRfdGFibGUgPSBsdGMyOTkwX2ky
Y19pZCwKPiArfTsKPiArCj4gK21vZHVsZV9pMmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7
Cj4gKwo+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkxUQzI5OTAgU2Vuc29yIERyaXZlciIpOwo+ICtN
T0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cyIpOwo+ICtNT0RVTEVfTElDRU5T
RSgiR1BMIHYyIik7Cj4KCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3Jn
Cmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM

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

* Re: [PATCH v2] hwmon: Add LTC2990 sensor driver
  2016-01-13 13:24     ` [lm-sensors] " Guenter Roeck
@ 2016-01-13 13:51       ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 13:51 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

On 13-01-16 14:24, Guenter Roeck wrote:
> On 01/13/2016 03:05 AM, Mike Looijmans wrote:
>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>> The LTC2990 supports a combination of voltage, current and temperature
>> monitoring. This driver currently only supports reading two currents
>> by measuring two differential voltages across series resistors, in
>> addition to the Vcc supply voltage and internal temperature.
>>
>> This is sufficient to support the Topic Miami SOM which uses this chip
>> to monitor the currents flowing into the FPGA and the CPU parts.
>>
>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>
> Mike,
>
> That looks much better. Can you send me the output of i2cdump for the chip ?
> That would help me writing module test code for it.

I'm kinda interested into how that would work.

I'll have to remove the driver first to get i2cdump to work on the chip. I 
cannot force a device removal from user space while running, can I?
And i suppose you want a dump of a chip in running status? (On boot, all are 
registers are simply set to zero)


> Thanks,
> Guenter
>
>> ---
>> v2: Processed all review comments.
>>      Put chip into continuous measurement mode.
>>      Added ducumentation.
>>      Use standard hwmon interfaces and macros.
>>
>>   Documentation/hwmon/ltc2990 |  44 ++++++++++++
>>   drivers/hwmon/Kconfig       |  14 ++++
>>   drivers/hwmon/Makefile      |   1 +
>>   drivers/hwmon/ltc2990.c     | 160
>> ++++++++++++++++++++++++++++++++++++++++++++
>>   4 files changed, 219 insertions(+)
>>   create mode 100644 Documentation/hwmon/ltc2990
>>   create mode 100644 drivers/hwmon/ltc2990.c
>>
>> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
>> new file mode 100644
>> index 0000000..838b74e
>> --- /dev/null
>> +++ b/Documentation/hwmon/ltc2990
>> @@ -0,0 +1,44 @@
>> +Kernel driver ltc2990
>> +=====================
>> +
>> +Supported chips:
>> +  * Linear Technology LTC2990
>> +    Prefix: 'ltc2990'
>> +    Addresses scanned: -
>> +    Datasheet: http://www.linear.com/product/ltc2990
>> +
>> +Author: Mike Looijmans <mike.looijmans@topic.nl>
>> +
>> +
>> +Description
>> +-----------
>> +
>> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
>> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
>> +can be combined to measure a differential voltage, which is typically used to
>> +measure current through a series resistor, or a temperature.
>> +
>> +This driver currently uses the 2x differential mode only. In order to support
>> +other modes, the driver will need to be expanded.
>> +
>> +
>> +Usage Notes
>> +-----------
>> +
>> +This driver does not probe for PMBus devices. You will have to instantiate
>> +devices explicitly.
>> +
>> +
>> +Sysfs attributes
>> +----------------
>> +
>> +The "curr*_input" measurements actually report the voltage drop across the
>> +input pins in microvolts. This is equivalent to the current through a 1mOhm
>> +sense resistor. Divide the reported value by the actual sense resistor value
>> +in mOhm to get the actual value.
>> +
>> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
>> +temp1_input   Internal chip temperature in millidegrees Celcius
>> +curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
>> +curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
>> +
>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
>> index 80a73bf..8a31d64 100644
>> --- a/drivers/hwmon/Kconfig
>> +++ b/drivers/hwmon/Kconfig
>> @@ -685,6 +685,20 @@ config SENSORS_LTC2945
>>         This driver can also be built as a module. If so, the module will
>>         be called ltc2945.
>>
>> +config SENSORS_LTC2990
>> +    tristate "Linear Technology LTC2990 (current monitoring mode only)"
>> +    depends on I2C
>> +    help
>> +      If you say yes here you get support for Linear Technology LTC2990
>> +      I2C System Monitor. The LTC2990 supports a combination of voltage,
>> +      current and temperature monitoring, but in addition to the Vcc supply
>> +      voltage and chip temperature, this driver currently only supports
>> +      reading two currents by measuring two differential voltages across
>> +      series resistors.
>> +
>> +      This driver can also be built as a module. If so, the module will
>> +      be called ltc2990.
>> +
>>   config SENSORS_LTC4151
>>       tristate "Linear Technology LTC4151"
>>       depends on I2C
>> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
>> index 12a3239..e4bd15b 100644
>> --- a/drivers/hwmon/Makefile
>> +++ b/drivers/hwmon/Makefile
>> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)    += lm95234.o
>>   obj-$(CONFIG_SENSORS_LM95241)    += lm95241.o
>>   obj-$(CONFIG_SENSORS_LM95245)    += lm95245.o
>>   obj-$(CONFIG_SENSORS_LTC2945)    += ltc2945.o
>> +obj-$(CONFIG_SENSORS_LTC2990)    += ltc2990.o
>>   obj-$(CONFIG_SENSORS_LTC4151)    += ltc4151.o
>>   obj-$(CONFIG_SENSORS_LTC4215)    += ltc4215.o
>>   obj-$(CONFIG_SENSORS_LTC4222)    += ltc4222.o
>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>> new file mode 100644
>> index 0000000..3720ff7
>> --- /dev/null
>> +++ b/drivers/hwmon/ltc2990.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * Driver for Linear Technology LTC2990 power monitor
>> + *
>> + * Copyright (C) 2014 Topic Embedded Products
>> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
>> + *
>> + * License: GPLv2
>> + *
>> + * This driver assumes the chip is wired as a dual current monitor, and
>> + * reports the voltage drop across two series resistors. It also reports
>> + * the chip's internal temperature and Vcc power supply voltage.
>> + */
>> +
>> +#include <linux/delay.h>

Not needed, will be removed in v3

>> +#include <linux/err.h>
>> +#include <linux/hwmon.h>
>> +#include <linux/hwmon-sysfs.h>
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>

Not needed

>> +
>> +#define LTC2990_STATUS    0x00
>> +#define LTC2990_CONTROL    0x01
>> +#define LTC2990_TRIGGER    0x02
>> +#define LTC2990_TINT_MSB    0x04
>> +#define LTC2990_TINT_LSB    0x05
>> +#define LTC2990_V1_MSB    0x06
>> +#define LTC2990_V1_LSB    0x07
>> +#define LTC2990_V2_MSB    0x08
>> +#define LTC2990_V2_LSB    0x09
>> +#define LTC2990_V3_MSB    0x0A
>> +#define LTC2990_V3_LSB    0x0B
>> +#define LTC2990_V4_MSB    0x0C
>> +#define LTC2990_V4_LSB    0x0D
>> +#define LTC2990_VCC_MSB    0x0E
>> +#define LTC2990_VCC_LSB    0x0F
>> +
>
> LSB not used.

Agree. Will remove them, it's clutter.

>
>> +#define LTC2990_STATUS_BUSY    BIT(0)
>> +#define LTC2990_STATUS_TINT    BIT(1)
>> +#define LTC2990_STATUS_V1    BIT(2)
>> +#define LTC2990_STATUS_V2    BIT(3)
>> +#define LTC2990_STATUS_V3    BIT(4)
>> +#define LTC2990_STATUS_V4    BIT(5)
>> +#define LTC2990_STATUS_VCC    BIT(6)
>> +
> No longer used ?

No need for status read when in continuous mode, so they have no point being here.

>
>> +/* Only define control settings we actually use */
>
> Hmmm ... but not all are used.

I think it's better to remove that comment :)

>> +#define LTC2990_CONTROL_KELVIN        BIT(7)
>> +#define LTC2990_CONTROL_SINGLE        BIT(6)
>> +#define LTC2990_CONTROL_MEASURE_ALL    (0x3 << 3)
>> +#define LTC2990_CONTROL_MODE_CURRENT    0x06
>> +#define LTC2990_CONTROL_MODE_VOLTAGE    0x07
>> +
>> +/* convert raw register value to sign-extended integer in 16-bit range */
>> +static int ltc2990_voltage_to_int(int raw)
>> +{
>> +    if (raw & BIT(14)) {
>> +        return -(0x4000 - (raw & 0x3FFF)) << 2;
>> +    } else {
>> +        return (raw & 0x3FFF) << 2;
>> +    }
>> +}
>> +
>> +/* Return the converted value from the given register in uV or mC */
>> +static int ltc2990_get_value(struct i2c_client *i2c, u8 index)
>> +{
>> +    int val;
>> +    int result;
>> +
>> +    val = i2c_smbus_read_word_swapped(i2c, (index << 1) + LTC2990_TINT_MSB);
>> +    if (unlikely(val < 0))
>> +        return val;
>> +
>> +    if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 13-bit  */
>> +        val = (val & 0x1FFF) << 3;
>> +        result = (val * 1000) >> 7;
>> +    } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB */
>> +        result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
>> +    } else { /* Vcc, 305.18μV/LSB, 2.5V offset */
>> +        result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
>> +        result += 2500;
>> +    }
>> +
> With the register in index (see below) this could be
>
>      val = i2c_smbus_read_word_swapped(i2c, index);
>
>      switch (index) {
>      case LTC2990_TINT_MSB:
>          val = (val & 0x1FFF) << 3;
>          result = (val * 1000) >> 7;
>          break;
>      case LTC2990_V1_MSB:
>      case LTC2990_V2_MSB:
>          ...
>          result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
>          break;
>      case LTC2990_VCC_MSB:
>          result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
>          result += 2500;
>          break;
>      default:
>          result = 0;    /* won't happen, makes compiler happy */
>          break;
>      }
>
> which I think would be easier to understand.

Agree, good point. Also using the register names helps readability.

>> +    return result;
>> +}
>> +
>> +static ssize_t ltc2990_show_value(struct device *dev,
>> +                  struct device_attribute *da, char *buf)
>> +{
>> +    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>> +    int value;
>> +
>> +    value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);
>> +    return snprintf(buf, PAGE_SIZE, "%d\n", value);
>> +}
>> +
>> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, 0);
>> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, 1);
>> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, 3);
>> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, 5);
>
> Consider providing the register MSB in index.
>
> Example:
>      static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
> LTC2990_TINT_MSB);

Agree, as above.

>> +
>> +static struct attribute *ltc2990_attrs[] = {
>> +    &sensor_dev_attr_temp1_input.dev_attr.attr,
>> +    &sensor_dev_attr_curr1_input.dev_attr.attr,
>> +    &sensor_dev_attr_curr2_input.dev_attr.attr,
>> +    &sensor_dev_attr_in0_input.dev_attr.attr,
>> +    NULL,
>> +};
>> +ATTRIBUTE_GROUPS(ltc2990);
>> +
>> +static int ltc2990_i2c_probe(struct i2c_client *i2c,
>> +    const struct i2c_device_id *id)
>
> Please align continuation lines with '('.
>
>> +{
>> +    int ret;
>> +    struct device *hwmon_dev;
>> +
>> +    if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
>
> Also need capability to read words.

Guess so...

>
>> +        return -ENODEV;
>> +
>> +    /* Setup continuous mode, current monitor */
>> +    ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
>> +        LTC2990_CONTROL_MEASURE_ALL | LTC2990_CONTROL_MODE_CURRENT);
>> +    if (ret < 0) {
>> +        dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
>> +        return ret;
>> +    }
>> +    /* Trigger once to start continuous conversion */
>> +    ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
>> +    if (ret < 0) {
>> +        dev_err(&i2c->dev, "Error: Failed to start aquisition.\n");
>
> s/aquisition/acquisition/
>
>> +        return ret;
>> +    }
>> +
>> +    hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
>> +                               i2c->name,
>> +                               i2c,
>> +                               ltc2990_groups);
>> +
>> +    return PTR_ERR_OR_ZERO(hwmon_dev);
>> +}
>> +
>> +static const struct i2c_device_id ltc2990_i2c_id[] = {
>> +    { "ltc2990", 0 },
>> +    {}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
>> +
>> +static struct i2c_driver ltc2990_i2c_driver = {
>> +    .driver = {
>> +        .name = "ltc2990",
>> +    },
>> +    .probe    = ltc2990_i2c_probe,
>> +    .id_table = ltc2990_i2c_id,
>> +};
>> +
>> +module_i2c_driver(ltc2990_i2c_driver);
>> +
>> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
>> +MODULE_AUTHOR("Topic Embedded Products");
>> +MODULE_LICENSE("GPL v2");
>>
>



Kind regards,

Mike Looijmans
System Expert

TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

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

* Re: [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 13:51       ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 13:51 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

77u/T24gMTMtMDEtMTYgMTQ6MjQsIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gMDEvMTMvMjAx
NiAwMzowNSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IFRoaXMgYWRkcyBzdXBwb3J0IGZv
ciB0aGUgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCAgSTJDIFN5c3RlbSBNb25pdG9yLgo+PiBU
aGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNvbWJpbmF0aW9uIG9mIHZvbHRhZ2UsIGN1cnJlbnQgYW5k
IHRlbXBlcmF0dXJlCj4+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1
cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4+IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50
aWFsIHZvbHRhZ2VzIGFjcm9zcyBzZXJpZXMgcmVzaXN0b3JzLCBpbgo+PiBhZGRpdGlvbiB0byB0
aGUgVmNjIHN1cHBseSB2b2x0YWdlIGFuZCBpbnRlcm5hbCB0ZW1wZXJhdHVyZS4KPj4KPj4gVGhp
cyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1c2Vz
IHRoaXMgY2hpcAo+PiB0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ
R0EgYW5kIHRoZSBDUFUgcGFydHMuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IE1pa2UgTG9vaWptYW5z
IDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPgo+IE1pa2UsCj4KPiBUaGF0IGxvb2tzIG11Y2gg
YmV0dGVyLiBDYW4geW91IHNlbmQgbWUgdGhlIG91dHB1dCBvZiBpMmNkdW1wIGZvciB0aGUgY2hp
cCA/Cj4gVGhhdCB3b3VsZCBoZWxwIG1lIHdyaXRpbmcgbW9kdWxlIHRlc3QgY29kZSBmb3IgaXQu
CgpJJ20ga2luZGEgaW50ZXJlc3RlZCBpbnRvIGhvdyB0aGF0IHdvdWxkIHdvcmsuCgpJJ2xsIGhh
dmUgdG8gcmVtb3ZlIHRoZSBkcml2ZXIgZmlyc3QgdG8gZ2V0IGkyY2R1bXAgdG8gd29yayBvbiB0
aGUgY2hpcC4gSSAKY2Fubm90IGZvcmNlIGEgZGV2aWNlIHJlbW92YWwgZnJvbSB1c2VyIHNwYWNl
IHdoaWxlIHJ1bm5pbmcsIGNhbiBJPwpBbmQgaSBzdXBwb3NlIHlvdSB3YW50IGEgZHVtcCBvZiBh
IGNoaXAgaW4gcnVubmluZyBzdGF0dXM/IChPbiBib290LCBhbGwgYXJlIApyZWdpc3RlcnMgYXJl
IHNpbXBseSBzZXQgdG8gemVybykKCgo+IFRoYW5rcywKPiBHdWVudGVyCj4KPj4gLS0tCj4+IHYy
OiBQcm9jZXNzZWQgYWxsIHJldmlldyBjb21tZW50cy4KPj4gICAgICBQdXQgY2hpcCBpbnRvIGNv
bnRpbnVvdXMgbWVhc3VyZW1lbnQgbW9kZS4KPj4gICAgICBBZGRlZCBkdWN1bWVudGF0aW9uLgo+
PiAgICAgIFVzZSBzdGFuZGFyZCBod21vbiBpbnRlcmZhY2VzIGFuZCBtYWNyb3MuCj4+Cj4+ICAg
RG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIHwgIDQ0ICsrKysrKysrKysrKwo+PiAgIGRyaXZl
cnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4+ICAgZHJpdmVycy9od21vbi9NYWtl
ZmlsZSAgICAgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYyAgICAgfCAxNjAK
Pj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4gICA0IGZp
bGVzIGNoYW5nZWQsIDIxOSBpbnNlcnRpb25zKCspCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IERv
Y3VtZW50YXRpb24vaHdtb24vbHRjMjk5MAo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz
L2h3bW9uL2x0YzI5OTAuYwo+Pgo+PiBkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9od21vbi9s
dGMyOTkwIGIvRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4+IG5ldyBmaWxlIG1vZGUgMTAw
NjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9E
b2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPj4gQEAgLTAsMCArMSw0NCBAQAo+PiArS2VybmVs
IGRyaXZlciBsdGMyOTkwCj4+ICs9PT09PT09PT09PT09PT09PT09PT0KPj4gKwo+PiArU3VwcG9y
dGVkIGNoaXBzOgo+PiArICAqIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4gKyAgICBQcmVm
aXg6ICdsdGMyOTkwJwo+PiArICAgIEFkZHJlc3NlcyBzY2FubmVkOiAtCj4+ICsgICAgRGF0YXNo
ZWV0OiBodHRwOi8vd3d3LmxpbmVhci5jb20vcHJvZHVjdC9sdGMyOTkwCj4+ICsKPj4gK0F1dGhv
cjogTWlrZSBMb29pam1hbnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgo+PiArCj4+ICsKPj4g
K0Rlc2NyaXB0aW9uCj4+ICstLS0tLS0tLS0tLQo+PiArCj4+ICtMVEMyOTkwIGlzIGEgUXVhZCBJ
MkMgVm9sdGFnZSwgQ3VycmVudCBhbmQgVGVtcGVyYXR1cmUgTW9uaXRvci4KPj4gK1RoZSBjaGlw
J3MgaW5wdXRzIGNhbiBtZWFzdXJlIDQgdm9sdGFnZXMsIG9yIHR3byBpbnB1dHMgdG9nZXRoZXIg
KDErMiBhbmQgMys0KQo+PiArY2FuIGJlIGNvbWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRp
YWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNhbGx5IHVzZWQgdG8KPj4gK21lYXN1cmUgY3VycmVu
dCB0aHJvdWdoIGEgc2VyaWVzIHJlc2lzdG9yLCBvciBhIHRlbXBlcmF0dXJlLgo+PiArCj4+ICtU
aGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUgMnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4g
SW4gb3JkZXIgdG8gc3VwcG9ydAo+PiArb3RoZXIgbW9kZXMsIHRoZSBkcml2ZXIgd2lsbCBuZWVk
IHRvIGJlIGV4cGFuZGVkLgo+PiArCj4+ICsKPj4gK1VzYWdlIE5vdGVzCj4+ICstLS0tLS0tLS0t
LQo+PiArCj4+ICtUaGlzIGRyaXZlciBkb2VzIG5vdCBwcm9iZSBmb3IgUE1CdXMgZGV2aWNlcy4g
WW91IHdpbGwgaGF2ZSB0byBpbnN0YW50aWF0ZQo+PiArZGV2aWNlcyBleHBsaWNpdGx5Lgo+PiAr
Cj4+ICsKPj4gK1N5c2ZzIGF0dHJpYnV0ZXMKPj4gKy0tLS0tLS0tLS0tLS0tLS0KPj4gKwo+PiAr
VGhlICJjdXJyKl9pbnB1dCIgbWVhc3VyZW1lbnRzIGFjdHVhbGx5IHJlcG9ydCB0aGUgdm9sdGFn
ZSBkcm9wIGFjcm9zcyB0aGUKPj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0cy4gVGhpcyBpcyBl
cXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+PiArc2Vuc2UgcmVzaXN0
b3IuIERpdmlkZSB0aGUgcmVwb3J0ZWQgdmFsdWUgYnkgdGhlIGFjdHVhbCBzZW5zZSByZXNpc3Rv
ciB2YWx1ZQo+PiAraW4gbU9obSB0byBnZXQgdGhlIGFjdHVhbCB2YWx1ZS4KPj4gKwo+PiAraW4w
X2lucHV0ICAgICBWb2x0YWdlIGF0IFZjYyBwaW4gaW4gbWlsbGl2b2x0IChyYW5nZSAyLjVWIHRv
IDVWKQo+PiArdGVtcDFfaW5wdXQgICBJbnRlcm5hbCBjaGlwIHRlbXBlcmF0dXJlIGluIG1pbGxp
ZGVncmVlcyBDZWxjaXVzCj4+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNyb3NzIHYx
LXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4+ICtjdXJyMl9pbnB1dCAgIEN1
cnJlbnQgaW4gbUEgYWNyb3NzIHYzLXY0IGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3Iu
Cj4+ICsKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt
b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi44YTMxZDY0IDEwMDY0NAo+PiAtLS0gYS9kcml2
ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02
ODUsNiArNjg1LDIwIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy
aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls
bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD
Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50
IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIGhl
bHAKPj4gKyAgICAgIElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5l
YXIgVGVjaG5vbG9neSBMVEMyOTkwCj4+ICsgICAgICBJMkMgU3lzdGVtIE1vbml0b3IuIFRoZSBM
VEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9sdGFnZSwKPj4gKyAgICAgIGN1cnJl
bnQgYW5kIHRlbXBlcmF0dXJlIG1vbml0b3JpbmcsIGJ1dCBpbiBhZGRpdGlvbiB0byB0aGUgVmNj
IHN1cHBseQo+PiArICAgICAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1wZXJhdHVyZSwgdGhpcyBkcml2
ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPj4gKyAgICAgIHJlYWRpbmcgdHdvIGN1cnJlbnRz
IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcwo+PiArICAgICAg
c2VyaWVzIHJlc2lzdG9ycy4KPj4gKwo+PiArICAgICAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUg
YnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPj4gKyAgICAgIGJlIGNh
bGxlZCBsdGMyOTkwLgo+PiArCj4+ICAgY29uZmlnIFNFTlNPUlNfTFRDNDE1MQo+PiAgICAgICB0
cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKPj4gICAgICAgZGVwZW5kcyBvbiBJ
MkMKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9u
L01ha2VmaWxlCj4+IGluZGV4IDEyYTMyMzkuLmU0YmQxNWIgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZl
cnMvaHdtb24vTWFrZWZpbGUKPj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBAQCAt
MTAxLDYgKzEwMSw3IEBAIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyMzQpICAgICs9IGxtOTUy
MzQubwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDEpICAgICs9IGxtOTUyNDEubwo+
PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDUpICAgICs9IGxtOTUyNDUubwo+PiAgIG9i
ai0kKENPTkZJR19TRU5TT1JTX0xUQzI5NDUpICAgICs9IGx0YzI5NDUubwo+PiArb2JqLSQoQ09O
RklHX1NFTlNPUlNfTFRDMjk5MCkgICAgKz0gbHRjMjk5MC5vCj4+ICAgb2JqLSQoQ09ORklHX1NF
TlNPUlNfTFRDNDE1MSkgICAgKz0gbHRjNDE1MS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNf
TFRDNDIxNSkgICAgKz0gbHRjNDIxNS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIy
MikgICAgKz0gbHRjNDIyMi5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL2x0YzI5OTAu
YyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGlu
ZGV4IDAwMDAwMDAuLjM3MjBmZjcKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2h3
bW9uL2x0YzI5OTAuYwo+PiBAQCAtMCwwICsxLDE2MCBAQAo+PiArLyoKPj4gKyAqIERyaXZlciBm
b3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCBwb3dlciBtb25pdG9yCj4+ICsgKgo+PiArICog
Q29weXJpZ2h0IChDKSAyMDE0IFRvcGljIEVtYmVkZGVkIFByb2R1Y3RzCj4+ICsgKiBBdXRob3I6
IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPj4gKyAqCj4+ICsgKiBM
aWNlbnNlOiBHUEx2Mgo+PiArICoKPj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAg
aXMgd2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4+ICsgKiByZXBvcnRzIHRo
ZSB2b2x0YWdlIGRyb3AgYWNyb3NzIHR3byBzZXJpZXMgcmVzaXN0b3JzLiBJdCBhbHNvIHJlcG9y
dHMKPj4gKyAqIHRoZSBjaGlwJ3MgaW50ZXJuYWwgdGVtcGVyYXR1cmUgYW5kIFZjYyBwb3dlciBz
dXBwbHkgdm9sdGFnZS4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvZGVsYXkuaD4K
Ck5vdCBuZWVkZWQsIHdpbGwgYmUgcmVtb3ZlZCBpbiB2MwoKPj4gKyNpbmNsdWRlIDxsaW51eC9l
cnIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9od21vbi5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3
bW9uLXN5c2ZzLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4+ICsjaW5jbHVkZSA8bGlu
dXgva2VybmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVkZSA8
bGludXgvc2xhYi5oPgoKTm90IG5lZWRlZAoKPj4gKwo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRV
UyAgICAweDAwCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTCAgICAweDAxCj4+ICsjZGVmaW5l
IExUQzI5OTBfVFJJR0dFUiAgICAweDAyCj4+ICsjZGVmaW5lIExUQzI5OTBfVElOVF9NU0IgICAg
MHgwNAo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTFNCICAgIDB4MDUKPj4gKyNkZWZpbmUgTFRD
Mjk5MF9WMV9NU0IgICAgMHgwNgo+PiArI2RlZmluZSBMVEMyOTkwX1YxX0xTQiAgICAweDA3Cj4+
ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCICAgIDB4MDgKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMl9M
U0IgICAgMHgwOQo+PiArI2RlZmluZSBMVEMyOTkwX1YzX01TQiAgICAweDBBCj4+ICsjZGVmaW5l
IExUQzI5OTBfVjNfTFNCICAgIDB4MEIKPj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IgICAgMHgw
Qwo+PiArI2RlZmluZSBMVEMyOTkwX1Y0X0xTQiAgICAweDBECj4+ICsjZGVmaW5lIExUQzI5OTBf
VkNDX01TQiAgICAweDBFCj4+ICsjZGVmaW5lIExUQzI5OTBfVkNDX0xTQiAgICAweDBGCj4+ICsK
Pgo+IExTQiBub3QgdXNlZC4KCkFncmVlLiBXaWxsIHJlbW92ZSB0aGVtLCBpdCdzIGNsdXR0ZXIu
Cgo+Cj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5l
IExUQzI5OTBfU1RBVFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVT
X1YxICAgIEJJVCgyKQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4g
KyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBf
U1RBVFVTX1Y0ICAgIEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklU
KDYpCj4+ICsKPiBObyBsb25nZXIgdXNlZCA/CgpObyBuZWVkIGZvciBzdGF0dXMgcmVhZCB3aGVu
IGluIGNvbnRpbnVvdXMgbW9kZSwgc28gdGhleSBoYXZlIG5vIHBvaW50IGJlaW5nIGhlcmUuCgo+
Cj4+ICsvKiBPbmx5IGRlZmluZSBjb250cm9sIHNldHRpbmdzIHdlIGFjdHVhbGx5IHVzZSAqLwo+
Cj4gSG1tbSAuLi4gYnV0IG5vdCBhbGwgYXJlIHVzZWQuCgpJIHRoaW5rIGl0J3MgYmV0dGVyIHRv
IHJlbW92ZSB0aGF0IGNvbW1lbnQgOikKCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxW
SU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAg
ICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01FQVNVUkVfQUxMICAgICgweDMg
PDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+
ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICsv
KiBjb252ZXJ0IHJhdyByZWdpc3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4g
MTYtYml0IHJhbmdlICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50
IHJhdykKPj4gK3sKPj4gKyAgICBpZiAocmF3ICYgQklUKDE0KSkgewo+PiArICAgICAgICByZXR1
cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPj4gKyAgICB9IGVsc2Ugewo+PiAr
ICAgICAgICByZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPj4gKyAgICB9Cj4+ICt9Cj4+ICsK
Pj4gKy8qIFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdpdmVuIHJlZ2lzdGVy
IGluIHVWIG9yIG1DICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBp
MmNfY2xpZW50ICppMmMsIHU4IGluZGV4KQo+PiArewo+PiArICAgIGludCB2YWw7Cj4+ICsgICAg
aW50IHJlc3VsdDsKPj4gKwo+PiArICAgIHZhbCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBl
ZChpMmMsIChpbmRleCA8PCAxKSArIExUQzI5OTBfVElOVF9NU0IpOwo+PiArICAgIGlmICh1bmxp
a2VseSh2YWwgPCAwKSkKPj4gKyAgICAgICAgcmV0dXJuIHZhbDsKPj4gKwo+PiArICAgIGlmIChp
bmRleCA9PSAwKSB7IC8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0
ICAqLwo+PiArICAgICAgICB2YWwgPSAodmFsICYgMHgxRkZGKSA8PCAzOwo+PiArICAgICAgICBy
ZXN1bHQgPSAodmFsICogMTAwMCkgPj4gNzsKPj4gKyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkg
eyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IgKi8KPj4gKyAgICAgICAgcmVzdWx0ID0gbHRjMjk5MF92
b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPj4gKyAgICB9IGVsc2UgeyAv
KiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCj4+ICsgICAgICAgIHJlc3VsdCA9
IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsK
Pj4gKyAgICAgICAgcmVzdWx0ICs9IDI1MDA7Cj4+ICsgICAgfQo+PiArCj4gV2l0aCB0aGUgcmVn
aXN0ZXIgaW4gaW5kZXggKHNlZSBiZWxvdykgdGhpcyBjb3VsZCBiZQo+Cj4gICAgICB2YWwgPSBp
MmNfc21idXNfcmVhZF93b3JkX3N3YXBwZWQoaTJjLCBpbmRleCk7Cj4KPiAgICAgIHN3aXRjaCAo
aW5kZXgpIHsKPiAgICAgIGNhc2UgTFRDMjk5MF9USU5UX01TQjoKPiAgICAgICAgICB2YWwgPSAo
dmFsICYgMHgxRkZGKSA8PCAzOwo+ICAgICAgICAgIHJlc3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3
Owo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgY2FzZSBMVEMyOTkwX1YxX01TQjoKPiAgICAgIGNh
c2UgTFRDMjk5MF9WMl9NU0I6Cj4gICAgICAgICAgLi4uCj4gICAgICAgICAgcmVzdWx0ID0gbHRj
Mjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPiAgICAgICAgICBi
cmVhazsKPiAgICAgIGNhc2UgTFRDMjk5MF9WQ0NfTVNCOgo+ICAgICAgICAgIHJlc3VsdCA9IGx0
YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsKPiAg
ICAgICAgICByZXN1bHQgKz0gMjUwMDsKPiAgICAgICAgICBicmVhazsKPiAgICAgIGRlZmF1bHQ6
Cj4gICAgICAgICAgcmVzdWx0ID0gMDsgICAgLyogd29uJ3QgaGFwcGVuLCBtYWtlcyBjb21waWxl
ciBoYXBweSAqLwo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgfQo+Cj4gd2hpY2ggSSB0aGluayB3
b3VsZCBiZSBlYXNpZXIgdG8gdW5kZXJzdGFuZC4KCkFncmVlLCBnb29kIHBvaW50LiBBbHNvIHVz
aW5nIHRoZSByZWdpc3RlciBuYW1lcyBoZWxwcyByZWFkYWJpbGl0eS4KCj4+ICsgICAgcmV0dXJu
IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl
KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf
YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2
aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgaW50
IHZhbHVlOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92YWx1ZShkZXZfZ2V0X2Ry
dmRhdGEoZGV2KSwgYXR0ci0+aW5kZXgpOwo+PiArICAgIHJldHVybiBzbnByaW50ZihidWYsIFBB
R0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBTRU5TT1JfREVW
SUNFX0FUVFIodGVtcDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwg
MCk7Cj4+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBs
dGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU
UihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLCAzKTsKPj4g
K3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3No
b3dfdmFsdWUsIE5VTEwsIDUpOwo+Cj4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWdpc3RlciBN
U0IgaW4gaW5kZXguCj4KPiBFeGFtcGxlOgo+ICAgICAgc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU
Uih0ZW1wMV9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+IExUQzI5
OTBfVElOVF9NU0IpOwoKQWdyZWUsIGFzIGFib3ZlLgoKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBh
dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3Rl
bXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCj4+ICsgICAgJnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9p
bnB1dC5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQu
ZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX2luMF9pbnB1dC5kZXZfYXR0
ci5hdHRyLAo+PiArICAgIE5VTEwsCj4+ICt9Owo+PiArQVRUUklCVVRFX0dST1VQUyhsdGMyOTkw
KTsKPj4gKwo+PiArc3RhdGljIGludCBsdGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVu
dCAqaTJjLAo+PiArICAgIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPgo+IFBsZWFz
ZSBhbGlnbiBjb250aW51YXRpb24gbGluZXMgd2l0aCAnKCcuCj4KPj4gK3sKPj4gKyAgICBpbnQg
cmV0Owo+PiArICAgIHN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsKPj4gKwo+PiArICAgIGlmICgh
aTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoaTJjLT5hZGFwdGVyLCBJMkNfRlVOQ19TTUJVU19CWVRF
X0RBVEEpKQo+Cj4gQWxzbyBuZWVkIGNhcGFiaWxpdHkgdG8gcmVhZCB3b3Jkcy4KCkd1ZXNzIHNv
Li4uCgo+Cj4+ICsgICAgICAgIHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgLyogU2V0dXAg
Y29udGludW91cyBtb2RlLCBjdXJyZW50IG1vbml0b3IgKi8KPj4gKyAgICByZXQgPSBpMmNfc21i
dXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMy
OTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfCBMVEMyOTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsK
Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy
cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g
cmV0Owo+PiArICAgIH0KPj4gKyAgICAvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91
cyBjb252ZXJzaW9uICovCj4+ICsgICAgcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShp
MmMsIExUQzI5OTBfVFJJR0dFUiwgMSk7Cj4+ICsgICAgaWYgKHJldCA8IDApIHsKPj4gKyAgICAg
ICAgZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRvIHN0YXJ0IGFxdWlzaXRpb24u
XG4iKTsKPgo+IHMvYXF1aXNpdGlvbi9hY3F1aXNpdGlvbi8KPgo+PiArICAgICAgICByZXR1cm4g
cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIGh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNl
X3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKCZpMmMtPmRldiwKPj4gKyAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICBpMmMtPm5hbWUsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
aTJjLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0YzI5OTBfZ3JvdXBzKTsK
Pj4gKwo+PiArICAgIHJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2KTsKPj4gK30KPj4g
Kwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10g
PSB7Cj4+ICsgICAgeyAibHRjMjk5MCIsIDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVM
RV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMyOTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1
Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2kyY19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsK
Pj4gKyAgICAgICAgLm5hbWUgPSAibHRjMjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUg
ICAgPSBsdGMyOTkwX2kyY19wcm9iZSwKPj4gKyAgICAuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19p
ZCwKPj4gK307Cj4+ICsKPj4gK21vZHVsZV9pMmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7
Cj4+ICsKPj4gK01PRFVMRV9ERVNDUklQVElPTigiTFRDMjk5MCBTZW5zb3IgRHJpdmVyIik7Cj4+
ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cyIpOwo+PiArTU9EVUxFX0xJ
Q0VOU0UoIkdQTCB2MiIpOwo+Pgo+CgoKCktpbmQgcmVnYXJkcywKCk1pa2UgTG9vaWptYW5zClN5
c3RlbSBFeHBlcnQKClRPUElDIEVtYmVkZGVkIFByb2R1Y3RzCkVpbmRob3ZlbnNld2VnIDMyLUMs
IE5MLTU2ODMgS0ggQmVzdApQb3N0YnVzIDQ0MCwgTkwtNTY4MCBBSyBCZXN0ClRlbGVmb29uOiAr
MzEgKDApIDQ5OSAzMyA2OSA3OQpFLW1haWw6IG1pa2UubG9vaWptYW5zQHRvcGljcHJvZHVjdHMu
Y29tCldlYnNpdGU6IHd3dy50b3BpY3Byb2R1Y3RzLmNvbQoKUGxlYXNlIGNvbnNpZGVyIHRoZSBl
bnZpcm9ubWVudCBiZWZvcmUgcHJpbnRpbmcgdGhpcyBlLW1haWwKCgoKCgoKX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxp
c3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcv
bWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz

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

* Re: [PATCH v2] hwmon: Add LTC2990 sensor driver
  2016-01-13 13:51       ` [lm-sensors] " Mike Looijmans
@ 2016-01-13 13:57         ` Guenter Roeck
  -1 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-13 13:57 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/13/2016 05:51 AM, Mike Looijmans wrote:
> On 13-01-16 14:24, Guenter Roeck wrote:
>> On 01/13/2016 03:05 AM, Mike Looijmans wrote:
>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>> The LTC2990 supports a combination of voltage, current and temperature
>>> monitoring. This driver currently only supports reading two currents
>>> by measuring two differential voltages across series resistors, in
>>> addition to the Vcc supply voltage and internal temperature.
>>>
>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>
>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>
>> Mike,
>>
>> That looks much better. Can you send me the output of i2cdump for the chip ?
>> That would help me writing module test code for it.
>
> I'm kinda interested into how that would work.
>
https://github.com/groeck/module-tests

> I'll have to remove the driver first to get i2cdump to work on the chip. I cannot force a device removal from user space while running, can I?
> And i suppose you want a dump of a chip in running status? (On boot, all are registers are simply set to zero)
>

Just use i2cdump -f while the driver is active.

Thanks,
Guenter

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

* Re: [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 13:57         ` Guenter Roeck
  0 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-13 13:57 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/13/2016 05:51 AM, Mike Looijmans wrote:
> On 13-01-16 14:24, Guenter Roeck wrote:
>> On 01/13/2016 03:05 AM, Mike Looijmans wrote:
>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>> The LTC2990 supports a combination of voltage, current and temperature
>>> monitoring. This driver currently only supports reading two currents
>>> by measuring two differential voltages across series resistors, in
>>> addition to the Vcc supply voltage and internal temperature.
>>>
>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>
>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>
>> Mike,
>>
>> That looks much better. Can you send me the output of i2cdump for the chip ?
>> That would help me writing module test code for it.
>
> I'm kinda interested into how that would work.
>
https://github.com/groeck/module-tests

> I'll have to remove the driver first to get i2cdump to work on the chip. I cannot force a device removal from user space while running, can I?
> And i suppose you want a dump of a chip in running status? (On boot, all are registers are simply set to zero)
>

Just use i2cdump -f while the driver is active.

Thanks,
Guenter


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [PATCH v2] hwmon: Add LTC2990 sensor driver
  2016-01-13 13:57         ` [lm-sensors] " Guenter Roeck
@ 2016-01-13 14:03           ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 14:03 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

On 13-01-16 14:57, Guenter Roeck wrote:
> On 01/13/2016 05:51 AM, Mike Looijmans wrote:
>> On 13-01-16 14:24, Guenter Roeck wrote:
>>> On 01/13/2016 03:05 AM, Mike Looijmans wrote:
>>>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>>>> The LTC2990 supports a combination of voltage, current and temperature
>>>> monitoring. This driver currently only supports reading two currents
>>>> by measuring two differential voltages across series resistors, in
>>>> addition to the Vcc supply voltage and internal temperature.
>>>>
>>>> This is sufficient to support the Topic Miami SOM which uses this chip
>>>> to monitor the currents flowing into the FPGA and the CPU parts.
>>>>
>>>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>>>
>>> Mike,
>>>
>>> That looks much better. Can you send me the output of i2cdump for the chip ?
>>> That would help me writing module test code for it.
>>
>> I'm kinda interested into how that would work.
>>
> https://github.com/groeck/module-tests
>
>> I'll have to remove the driver first to get i2cdump to work on the chip. I
>> cannot force a device removal from user space while running, can I?
>> And i suppose you want a dump of a chip in running status? (On boot, all are
>> registers are simply set to zero)
>>
>
> Just use i2cdump -f while the driver is active.

Here's the dump (twice so you can see the A/D converter is actually running):

root@topic-miami-florida-pci-xc7z015:~# i2cdump -y -f -r 0-0xf 1 0x4c b
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 7f 1e 7f 7f 82 5f 80 44 80 44 80 3f 80 3f 89 b5    ?????_?D?D??????
root@topic-miami-florida-pci-xc7z015:~# i2cdump -y -f -r 0-0xf 1 0x4c b
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 7f 1e 7f 7f 82 65 80 42 80 42 80 3d 80 3d 89 b4    ?????e?B?B?=?=??




Kind regards,

Mike Looijmans
System Expert

TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

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

* Re: [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 14:03           ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 14:03 UTC (permalink / raw)
  To: Guenter Roeck, lm-sensors; +Cc: jdelvare, linux-kernel

77u/T24gMTMtMDEtMTYgMTQ6NTcsIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gMDEvMTMvMjAx
NiAwNTo1MSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IE9uIDEzLTAxLTE2IDE0OjI0LCBH
dWVudGVyIFJvZWNrIHdyb3RlOgo+Pj4gT24gMDEvMTMvMjAxNiAwMzowNSBBTSwgTWlrZSBMb29p
am1hbnMgd3JvdGU6Cj4+Pj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5v
bG9neSBMVEMyOTkwICBJMkMgU3lzdGVtIE1vbml0b3IuCj4+Pj4gVGhlIExUQzI5OTAgc3VwcG9y
dHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+Pj4+
IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcg
dHdvIGN1cnJlbnRzCj4+Pj4gYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMg
YWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCj4+Pj4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBw
bHkgdm9sdGFnZSBhbmQgaW50ZXJuYWwgdGVtcGVyYXR1cmUuCj4+Pj4KPj4+PiBUaGlzIGlzIHN1
ZmZpY2llbnQgdG8gc3VwcG9ydCB0aGUgVG9waWMgTWlhbWkgU09NIHdoaWNoIHVzZXMgdGhpcyBj
aGlwCj4+Pj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRoZSBGUEdBIGFu
ZCB0aGUgQ1BVIHBhcnRzLgo+Pj4+Cj4+Pj4gU2lnbmVkLW9mZi1ieTogTWlrZSBMb29pam1hbnMg
PG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgo+Pj4KPj4+IE1pa2UsCj4+Pgo+Pj4gVGhhdCBsb29r
cyBtdWNoIGJldHRlci4gQ2FuIHlvdSBzZW5kIG1lIHRoZSBvdXRwdXQgb2YgaTJjZHVtcCBmb3Ig
dGhlIGNoaXAgPwo+Pj4gVGhhdCB3b3VsZCBoZWxwIG1lIHdyaXRpbmcgbW9kdWxlIHRlc3QgY29k
ZSBmb3IgaXQuCj4+Cj4+IEknbSBraW5kYSBpbnRlcmVzdGVkIGludG8gaG93IHRoYXQgd291bGQg
d29yay4KPj4KPiBodHRwczovL2dpdGh1Yi5jb20vZ3JvZWNrL21vZHVsZS10ZXN0cwo+Cj4+IEkn
bGwgaGF2ZSB0byByZW1vdmUgdGhlIGRyaXZlciBmaXJzdCB0byBnZXQgaTJjZHVtcCB0byB3b3Jr
IG9uIHRoZSBjaGlwLiBJCj4+IGNhbm5vdCBmb3JjZSBhIGRldmljZSByZW1vdmFsIGZyb20gdXNl
ciBzcGFjZSB3aGlsZSBydW5uaW5nLCBjYW4gST8KPj4gQW5kIGkgc3VwcG9zZSB5b3Ugd2FudCBh
IGR1bXAgb2YgYSBjaGlwIGluIHJ1bm5pbmcgc3RhdHVzPyAoT24gYm9vdCwgYWxsIGFyZQo+PiBy
ZWdpc3RlcnMgYXJlIHNpbXBseSBzZXQgdG8gemVybykKPj4KPgo+IEp1c3QgdXNlIGkyY2R1bXAg
LWYgd2hpbGUgdGhlIGRyaXZlciBpcyBhY3RpdmUuCgpIZXJlJ3MgdGhlIGR1bXAgKHR3aWNlIHNv
IHlvdSBjYW4gc2VlIHRoZSBBL0QgY29udmVydGVyIGlzIGFjdHVhbGx5IHJ1bm5pbmcpOgoKcm9v
dEB0b3BpYy1taWFtaS1mbG9yaWRhLXBjaS14Yzd6MDE1On4jIGkyY2R1bXAgLXkgLWYgLXIgMC0w
eGYgMSAweDRjIGIKICAgICAgMCAgMSAgMiAgMyAgNCAgNSAgNiAgNyAgOCAgOSAgYSAgYiAgYyAg
ZCAgZSAgZiAgICAwMTIzNDU2Nzg5YWJjZGVmCjAwOiA3ZiAxZSA3ZiA3ZiA4MiA1ZiA4MCA0NCA4
MCA0NCA4MCAzZiA4MCAzZiA4OSBiNSAgICA/Pz8/P18/RD9EPz8/Pz8/CnJvb3RAdG9waWMtbWlh
bWktZmxvcmlkYS1wY2kteGM3ejAxNTp+IyBpMmNkdW1wIC15IC1mIC1yIDAtMHhmIDEgMHg0YyBi
CiAgICAgIDAgIDEgIDIgIDMgIDQgIDUgIDYgIDcgIDggIDkgIGEgIGIgIGMgIGQgIGUgIGYgICAg
MDEyMzQ1Njc4OWFiY2RlZgowMDogN2YgMWUgN2YgN2YgODIgNjUgODAgNDIgODAgNDIgODAgM2Qg
ODAgM2QgODkgYjQgICAgPz8/Pz9lP0I/Qj89Pz0/PwoKCgoKS2luZCByZWdhcmRzLAoKTWlrZSBM
b29pam1hbnMKU3lzdGVtIEV4cGVydAoKVE9QSUMgRW1iZWRkZWQgUHJvZHVjdHMKRWluZGhvdmVu
c2V3ZWcgMzItQywgTkwtNTY4MyBLSCBCZXN0ClBvc3RidXMgNDQwLCBOTC01NjgwIEFLIEJlc3QK
VGVsZWZvb246ICszMSAoMCkgNDk5IDMzIDY5IDc5CkUtbWFpbDogbWlrZS5sb29pam1hbnNAdG9w
aWNwcm9kdWN0cy5jb20KV2Vic2l0ZTogd3d3LnRvcGljcHJvZHVjdHMuY29tCgpQbGVhc2UgY29u
c2lkZXIgdGhlIGVudmlyb25tZW50IGJlZm9yZSBwcmludGluZyB0aGlzIGUtbWFpbAoKCgoKCgpf
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsbS1zZW5zb3Jz
IG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0dHA6Ly9saXN0cy5sbS1z
ZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM

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

* [PATCH v3] hwmon: Add LTC2990 sensor driver
  2016-01-13 11:05   ` [lm-sensors] " Mike Looijmans
@ 2016-01-13 14:45     ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 14:45 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

This adds support for the Linear Technology LTC2990  I2C System Monitor.
The LTC2990 supports a combination of voltage, current and temperature
monitoring. This driver currently only supports reading two currents
by measuring two differential voltages across series resistors, in
addition to the Vcc supply voltage and internal temperature.

This is sufficient to support the Topic Miami SOM which uses this chip
to monitor the currents flowing into the FPGA and the CPU parts.

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
---
v3: Remove unused includes.
    Remove (most) unused register defines.
    Also check on SMBUS WORD capability.
    Use register defines as value indices.
    Alignment fixups with "(".
v2: Processed all review comments.
     Put chip into continuous measurement mode.
     Added ducumentation.
     Use standard hwmon interfaces and macros.

 Documentation/hwmon/ltc2990 |  44 ++++++++++++
 drivers/hwmon/Kconfig       |  14 ++++
 drivers/hwmon/Makefile      |   1 +
 drivers/hwmon/ltc2990.c     | 159 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 218 insertions(+)
 create mode 100644 Documentation/hwmon/ltc2990
 create mode 100644 drivers/hwmon/ltc2990.c

diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
new file mode 100644
index 0000000..838b74e
--- /dev/null
+++ b/Documentation/hwmon/ltc2990
@@ -0,0 +1,44 @@
+Kernel driver ltc2990
+=====================
+
+Supported chips:
+  * Linear Technology LTC2990
+    Prefix: 'ltc2990'
+    Addresses scanned: -
+    Datasheet: http://www.linear.com/product/ltc2990
+
+Author: Mike Looijmans <mike.looijmans@topic.nl>
+
+
+Description
+-----------
+
+LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
+The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
+can be combined to measure a differential voltage, which is typically used to
+measure current through a series resistor, or a temperature.
+
+This driver currently uses the 2x differential mode only. In order to support
+other modes, the driver will need to be expanded.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have to instantiate
+devices explicitly.
+
+
+Sysfs attributes
+----------------
+
+The "curr*_input" measurements actually report the voltage drop across the
+input pins in microvolts. This is equivalent to the current through a 1mOhm
+sense resistor. Divide the reported value by the actual sense resistor value
+in mOhm to get the actual value.
+
+in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
+temp1_input   Internal chip temperature in millidegrees Celcius
+curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
+curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
+
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 80a73bf..8a31d64 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -685,6 +685,20 @@ config SENSORS_LTC2945
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2945.
 
+config SENSORS_LTC2990
+	tristate "Linear Technology LTC2990 (current monitoring mode only)"
+	depends on I2C
+	help
+	  If you say yes here you get support for Linear Technology LTC2990
+	  I2C System Monitor. The LTC2990 supports a combination of voltage,
+	  current and temperature monitoring, but in addition to the Vcc supply
+	  voltage and chip temperature, this driver currently only supports
+	  reading two currents by measuring two differential voltages across
+	  series resistors.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc2990.
+
 config SENSORS_LTC4151
 	tristate "Linear Technology LTC4151"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 12a3239..e4bd15b 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
 obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
 obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
 obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
+obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
 obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
 obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
new file mode 100644
index 0000000..37ca5f4
--- /dev/null
+++ b/drivers/hwmon/ltc2990.c
@@ -0,0 +1,159 @@
+/*
+ * Driver for Linear Technology LTC2990 power monitor
+ *
+ * Copyright (C) 2014 Topic Embedded Products
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * License: GPLv2
+ *
+ * This driver assumes the chip is wired as a dual current monitor, and
+ * reports the voltage drop across two series resistors. It also reports
+ * the chip's internal temperature and Vcc power supply voltage.
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#define LTC2990_STATUS	0x00
+#define LTC2990_CONTROL	0x01
+#define LTC2990_TRIGGER	0x02
+#define LTC2990_TINT_MSB	0x04
+#define LTC2990_V1_MSB	0x06
+#define LTC2990_V2_MSB	0x08
+#define LTC2990_V3_MSB	0x0A
+#define LTC2990_V4_MSB	0x0C
+#define LTC2990_VCC_MSB	0x0E
+
+#define LTC2990_CONTROL_KELVIN		BIT(7)
+#define LTC2990_CONTROL_SINGLE		BIT(6)
+#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
+#define LTC2990_CONTROL_MODE_CURRENT	0x06
+#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
+
+/* convert raw register value to sign-extended integer in 16-bit range */
+static int ltc2990_voltage_to_int(int raw)
+{
+	if (raw & BIT(14)) {
+		return -(0x4000 - (raw & 0x3FFF)) << 2;
+	} else {
+		return (raw & 0x3FFF) << 2;
+	}
+}
+
+/* Return the converted value from the given register in uV or mC */
+static int ltc2990_get_value(struct i2c_client *i2c, u8 reg)
+{
+	int val;
+	int result;
+
+	val = i2c_smbus_read_word_swapped(i2c, reg);
+	if (unlikely(val < 0))
+		return val;
+	switch (reg) {
+	case LTC2990_TINT_MSB:
+		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
+		val = (val & 0x1FFF) << 3;
+		result = (val * 1000) >> 7;
+		break;
+	case LTC2990_V1_MSB:
+	case LTC2990_V3_MSB:
+		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
+		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
+		break;
+	case LTC2990_VCC_MSB:
+		/* Vcc, 305.18μV/LSB, 2.5V offset */
+		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
+		result += 2500;
+		break;
+	default:
+		result = 0; /* won't happen, keep compiler happy */
+		break;
+	}
+
+	return result;
+}
+
+static ssize_t ltc2990_show_value(struct device *dev,
+				  struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	int value;
+
+	value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);
+	return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_TINT_MSB);
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_V1_MSB);
+static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_V3_MSB);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_VCC_MSB);
+
+static struct attribute *ltc2990_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr2_input.dev_attr.attr,
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(ltc2990);
+
+static int ltc2990_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
+{
+	int ret;
+	struct device *hwmon_dev;
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	/* Setup continuous mode, current monitor */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
+					LTC2990_CONTROL_MEASURE_ALL |
+					LTC2990_CONTROL_MODE_CURRENT);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
+		return ret;
+	}
+	/* Trigger once to start continuous conversion */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
+		return ret;
+	}
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
+							   i2c->name,
+							   i2c,
+							   ltc2990_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id ltc2990_i2c_id[] = {
+	{ "ltc2990", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
+
+static struct i2c_driver ltc2990_i2c_driver = {
+	.driver = {
+		.name = "ltc2990",
+	},
+	.probe    = ltc2990_i2c_probe,
+	.id_table = ltc2990_i2c_id,
+};
+
+module_i2c_driver(ltc2990_i2c_driver);
+
+MODULE_DESCRIPTION("LTC2990 Sensor Driver");
+MODULE_AUTHOR("Topic Embedded Products");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [lm-sensors] [PATCH v3] hwmon: Add LTC2990 sensor driver
@ 2016-01-13 14:45     ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-13 14:45 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

VGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMg
U3lzdGVtIE1vbml0b3IuClRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9s
dGFnZSwgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUKbW9uaXRvcmluZy4gVGhpcyBkcml2ZXIgY3Vy
cmVudGx5IG9ubHkgc3VwcG9ydHMgcmVhZGluZyB0d28gY3VycmVudHMKYnkgbWVhc3VyaW5nIHR3
byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCmFkZGl0
aW9uIHRvIHRoZSBWY2Mgc3VwcGx5IHZvbHRhZ2UgYW5kIGludGVybmFsIHRlbXBlcmF0dXJlLgoK
VGhpcyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1
c2VzIHRoaXMgY2hpcAp0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ
R0EgYW5kIHRoZSBDUFUgcGFydHMuCgpTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlr
ZS5sb29pam1hbnNAdG9waWMubmw+Ci0tLQp2MzogUmVtb3ZlIHVudXNlZCBpbmNsdWRlcy4KICAg
IFJlbW92ZSAobW9zdCkgdW51c2VkIHJlZ2lzdGVyIGRlZmluZXMuCiAgICBBbHNvIGNoZWNrIG9u
IFNNQlVTIFdPUkQgY2FwYWJpbGl0eS4KICAgIFVzZSByZWdpc3RlciBkZWZpbmVzIGFzIHZhbHVl
IGluZGljZXMuCiAgICBBbGlnbm1lbnQgZml4dXBzIHdpdGggIigiLgp2MjogUHJvY2Vzc2VkIGFs
bCByZXZpZXcgY29tbWVudHMuCiAgICAgUHV0IGNoaXAgaW50byBjb250aW51b3VzIG1lYXN1cmVt
ZW50IG1vZGUuCiAgICAgQWRkZWQgZHVjdW1lbnRhdGlvbi4KICAgICBVc2Ugc3RhbmRhcmQgaHdt
b24gaW50ZXJmYWNlcyBhbmQgbWFjcm9zLgoKIERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MCB8
ICA0NCArKysrKysrKysrKysKIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysr
CiBkcml2ZXJzL2h3bW9uL01ha2VmaWxlICAgICAgfCAgIDEgKwogZHJpdmVycy9od21vbi9sdGMy
OTkwLmMgICAgIHwgMTU5ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrCiA0IGZpbGVzIGNoYW5nZWQsIDIxOCBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2
NDQgRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy
cy9od21vbi9sdGMyOTkwLmMKCmRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5
OTAgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5k
ZXggMDAwMDAwMC4uODM4Yjc0ZQotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRpb24vaHdt
b24vbHRjMjk5MApAQCAtMCwwICsxLDQ0IEBACitLZXJuZWwgZHJpdmVyIGx0YzI5OTAKKz09PT09
PT09PT09PT09PT09PT09PQorCitTdXBwb3J0ZWQgY2hpcHM6CisgICogTGluZWFyIFRlY2hub2xv
Z3kgTFRDMjk5MAorICAgIFByZWZpeDogJ2x0YzI5OTAnCisgICAgQWRkcmVzc2VzIHNjYW5uZWQ6
IC0KKyAgICBEYXRhc2hlZXQ6IGh0dHA6Ly93d3cubGluZWFyLmNvbS9wcm9kdWN0L2x0YzI5OTAK
KworQXV0aG9yOiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+CisKKwor
RGVzY3JpcHRpb24KKy0tLS0tLS0tLS0tCisKK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdl
LCBDdXJyZW50IGFuZCBUZW1wZXJhdHVyZSBNb25pdG9yLgorVGhlIGNoaXAncyBpbnB1dHMgY2Fu
IG1lYXN1cmUgNCB2b2x0YWdlcywgb3IgdHdvIGlucHV0cyB0b2dldGhlciAoMSsyIGFuZCAzKzQp
CitjYW4gYmUgY29tYmluZWQgdG8gbWVhc3VyZSBhIGRpZmZlcmVudGlhbCB2b2x0YWdlLCB3aGlj
aCBpcyB0eXBpY2FsbHkgdXNlZCB0bworbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBzZXJpZXMg
cmVzaXN0b3IsIG9yIGEgdGVtcGVyYXR1cmUuCisKK1RoaXMgZHJpdmVyIGN1cnJlbnRseSB1c2Vz
IHRoZSAyeCBkaWZmZXJlbnRpYWwgbW9kZSBvbmx5LiBJbiBvcmRlciB0byBzdXBwb3J0CitvdGhl
ciBtb2RlcywgdGhlIGRyaXZlciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQuCisKKworVXNhZ2Ug
Tm90ZXMKKy0tLS0tLS0tLS0tCisKK1RoaXMgZHJpdmVyIGRvZXMgbm90IHByb2JlIGZvciBQTUJ1
cyBkZXZpY2VzLiBZb3Ugd2lsbCBoYXZlIHRvIGluc3RhbnRpYXRlCitkZXZpY2VzIGV4cGxpY2l0
bHkuCisKKworU3lzZnMgYXR0cmlidXRlcworLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgImN1cnIq
X2lucHV0IiBtZWFzdXJlbWVudHMgYWN0dWFsbHkgcmVwb3J0IHRoZSB2b2x0YWdlIGRyb3AgYWNy
b3NzIHRoZQoraW5wdXQgcGlucyBpbiBtaWNyb3ZvbHRzLiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8g
dGhlIGN1cnJlbnQgdGhyb3VnaCBhIDFtT2htCitzZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSBy
ZXBvcnRlZCB2YWx1ZSBieSB0aGUgYWN0dWFsIHNlbnNlIHJlc2lzdG9yIHZhbHVlCitpbiBtT2ht
IHRvIGdldCB0aGUgYWN0dWFsIHZhbHVlLgorCitpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNj
IHBpbiBpbiBtaWxsaXZvbHQgKHJhbmdlIDIuNVYgdG8gNVYpCit0ZW1wMV9pbnB1dCAgIEludGVy
bmFsIGNoaXAgdGVtcGVyYXR1cmUgaW4gbWlsbGlkZWdyZWVzIENlbGNpdXMKK2N1cnIxX2lucHV0
ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjEtdjIgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNp
c3Rvci4KK2N1cnIyX2lucHV0ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcg
YSAxbU9obSBzZW5zZSByZXNpc3Rvci4KKwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9LY29u
ZmlnIGIvZHJpdmVycy9od21vbi9LY29uZmlnCmluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAwNjQ0
Ci0tLSBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZworKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcK
QEAgLTY4NSw2ICs2ODUsMjAgQEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQogCSAgVGhpcyBkcml2
ZXIgY2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwK
IAkgIGJlIGNhbGxlZCBsdGMyOTQ1LgogCitjb25maWcgU0VOU09SU19MVEMyOTkwCisJdHJpc3Rh
dGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgKGN1cnJlbnQgbW9uaXRvcmluZyBtb2RlIG9u
bHkpIgorCWRlcGVuZHMgb24gSTJDCisJaGVscAorCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3Ug
Z2V0IHN1cHBvcnQgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKKwkgIEkyQyBTeXN0ZW0g
TW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLAor
CSAgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUgbW9uaXRvcmluZywgYnV0IGluIGFkZGl0aW9uIHRv
IHRoZSBWY2Mgc3VwcGx5CisJICB2b2x0YWdlIGFuZCBjaGlwIHRlbXBlcmF0dXJlLCB0aGlzIGRy
aXZlciBjdXJyZW50bHkgb25seSBzdXBwb3J0cworCSAgcmVhZGluZyB0d28gY3VycmVudHMgYnkg
bWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzCisJICBzZXJpZXMgcmVz
aXN0b3JzLgorCisJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4g
SWYgc28sIHRoZSBtb2R1bGUgd2lsbAorCSAgYmUgY2FsbGVkIGx0YzI5OTAuCisKIGNvbmZpZyBT
RU5TT1JTX0xUQzQxNTEKIAl0cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKIAlk
ZXBlbmRzIG9uIEkyQwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZl
cnMvaHdtb24vTWFrZWZpbGUKaW5kZXggMTJhMzIzOS4uZTRiZDE1YiAxMDA2NDQKLS0tIGEvZHJp
dmVycy9od21vbi9NYWtlZmlsZQorKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCkBAIC0xMDEs
NiArMTAxLDcgQEAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTE05NTIzNCkJKz0gbG05NTIzNC5vCiBv
YmotJChDT05GSUdfU0VOU09SU19MTTk1MjQxKQkrPSBsbTk1MjQxLm8KIG9iai0kKENPTkZJR19T
RU5TT1JTX0xNOTUyNDUpCSs9IGxtOTUyNDUubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk0
NSkJKz0gbHRjMjk0NS5vCitvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTkwKQkrPSBsdGMyOTkw
Lm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpCSs9IGx0YzQxNTEubwogb2JqLSQoQ09O
RklHX1NFTlNPUlNfTFRDNDIxNSkJKz0gbHRjNDIxNS5vCiBvYmotJChDT05GSUdfU0VOU09SU19M
VEM0MjIyKQkrPSBsdGM0MjIyLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5j
IGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAw
MDAwMC4uMzdjYTVmNAotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5j
CkBAIC0wLDAgKzEsMTU5IEBACisvKgorICogRHJpdmVyIGZvciBMaW5lYXIgVGVjaG5vbG9neSBM
VEMyOTkwIHBvd2VyIG1vbml0b3IKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1i
ZWRkZWQgUHJvZHVjdHMKKyAqIEF1dGhvcjogTWlrZSBMb29pam1hbnMgPG1pa2UubG9vaWptYW5z
QHRvcGljLm5sPgorICoKKyAqIExpY2Vuc2U6IEdQTHYyCisgKgorICogVGhpcyBkcml2ZXIgYXNz
dW1lcyB0aGUgY2hpcCBpcyB3aXJlZCBhcyBhIGR1YWwgY3VycmVudCBtb25pdG9yLCBhbmQKKyAq
IHJlcG9ydHMgdGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0
IGFsc28gcmVwb3J0cworICogdGhlIGNoaXAncyBpbnRlcm5hbCB0ZW1wZXJhdHVyZSBhbmQgVmNj
IHBvd2VyIHN1cHBseSB2b2x0YWdlLgorICovCisKKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KKyNp
bmNsdWRlIDxsaW51eC9od21vbi5oPgorI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cisj
aW5jbHVkZSA8bGludXgvaTJjLmg+CisjaW5jbHVkZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVk
ZSA8bGludXgvbW9kdWxlLmg+CisKKyNkZWZpbmUgTFRDMjk5MF9TVEFUVVMJMHgwMAorI2RlZmlu
ZSBMVEMyOTkwX0NPTlRST0wJMHgwMQorI2RlZmluZSBMVEMyOTkwX1RSSUdHRVIJMHgwMgorI2Rl
ZmluZSBMVEMyOTkwX1RJTlRfTVNCCTB4MDQKKyNkZWZpbmUgTFRDMjk5MF9WMV9NU0IJMHgwNgor
I2RlZmluZSBMVEMyOTkwX1YyX01TQgkweDA4CisjZGVmaW5lIExUQzI5OTBfVjNfTVNCCTB4MEEK
KyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IJMHgwQworI2RlZmluZSBMVEMyOTkwX1ZDQ19NU0IJMHgw
RQorCisjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxWSU4JCUJJVCg3KQorI2RlZmluZSBMVEMy
OTkwX0NPTlRST0xfU0lOR0xFCQlCSVQoNikKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01FQVNV
UkVfQUxMCSgweDMgPDwgMykKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkw
eDA2CisjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UJMHgwNworCisvKiBjb252
ZXJ0IHJhdyByZWdpc3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0
IHJhbmdlICovCitzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50IHJhdykKK3sK
KwlpZiAocmF3ICYgQklUKDE0KSkgeworCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZG
KSkgPDwgMjsKKwl9IGVsc2UgeworCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKKwl9Cit9
CisKKy8qIFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdpdmVuIHJlZ2lzdGVy
IGluIHVWIG9yIG1DICovCitzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBpMmNf
Y2xpZW50ICppMmMsIHU4IHJlZykKK3sKKwlpbnQgdmFsOworCWludCByZXN1bHQ7CisKKwl2YWwg
PSBpMmNfc21idXNfcmVhZF93b3JkX3N3YXBwZWQoaTJjLCByZWcpOworCWlmICh1bmxpa2VseSh2
YWwgPCAwKSkKKwkJcmV0dXJuIHZhbDsKKwlzd2l0Y2ggKHJlZykgeworCWNhc2UgTFRDMjk5MF9U
SU5UX01TQjoKKwkJLyogaW50ZXJuYWwgdGVtcCwgMC4wNjI1IGRlZ3JlZXMvTFNCLCAxMy1iaXQg
ICovCisJCXZhbCA9ICh2YWwgJiAweDFGRkYpIDw8IDM7CisJCXJlc3VsdCA9ICh2YWwgKiAxMDAw
KSA+PiA3OworCQlicmVhazsKKwljYXNlIExUQzI5OTBfVjFfTVNCOgorCWNhc2UgTFRDMjk5MF9W
M19NU0I6CisJCSAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IuIERlcGVuZHMgb24gbW9kZS4gKi8KKwkJ
cmVzdWx0ID0gbHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsK
KwkJYnJlYWs7CisJY2FzZSBMVEMyOTkwX1ZDQ19NU0I6CisJCS8qIFZjYywgMzA1LjE4zrxWL0xT
QiwgMi41ViBvZmZzZXQgKi8KKwkJcmVzdWx0ID0gbHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwp
ICogMzA1MTggLyAoNCAqIDEwMCAqIDEwMDApOworCQlyZXN1bHQgKz0gMjUwMDsKKwkJYnJlYWs7
CisJZGVmYXVsdDoKKwkJcmVzdWx0ID0gMDsgLyogd29uJ3QgaGFwcGVuLCBrZWVwIGNvbXBpbGVy
IGhhcHB5ICovCisJCWJyZWFrOworCX0KKworCXJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBz
c2l6ZV90IGx0YzI5OTBfc2hvd192YWx1ZShzdHJ1Y3QgZGV2aWNlICpkZXYsCisJCQkJICBzdHJ1
Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGEsIGNoYXIgKmJ1ZikKK3sKKwlzdHJ1Y3Qgc2Vuc29yX2Rl
dmljZV9hdHRyaWJ1dGUgKmF0dHIgPSB0b19zZW5zb3JfZGV2X2F0dHIoZGEpOworCWludCB2YWx1
ZTsKKworCXZhbHVlID0gbHRjMjk5MF9nZXRfdmFsdWUoZGV2X2dldF9kcnZkYXRhKGRldiksIGF0
dHItPmluZGV4KTsKKwlyZXR1cm4gc25wcmludGYoYnVmLCBQQUdFX1NJWkUsICIlZFxuIiwgdmFs
dWUpOworfQorCitzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHRlbXAxX2lucHV0LCBTX0lSVUdP
LCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsCisJCQkgIExUQzI5OTBfVElOVF9NU0IpOworc3Rh
dGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMV9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93
X3ZhbHVlLCBOVUxMLAorCQkJICBMVEMyOTkwX1YxX01TQik7CitzdGF0aWMgU0VOU09SX0RFVklD
RV9BVFRSKGN1cnIyX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsCisJ
CQkgIExUQzI5OTBfVjNfTVNCKTsKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0
LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsCisJCQkgIExUQzI5OTBfVkNDX01T
Qik7CisKK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpsdGMyOTkwX2F0dHJzW10gPSB7CisJJnNl
bnNvcl9kZXZfYXR0cl90ZW1wMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAorCSZzZW5zb3JfZGV2X2F0
dHJfY3VycjFfaW5wdXQuZGV2X2F0dHIuYXR0ciwKKwkmc2Vuc29yX2Rldl9hdHRyX2N1cnIyX2lu
cHV0LmRldl9hdHRyLmF0dHIsCisJJnNlbnNvcl9kZXZfYXR0cl9pbjBfaW5wdXQuZGV2X2F0dHIu
YXR0ciwKKwlOVUxMLAorfTsKK0FUVFJJQlVURV9HUk9VUFMobHRjMjk5MCk7CisKK3N0YXRpYyBp
bnQgbHRjMjk5MF9pMmNfcHJvYmUoc3RydWN0IGkyY19jbGllbnQgKmkyYywKKwkJCSAgICAgY29u
c3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgKmlkKQoreworCWludCByZXQ7CisJc3RydWN0IGRldmlj
ZSAqaHdtb25fZGV2OworCisJaWYgKCFpMmNfY2hlY2tfZnVuY3Rpb25hbGl0eShpMmMtPmFkYXB0
ZXIsIEkyQ19GVU5DX1NNQlVTX0JZVEVfREFUQSB8CisJCQkJICAgICBJMkNfRlVOQ19TTUJVU19X
T1JEX0RBVEEpKQorCQlyZXR1cm4gLUVOT0RFVjsKKworCS8qIFNldHVwIGNvbnRpbnVvdXMgbW9k
ZSwgY3VycmVudCBtb25pdG9yICovCisJcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShp
MmMsIExUQzI5OTBfQ09OVFJPTCwKKwkJCQkJTFRDMjk5MF9DT05UUk9MX01FQVNVUkVfQUxMIHwK
KwkJCQkJTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVCk7CisJaWYgKHJldCA8IDApIHsKKwkJ
ZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRvIHNldCBjb250cm9sIG1vZGUuXG4i
KTsKKwkJcmV0dXJuIHJldDsKKwl9CisJLyogVHJpZ2dlciBvbmNlIHRvIHN0YXJ0IGNvbnRpbnVv
dXMgY29udmVyc2lvbiAqLworCXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoaTJjLCBM
VEMyOTkwX1RSSUdHRVIsIDEpOworCWlmIChyZXQgPCAwKSB7CisJCWRldl9lcnIoJmkyYy0+ZGV2
LCAiRXJyb3I6IEZhaWxlZCB0byBzdGFydCBhY3F1aXNpdGlvbi5cbiIpOworCQlyZXR1cm4gcmV0
OworCX0KKworCWh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhfZ3Jv
dXBzKCZpMmMtPmRldiwKKwkJCQkJCQkgICBpMmMtPm5hbWUsCisJCQkJCQkJICAgaTJjLAorCQkJ
CQkJCSAgIGx0YzI5OTBfZ3JvdXBzKTsKKworCXJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25f
ZGV2KTsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJj
X2lkW10gPSB7CisJeyAibHRjMjk5MCIsIDAgfSwKKwl7fQorfTsKK01PRFVMRV9ERVZJQ0VfVEFC
TEUoaTJjLCBsdGMyOTkwX2kyY19pZCk7CisKK3N0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBsdGMy
OTkwX2kyY19kcml2ZXIgPSB7CisJLmRyaXZlciA9IHsKKwkJLm5hbWUgPSAibHRjMjk5MCIsCisJ
fSwKKwkucHJvYmUgICAgPSBsdGMyOTkwX2kyY19wcm9iZSwKKwkuaWRfdGFibGUgPSBsdGMyOTkw
X2kyY19pZCwKK307CisKK21vZHVsZV9pMmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7CisK
K01PRFVMRV9ERVNDUklQVElPTigiTFRDMjk5MCBTZW5zb3IgRHJpdmVyIik7CitNT0RVTEVfQVVU
SE9SKCJUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cyIpOworTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIp
OwotLSAKMS45LjEKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0
dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM

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

* Re: [PATCH v3] hwmon: Add LTC2990 sensor driver
  2016-01-13 14:45     ` [lm-sensors] " Mike Looijmans
@ 2016-01-14 19:14       ` Guenter Roeck
  -1 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-14 19:14 UTC (permalink / raw)
  To: Mike Looijmans; +Cc: lm-sensors, jdelvare, linux-kernel

On Wed, Jan 13, 2016 at 03:45:01PM +0100, Mike Looijmans wrote:
> This adds support for the Linear Technology LTC2990  I2C System Monitor.
> The LTC2990 supports a combination of voltage, current and temperature
> monitoring. This driver currently only supports reading two currents
> by measuring two differential voltages across series resistors, in
> addition to the Vcc supply voltage and internal temperature.
> 
> This is sufficient to support the Topic Miami SOM which uses this chip
> to monitor the currents flowing into the FPGA and the CPU parts.
> 
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>

Hi Mike,

almost there. Please see inline.

Thanks,
Guenter

> ---
> v3: Remove unused includes.
>     Remove (most) unused register defines.
>     Also check on SMBUS WORD capability.
>     Use register defines as value indices.
>     Alignment fixups with "(".
> v2: Processed all review comments.
>      Put chip into continuous measurement mode.
>      Added ducumentation.
>      Use standard hwmon interfaces and macros.
> 
>  Documentation/hwmon/ltc2990 |  44 ++++++++++++
>  drivers/hwmon/Kconfig       |  14 ++++
>  drivers/hwmon/Makefile      |   1 +
>  drivers/hwmon/ltc2990.c     | 159 ++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 218 insertions(+)
>  create mode 100644 Documentation/hwmon/ltc2990
>  create mode 100644 drivers/hwmon/ltc2990.c
> 
> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
> new file mode 100644
> index 0000000..838b74e
> --- /dev/null
> +++ b/Documentation/hwmon/ltc2990
> @@ -0,0 +1,44 @@
> +Kernel driver ltc2990
> +=====================
> +
> +Supported chips:
> +  * Linear Technology LTC2990
> +    Prefix: 'ltc2990'
> +    Addresses scanned: -
> +    Datasheet: http://www.linear.com/product/ltc2990
> +
> +Author: Mike Looijmans <mike.looijmans@topic.nl>
> +
> +
> +Description
> +-----------
> +
> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
> +can be combined to measure a differential voltage, which is typically used to
> +measure current through a series resistor, or a temperature.
> +
> +This driver currently uses the 2x differential mode only. In order to support
> +other modes, the driver will need to be expanded.
> +
> +
> +Usage Notes
> +-----------
> +
> +This driver does not probe for PMBus devices. You will have to instantiate
> +devices explicitly.
> +
> +
> +Sysfs attributes
> +----------------
> +
> +The "curr*_input" measurements actually report the voltage drop across the
> +input pins in microvolts. This is equivalent to the current through a 1mOhm
> +sense resistor. Divide the reported value by the actual sense resistor value
> +in mOhm to get the actual value.
> +
> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
> +temp1_input   Internal chip temperature in millidegrees Celcius
> +curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
> +curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
> +
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 80a73bf..8a31d64 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -685,6 +685,20 @@ config SENSORS_LTC2945
>  	  This driver can also be built as a module. If so, the module will
>  	  be called ltc2945.
>  
> +config SENSORS_LTC2990
> +	tristate "Linear Technology LTC2990 (current monitoring mode only)"
> +	depends on I2C
> +	help
> +	  If you say yes here you get support for Linear Technology LTC2990
> +	  I2C System Monitor. The LTC2990 supports a combination of voltage,
> +	  current and temperature monitoring, but in addition to the Vcc supply
> +	  voltage and chip temperature, this driver currently only supports
> +	  reading two currents by measuring two differential voltages across
> +	  series resistors.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called ltc2990.
> +
>  config SENSORS_LTC4151
>  	tristate "Linear Technology LTC4151"
>  	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 12a3239..e4bd15b 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
>  obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
>  obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
>  obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
> +obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
>  obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
>  obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
>  obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> new file mode 100644
> index 0000000..37ca5f4
> --- /dev/null
> +++ b/drivers/hwmon/ltc2990.c
> @@ -0,0 +1,159 @@
> +/*
> + * Driver for Linear Technology LTC2990 power monitor
> + *
> + * Copyright (C) 2014 Topic Embedded Products
> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
> + *
> + * License: GPLv2
> + *
> + * This driver assumes the chip is wired as a dual current monitor, and
> + * reports the voltage drop across two series resistors. It also reports
> + * the chip's internal temperature and Vcc power supply voltage.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define LTC2990_STATUS	0x00
> +#define LTC2990_CONTROL	0x01
> +#define LTC2990_TRIGGER	0x02
> +#define LTC2990_TINT_MSB	0x04
> +#define LTC2990_V1_MSB	0x06
> +#define LTC2990_V2_MSB	0x08
> +#define LTC2990_V3_MSB	0x0A
> +#define LTC2990_V4_MSB	0x0C
> +#define LTC2990_VCC_MSB	0x0E
> +
> +#define LTC2990_CONTROL_KELVIN		BIT(7)
> +#define LTC2990_CONTROL_SINGLE		BIT(6)
> +#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
> +#define LTC2990_CONTROL_MODE_CURRENT	0x06
> +#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
> +
> +/* convert raw register value to sign-extended integer in 16-bit range */
> +static int ltc2990_voltage_to_int(int raw)
> +{
> +	if (raw & BIT(14)) {
> +		return -(0x4000 - (raw & 0x3FFF)) << 2;
> +	} else {
> +		return (raw & 0x3FFF) << 2;
> +	}

Unnecessary { }. Please see checkpatch warning.

> +}
> +
> +/* Return the converted value from the given register in uV or mC */
> +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg)
> +{
> +	int val;
> +	int result;
> +
> +	val = i2c_smbus_read_word_swapped(i2c, reg);
> +	if (unlikely(val < 0))
> +		return val;

This suggests the function returns a value < 0 on error ...

> +	switch (reg) {
> +	case LTC2990_TINT_MSB:
> +		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
> +		val = (val & 0x1FFF) << 3;
> +		result = (val * 1000) >> 7;
> +		break;
> +	case LTC2990_V1_MSB:
> +	case LTC2990_V3_MSB:
> +		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
> +		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
> +		break;
> +	case LTC2990_VCC_MSB:
> +		/* Vcc, 305.18μV/LSB, 2.5V offset */
> +		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
> +		result += 2500;
> +		break;
> +	default:
> +		result = 0; /* won't happen, keep compiler happy */

Given that, we can return some error here, and ...

> +		break;
> +	}
> +
> +	return result;
> +}
> +
> +static ssize_t ltc2990_show_value(struct device *dev,
> +				  struct device_attribute *da, char *buf)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +	int value;
> +
> +	value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);

... we should actually check the error return here.

	if (value < 0)
		return value;

> +	return snprintf(buf, PAGE_SIZE, "%d\n", value);
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_TINT_MSB);
> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_V1_MSB);
> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_V3_MSB);
> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_VCC_MSB);
> +
> +static struct attribute *ltc2990_attrs[] = {
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr2_input.dev_attr.attr,
> +	&sensor_dev_attr_in0_input.dev_attr.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(ltc2990);
> +
> +static int ltc2990_i2c_probe(struct i2c_client *i2c,
> +			     const struct i2c_device_id *id)
> +{
> +	int ret;
> +	struct device *hwmon_dev;
> +
> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
> +				     I2C_FUNC_SMBUS_WORD_DATA))
> +		return -ENODEV;
> +
> +	/* Setup continuous mode, current monitor */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
> +					LTC2990_CONTROL_MEASURE_ALL |
> +					LTC2990_CONTROL_MODE_CURRENT);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
> +		return ret;
> +	}
> +	/* Trigger once to start continuous conversion */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
> +		return ret;
> +	}
> +
> +	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
> +							   i2c->name,
> +							   i2c,
> +							   ltc2990_groups);
> +
> +	return PTR_ERR_OR_ZERO(hwmon_dev);
> +}
> +
> +static const struct i2c_device_id ltc2990_i2c_id[] = {
> +	{ "ltc2990", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
> +
> +static struct i2c_driver ltc2990_i2c_driver = {
> +	.driver = {
> +		.name = "ltc2990",
> +	},
> +	.probe    = ltc2990_i2c_probe,
> +	.id_table = ltc2990_i2c_id,
> +};
> +
> +module_i2c_driver(ltc2990_i2c_driver);
> +
> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
> +MODULE_AUTHOR("Topic Embedded Products");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1
> 

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

* Re: [lm-sensors] [PATCH v3] hwmon: Add LTC2990 sensor driver
@ 2016-01-14 19:14       ` Guenter Roeck
  0 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-14 19:14 UTC (permalink / raw)
  To: Mike Looijmans; +Cc: lm-sensors, jdelvare, linux-kernel

T24gV2VkLCBKYW4gMTMsIDIwMTYgYXQgMDM6NDU6MDFQTSArMDEwMCwgTWlrZSBMb29pam1hbnMg
d3JvdGU6Cj4gVGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMy
OTkwICBJMkMgU3lzdGVtIE1vbml0b3IuCj4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5h
dGlvbiBvZiB2b2x0YWdlLCBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+IG1vbml0b3JpbmcuIFRo
aXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4g
YnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNp
c3RvcnMsIGluCj4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkgdm9sdGFnZSBhbmQgaW50ZXJu
YWwgdGVtcGVyYXR1cmUuCj4gCj4gVGhpcyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRv
cGljIE1pYW1pIFNPTSB3aGljaCB1c2VzIHRoaXMgY2hpcAo+IHRvIG1vbml0b3IgdGhlIGN1cnJl
bnRzIGZsb3dpbmcgaW50byB0aGUgRlBHQSBhbmQgdGhlIENQVSBwYXJ0cy4KPiAKPiBTaWduZWQt
b2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+CgpIaSBNaWtl
LAoKYWxtb3N0IHRoZXJlLiBQbGVhc2Ugc2VlIGlubGluZS4KClRoYW5rcywKR3VlbnRlcgoKPiAt
LS0KPiB2MzogUmVtb3ZlIHVudXNlZCBpbmNsdWRlcy4KPiAgICAgUmVtb3ZlIChtb3N0KSB1bnVz
ZWQgcmVnaXN0ZXIgZGVmaW5lcy4KPiAgICAgQWxzbyBjaGVjayBvbiBTTUJVUyBXT1JEIGNhcGFi
aWxpdHkuCj4gICAgIFVzZSByZWdpc3RlciBkZWZpbmVzIGFzIHZhbHVlIGluZGljZXMuCj4gICAg
IEFsaWdubWVudCBmaXh1cHMgd2l0aCAiKCIuCj4gdjI6IFByb2Nlc3NlZCBhbGwgcmV2aWV3IGNv
bW1lbnRzLgo+ICAgICAgUHV0IGNoaXAgaW50byBjb250aW51b3VzIG1lYXN1cmVtZW50IG1vZGUu
Cj4gICAgICBBZGRlZCBkdWN1bWVudGF0aW9uLgo+ICAgICAgVXNlIHN0YW5kYXJkIGh3bW9uIGlu
dGVyZmFjZXMgYW5kIG1hY3Jvcy4KPiAKPiAgRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIHwg
IDQ0ICsrKysrKysrKysrKwo+ICBkcml2ZXJzL2h3bW9uL0tjb25maWcgICAgICAgfCAgMTQgKysr
Kwo+ICBkcml2ZXJzL2h3bW9uL01ha2VmaWxlICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL2h3bW9u
L2x0YzI5OTAuYyAgICAgfCAxNTkgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysKPiAgNCBmaWxlcyBjaGFuZ2VkLCAyMTggaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUg
bW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4gIGNyZWF0ZSBtb2RlIDEw
MDY0NCBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+IAo+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0
aW9uL2h3bW9uL2x0YzI5OTAgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiBuZXcgZmls
ZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPiAtLS0gL2Rldi9udWxsCj4g
KysrIGIvRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4gQEAgLTAsMCArMSw0NCBAQAo+ICtL
ZXJuZWwgZHJpdmVyIGx0YzI5OTAKPiArPT09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtTdXBw
b3J0ZWQgY2hpcHM6Cj4gKyAgKiBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKyAgICBQcmVm
aXg6ICdsdGMyOTkwJwo+ICsgICAgQWRkcmVzc2VzIHNjYW5uZWQ6IC0KPiArICAgIERhdGFzaGVl
dDogaHR0cDovL3d3dy5saW5lYXIuY29tL3Byb2R1Y3QvbHRjMjk5MAo+ICsKPiArQXV0aG9yOiBN
aWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKwo+ICsKPiArRGVzY3Jp
cHRpb24KPiArLS0tLS0tLS0tLS0KPiArCj4gK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdl
LCBDdXJyZW50IGFuZCBUZW1wZXJhdHVyZSBNb25pdG9yLgo+ICtUaGUgY2hpcCdzIGlucHV0cyBj
YW4gbWVhc3VyZSA0IHZvbHRhZ2VzLCBvciB0d28gaW5wdXRzIHRvZ2V0aGVyICgxKzIgYW5kIDMr
NCkKPiArY2FuIGJlIGNvbWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRpYWwgdm9sdGFnZSwg
d2hpY2ggaXMgdHlwaWNhbGx5IHVzZWQgdG8KPiArbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBz
ZXJpZXMgcmVzaXN0b3IsIG9yIGEgdGVtcGVyYXR1cmUuCj4gKwo+ICtUaGlzIGRyaXZlciBjdXJy
ZW50bHkgdXNlcyB0aGUgMnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4gSW4gb3JkZXIgdG8gc3Vw
cG9ydAo+ICtvdGhlciBtb2RlcywgdGhlIGRyaXZlciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQu
Cj4gKwo+ICsKPiArVXNhZ2UgTm90ZXMKPiArLS0tLS0tLS0tLS0KPiArCj4gK1RoaXMgZHJpdmVy
IGRvZXMgbm90IHByb2JlIGZvciBQTUJ1cyBkZXZpY2VzLiBZb3Ugd2lsbCBoYXZlIHRvIGluc3Rh
bnRpYXRlCj4gK2RldmljZXMgZXhwbGljaXRseS4KPiArCj4gKwo+ICtTeXNmcyBhdHRyaWJ1dGVz
Cj4gKy0tLS0tLS0tLS0tLS0tLS0KPiArCj4gK1RoZSAiY3VycipfaW5wdXQiIG1lYXN1cmVtZW50
cyBhY3R1YWxseSByZXBvcnQgdGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdGhlCj4gK2lucHV0IHBp
bnMgaW4gbWljcm92b2x0cy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91
Z2ggYSAxbU9obQo+ICtzZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSByZXBvcnRlZCB2YWx1ZSBi
eSB0aGUgYWN0dWFsIHNlbnNlIHJlc2lzdG9yIHZhbHVlCj4gK2luIG1PaG0gdG8gZ2V0IHRoZSBh
Y3R1YWwgdmFsdWUuCj4gKwo+ICtpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNjIHBpbiBpbiBt
aWxsaXZvbHQgKHJhbmdlIDIuNVYgdG8gNVYpCj4gK3RlbXAxX2lucHV0ICAgSW50ZXJuYWwgY2hp
cCB0ZW1wZXJhdHVyZSBpbiBtaWxsaWRlZ3JlZXMgQ2VsY2l1cwo+ICtjdXJyMV9pbnB1dCAgIEN1
cnJlbnQgaW4gbUEgYWNyb3NzIHYxLXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3Iu
Cj4gK2N1cnIyX2lucHV0ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcgYSAx
bU9obSBzZW5zZSByZXNpc3Rvci4KPiArCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2Nv
bmZpZyBiL2RyaXZlcnMvaHdtb24vS2NvbmZpZwo+IGluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAw
NjQ0Cj4gLS0tIGEvZHJpdmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9od21vbi9L
Y29uZmlnCj4gQEAgLTY4NSw2ICs2ODUsMjAgQEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQo+ICAJ
ICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBt
b2R1bGUgd2lsbAo+ICAJICBiZSBjYWxsZWQgbHRjMjk0NS4KPiAgCj4gK2NvbmZpZyBTRU5TT1JT
X0xUQzI5OTAKPiArCXRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50
IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPiArCWRlcGVuZHMgb24gSTJDCj4gKwloZWxwCj4gKwkg
IElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5lYXIgVGVjaG5vbG9n
eSBMVEMyOTkwCj4gKwkgIEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMg
YSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLAo+ICsJICBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZSBt
b25pdG9yaW5nLCBidXQgaW4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkKPiArCSAgdm9sdGFn
ZSBhbmQgY2hpcCB0ZW1wZXJhdHVyZSwgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9y
dHMKPiArCSAgcmVhZGluZyB0d28gY3VycmVudHMgYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRp
YWwgdm9sdGFnZXMgYWNyb3NzCj4gKwkgIHNlcmllcyByZXNpc3RvcnMuCj4gKwo+ICsJICBUaGlz
IGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUg
d2lsbAo+ICsJICBiZSBjYWxsZWQgbHRjMjk5MC4KPiArCj4gIGNvbmZpZyBTRU5TT1JTX0xUQzQx
NTEKPiAgCXRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEM0MTUxIgo+ICAJZGVwZW5kcyBv
biBJMkMKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdt
b24vTWFrZWZpbGUKPiBpbmRleCAxMmEzMjM5Li5lNGJkMTViIDEwMDY0NAo+IC0tLSBhL2RyaXZl
cnMvaHdtb24vTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4gQEAgLTEw
MSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjM0KQkrPSBsbTk1MjM0Lm8K
PiAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTE05NTI0MSkJKz0gbG05NTI0MS5vCj4gIG9iai0kKENP
TkZJR19TRU5TT1JTX0xNOTUyNDUpCSs9IGxtOTUyNDUubwo+ICBvYmotJChDT05GSUdfU0VOU09S
U19MVEMyOTQ1KQkrPSBsdGMyOTQ1Lm8KPiArb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk5MCkJ
Kz0gbHRjMjk5MC5vCj4gIG9iai0kKENPTkZJR19TRU5TT1JTX0xUQzQxNTEpCSs9IGx0YzQxNTEu
bwo+ICBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MjE1KQkrPSBsdGM0MjE1Lm8KPiAgb2JqLSQo
Q09ORklHX1NFTlNPUlNfTFRDNDIyMikJKz0gbHRjNDIyMi5vCj4gZGlmZiAtLWdpdCBhL2RyaXZl
cnMvaHdtb24vbHRjMjk5MC5jIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPiBuZXcgZmlsZSBt
b2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjM3Y2E1ZjQKPiAtLS0gL2Rldi9udWxsCj4gKysr
IGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPiBAQCAtMCwwICsxLDE1OSBAQAo+ICsvKgo+ICsg
KiBEcml2ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgo+ICsg
Kgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMKPiArICog
QXV0aG9yOiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKyAqCj4g
KyAqIExpY2Vuc2U6IEdQTHYyCj4gKyAqCj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNo
aXAgaXMgd2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4gKyAqIHJlcG9ydHMg
dGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0IGFsc28gcmVw
b3J0cwo+ICsgKiB0aGUgY2hpcCdzIGludGVybmFsIHRlbXBlcmF0dXJlIGFuZCBWY2MgcG93ZXIg
c3VwcGx5IHZvbHRhZ2UuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsj
aW5jbHVkZSA8bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+
Cj4gKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+
ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVT
CTB4MDAKPiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQo+ICsjZGVmaW5lIExUQzI5OTBf
VFJJR0dFUgkweDAyCj4gKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0Cj4gKyNkZWZpbmUg
TFRDMjk5MF9WMV9NU0IJMHgwNgo+ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCCTB4MDgKPiArI2Rl
ZmluZSBMVEMyOTkwX1YzX01TQgkweDBBCj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IJMHgwQwo+
ICsjZGVmaW5lIExUQzI5OTBfVkNDX01TQgkweDBFCj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfQ09O
VFJPTF9LRUxWSU4JCUJJVCg3KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9TSU5HTEUJCUJJ
VCg2KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCj4g
KyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkweDA2Cj4gKyNkZWZpbmUgTFRD
Mjk5MF9DT05UUk9MX01PREVfVk9MVEFHRQkweDA3Cj4gKwo+ICsvKiBjb252ZXJ0IHJhdyByZWdp
c3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0IHJhbmdlICovCj4g
K3N0YXRpYyBpbnQgbHRjMjk5MF92b2x0YWdlX3RvX2ludChpbnQgcmF3KQo+ICt7Cj4gKwlpZiAo
cmF3ICYgQklUKDE0KSkgewo+ICsJCXJldHVybiAtKDB4NDAwMCAtIChyYXcgJiAweDNGRkYpKSA8
PCAyOwo+ICsJfSBlbHNlIHsKPiArCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPiArCX0K
ClVubmVjZXNzYXJ5IHsgfS4gUGxlYXNlIHNlZSBjaGVja3BhdGNoIHdhcm5pbmcuCgo+ICt9Cj4g
Kwo+ICsvKiBSZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBmcm9tIHRoZSBnaXZlbiByZWdpc3Rl
ciBpbiB1ViBvciBtQyAqLwo+ICtzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBp
MmNfY2xpZW50ICppMmMsIHU4IHJlZykKPiArewo+ICsJaW50IHZhbDsKPiArCWludCByZXN1bHQ7
Cj4gKwo+ICsJdmFsID0gaTJjX3NtYnVzX3JlYWRfd29yZF9zd2FwcGVkKGkyYywgcmVnKTsKPiAr
CWlmICh1bmxpa2VseSh2YWwgPCAwKSkKPiArCQlyZXR1cm4gdmFsOwoKVGhpcyBzdWdnZXN0cyB0
aGUgZnVuY3Rpb24gcmV0dXJucyBhIHZhbHVlIDwgMCBvbiBlcnJvciAuLi4KCj4gKwlzd2l0Y2gg
KHJlZykgewo+ICsJY2FzZSBMVEMyOTkwX1RJTlRfTVNCOgo+ICsJCS8qIGludGVybmFsIHRlbXAs
IDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0ICAqLwo+ICsJCXZhbCA9ICh2YWwgJiAweDFGRkYp
IDw8IDM7Cj4gKwkJcmVzdWx0ID0gKHZhbCAqIDEwMDApID4+IDc7Cj4gKwkJYnJlYWs7Cj4gKwlj
YXNlIExUQzI5OTBfVjFfTVNCOgo+ICsJY2FzZSBMVEMyOTkwX1YzX01TQjoKPiArCQkgLyogVngt
VnksIDE5LjQydVYvTFNCLiBEZXBlbmRzIG9uIG1vZGUuICovCj4gKwkJcmVzdWx0ID0gbHRjMjk5
MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPiArCQlicmVhazsKPiAr
CWNhc2UgTFRDMjk5MF9WQ0NfTVNCOgo+ICsJCS8qIFZjYywgMzA1LjE4zrxWL0xTQiwgMi41ViBv
ZmZzZXQgKi8KPiArCQlyZXN1bHQgPSBsdGMyOTkwX3ZvbHRhZ2VfdG9faW50KHZhbCkgKiAzMDUx
OCAvICg0ICogMTAwICogMTAwMCk7Cj4gKwkJcmVzdWx0ICs9IDI1MDA7Cj4gKwkJYnJlYWs7Cj4g
KwlkZWZhdWx0Ogo+ICsJCXJlc3VsdCA9IDA7IC8qIHdvbid0IGhhcHBlbiwga2VlcCBjb21waWxl
ciBoYXBweSAqLwoKR2l2ZW4gdGhhdCwgd2UgY2FuIHJldHVybiBzb21lIGVycm9yIGhlcmUsIGFu
ZCAuLi4KCj4gKwkJYnJlYWs7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsK
PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVlKHN0cnVjdCBkZXZpY2UgKmRldiwK
PiArCQkJCSAgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmRhLCBjaGFyICpidWYpCj4gK3sKPiAr
CXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0
cihkYSk7Cj4gKwlpbnQgdmFsdWU7Cj4gKwo+ICsJdmFsdWUgPSBsdGMyOTkwX2dldF92YWx1ZShk
ZXZfZ2V0X2RydmRhdGEoZGV2KSwgYXR0ci0+aW5kZXgpOwoKLi4uIHdlIHNob3VsZCBhY3R1YWxs
eSBjaGVjayB0aGUgZXJyb3IgcmV0dXJuIGhlcmUuCgoJaWYgKHZhbHVlIDwgMCkKCQlyZXR1cm4g
dmFsdWU7Cgo+ICsJcmV0dXJuIHNucHJpbnRmKGJ1ZiwgUEFHRV9TSVpFLCAiJWRcbiIsIHZhbHVl
KTsKPiArfQo+ICsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih0ZW1wMV9pbnB1dCwgU19J
UlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVElOVF9NU0Ip
Owo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBsdGMy
OTkwX3Nob3dfdmFsdWUsIE5VTEwsCj4gKwkJCSAgTFRDMjk5MF9WMV9NU0IpOwo+ICtzdGF0aWMg
U0VOU09SX0RFVklDRV9BVFRSKGN1cnIyX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFs
dWUsIE5VTEwsCj4gKwkJCSAgTFRDMjk5MF9WM19NU0IpOwo+ICtzdGF0aWMgU0VOU09SX0RFVklD
RV9BVFRSKGluMF9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJ
CQkgIExUQzI5OTBfVkNDX01TQik7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqbHRj
Mjk5MF9hdHRyc1tdID0gewo+ICsJJnNlbnNvcl9kZXZfYXR0cl90ZW1wMV9pbnB1dC5kZXZfYXR0
ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+
ICsJJnNlbnNvcl9kZXZfYXR0cl9jdXJyMl9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNv
cl9kZXZfYXR0cl9pbjBfaW5wdXQuZGV2X2F0dHIuYXR0ciwKPiArCU5VTEwsCj4gK307Cj4gK0FU
VFJJQlVURV9HUk9VUFMobHRjMjk5MCk7Cj4gKwo+ICtzdGF0aWMgaW50IGx0YzI5OTBfaTJjX3By
b2JlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsCj4gKwkJCSAgICAgY29uc3Qgc3RydWN0IGkyY19k
ZXZpY2VfaWQgKmlkKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsJc3RydWN0IGRldmljZSAqaHdtb25f
ZGV2Owo+ICsKPiArCWlmICghaTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoaTJjLT5hZGFwdGVyLCBJ
MkNfRlVOQ19TTUJVU19CWVRFX0RBVEEgfAo+ICsJCQkJICAgICBJMkNfRlVOQ19TTUJVU19XT1JE
X0RBVEEpKQo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsKPiArCS8qIFNldHVwIGNvbnRpbnVvdXMg
bW9kZSwgY3VycmVudCBtb25pdG9yICovCj4gKwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9k
YXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+ICsJCQkJCUxUQzI5OTBfQ09OVFJPTF9NRUFTVVJF
X0FMTCB8Cj4gKwkJCQkJTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVCk7Cj4gKwlpZiAocmV0
IDwgMCkgewo+ICsJCWRldl9lcnIoJmkyYy0+ZGV2LCAiRXJyb3I6IEZhaWxlZCB0byBzZXQgY29u
dHJvbCBtb2RlLlxuIik7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCS8qIFRyaWdnZXIgb25j
ZSB0byBzdGFydCBjb250aW51b3VzIGNvbnZlcnNpb24gKi8KPiArCXJldCA9IGkyY19zbWJ1c193
cml0ZV9ieXRlX2RhdGEoaTJjLCBMVEMyOTkwX1RSSUdHRVIsIDEpOwo+ICsJaWYgKHJldCA8IDAp
IHsKPiArCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWlsZWQgdG8gc3RhcnQgYWNxdWlz
aXRpb24uXG4iKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWh3bW9uX2RldiA9IGRl
dm1faHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKCZpMmMtPmRldiwKPiArCQkJCQkJ
CSAgIGkyYy0+bmFtZSwKPiArCQkJCQkJCSAgIGkyYywKPiArCQkJCQkJCSAgIGx0YzI5OTBfZ3Jv
dXBzKTsKPiArCj4gKwlyZXR1cm4gUFRSX0VSUl9PUl9aRVJPKGh3bW9uX2Rldik7Cj4gK30KPiAr
Cj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCBsdGMyOTkwX2kyY19pZFtdID0g
ewo+ICsJeyAibHRjMjk5MCIsIDAgfSwKPiArCXt9Cj4gK307Cj4gK01PRFVMRV9ERVZJQ0VfVEFC
TEUoaTJjLCBsdGMyOTkwX2kyY19pZCk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIg
bHRjMjk5MF9pMmNfZHJpdmVyID0gewo+ICsJLmRyaXZlciA9IHsKPiArCQkubmFtZSA9ICJsdGMy
OTkwIiwKPiArCX0sCj4gKwkucHJvYmUgICAgPSBsdGMyOTkwX2kyY19wcm9iZSwKPiArCS5pZF90
YWJsZSA9IGx0YzI5OTBfaTJjX2lkLAo+ICt9Owo+ICsKPiArbW9kdWxlX2kyY19kcml2ZXIobHRj
Mjk5MF9pMmNfZHJpdmVyKTsKPiArCj4gK01PRFVMRV9ERVNDUklQVElPTigiTFRDMjk5MCBTZW5z
b3IgRHJpdmVyIik7Cj4gK01PRFVMRV9BVVRIT1IoIlRvcGljIEVtYmVkZGVkIFByb2R1Y3RzIik7
Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPiAtLSAKPiAxLjkuMQo+IAoKX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5n
IGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5v
cmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz

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

* Re: [PATCH v3] hwmon: Add LTC2990 sensor driver
  2016-01-14 19:14       ` [lm-sensors] " Guenter Roeck
@ 2016-01-15  9:54         ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-15  9:54 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: lm-sensors, jdelvare, linux-kernel

On 14-01-16 20:14, Guenter Roeck wrote:
> On Wed, Jan 13, 2016 at 03:45:01PM +0100, Mike Looijmans wrote:
>> This adds support for the Linear Technology LTC2990  I2C System Monitor.
>> The LTC2990 supports a combination of voltage, current and temperature
>> monitoring. This driver currently only supports reading two currents
>> by measuring two differential voltages across series resistors, in
>> addition to the Vcc supply voltage and internal temperature.
>>
>> This is sufficient to support the Topic Miami SOM which uses this chip
>> to monitor the currents flowing into the FPGA and the CPU parts.
>>
>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>
> Hi Mike,
>
> almost there. Please see inline.

Great, I'll order some cake :)

Expect v4 in a few minutes, I'm testing it on the hardware now.

> Thanks,
> Guenter
>
>> ---
>> v3: Remove unused includes.
>>      Remove (most) unused register defines.
>>      Also check on SMBUS WORD capability.
>>      Use register defines as value indices.
>>      Alignment fixups with "(".
>> v2: Processed all review comments.
>>       Put chip into continuous measurement mode.
>>       Added ducumentation.
>>       Use standard hwmon interfaces and macros.
>>
>>   Documentation/hwmon/ltc2990 |  44 ++++++++++++
>>   drivers/hwmon/Kconfig       |  14 ++++
>>   drivers/hwmon/Makefile      |   1 +
>>   drivers/hwmon/ltc2990.c     | 159 ++++++++++++++++++++++++++++++++++++++++++++
>>   4 files changed, 218 insertions(+)
>>   create mode 100644 Documentation/hwmon/ltc2990
>>   create mode 100644 drivers/hwmon/ltc2990.c
>>
>> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
>> new file mode 100644
>> index 0000000..838b74e
>> --- /dev/null
>> +++ b/Documentation/hwmon/ltc2990
>> @@ -0,0 +1,44 @@
>> +Kernel driver ltc2990
>> +=====================
>> +
>> +Supported chips:
>> +  * Linear Technology LTC2990
>> +    Prefix: 'ltc2990'
>> +    Addresses scanned: -
>> +    Datasheet: http://www.linear.com/product/ltc2990
>> +
>> +Author: Mike Looijmans <mike.looijmans@topic.nl>
>> +
>> +
>> +Description
>> +-----------
>> +
>> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
>> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
>> +can be combined to measure a differential voltage, which is typically used to
>> +measure current through a series resistor, or a temperature.
>> +
>> +This driver currently uses the 2x differential mode only. In order to support
>> +other modes, the driver will need to be expanded.
>> +
>> +
>> +Usage Notes
>> +-----------
>> +
>> +This driver does not probe for PMBus devices. You will have to instantiate
>> +devices explicitly.
>> +
>> +
>> +Sysfs attributes
>> +----------------
>> +
>> +The "curr*_input" measurements actually report the voltage drop across the
>> +input pins in microvolts. This is equivalent to the current through a 1mOhm
>> +sense resistor. Divide the reported value by the actual sense resistor value
>> +in mOhm to get the actual value.
>> +
>> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
>> +temp1_input   Internal chip temperature in millidegrees Celcius
>> +curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
>> +curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
>> +
>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
>> index 80a73bf..8a31d64 100644
>> --- a/drivers/hwmon/Kconfig
>> +++ b/drivers/hwmon/Kconfig
>> @@ -685,6 +685,20 @@ config SENSORS_LTC2945
>>   	  This driver can also be built as a module. If so, the module will
>>   	  be called ltc2945.
>>
>> +config SENSORS_LTC2990
>> +	tristate "Linear Technology LTC2990 (current monitoring mode only)"
>> +	depends on I2C
>> +	help
>> +	  If you say yes here you get support for Linear Technology LTC2990
>> +	  I2C System Monitor. The LTC2990 supports a combination of voltage,
>> +	  current and temperature monitoring, but in addition to the Vcc supply
>> +	  voltage and chip temperature, this driver currently only supports
>> +	  reading two currents by measuring two differential voltages across
>> +	  series resistors.
>> +
>> +	  This driver can also be built as a module. If so, the module will
>> +	  be called ltc2990.
>> +
>>   config SENSORS_LTC4151
>>   	tristate "Linear Technology LTC4151"
>>   	depends on I2C
>> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
>> index 12a3239..e4bd15b 100644
>> --- a/drivers/hwmon/Makefile
>> +++ b/drivers/hwmon/Makefile
>> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
>>   obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
>>   obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
>>   obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
>> +obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
>>   obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
>>   obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
>>   obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>> new file mode 100644
>> index 0000000..37ca5f4
>> --- /dev/null
>> +++ b/drivers/hwmon/ltc2990.c
>> @@ -0,0 +1,159 @@
>> +/*
>> + * Driver for Linear Technology LTC2990 power monitor
>> + *
>> + * Copyright (C) 2014 Topic Embedded Products
>> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
>> + *
>> + * License: GPLv2
>> + *
>> + * This driver assumes the chip is wired as a dual current monitor, and
>> + * reports the voltage drop across two series resistors. It also reports
>> + * the chip's internal temperature and Vcc power supply voltage.
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/hwmon.h>
>> +#include <linux/hwmon-sysfs.h>
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +
>> +#define LTC2990_STATUS	0x00
>> +#define LTC2990_CONTROL	0x01
>> +#define LTC2990_TRIGGER	0x02
>> +#define LTC2990_TINT_MSB	0x04
>> +#define LTC2990_V1_MSB	0x06
>> +#define LTC2990_V2_MSB	0x08
>> +#define LTC2990_V3_MSB	0x0A
>> +#define LTC2990_V4_MSB	0x0C
>> +#define LTC2990_VCC_MSB	0x0E
>> +
>> +#define LTC2990_CONTROL_KELVIN		BIT(7)
>> +#define LTC2990_CONTROL_SINGLE		BIT(6)
>> +#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
>> +#define LTC2990_CONTROL_MODE_CURRENT	0x06
>> +#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
>> +
>> +/* convert raw register value to sign-extended integer in 16-bit range */
>> +static int ltc2990_voltage_to_int(int raw)
>> +{
>> +	if (raw & BIT(14)) {
>> +		return -(0x4000 - (raw & 0x3FFF)) << 2;
>> +	} else {
>> +		return (raw & 0x3FFF) << 2;
>> +	}
>
> Unnecessary { }. Please see checkpatch warning.

I'll make sure to run checkpatch again. Its only remaining warning is about 
MAINTAINERS now.

>> +}
>> +
>> +/* Return the converted value from the given register in uV or mC */
>> +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg)
>> +{
>> +	int val;
>> +	int result;
>> +
>> +	val = i2c_smbus_read_word_swapped(i2c, reg);
>> +	if (unlikely(val < 0))
>> +		return val;
>
> This suggests the function returns a value < 0 on error ...

Misleading, since most of the valid results can be negative. I'll change the 
method to return a result code and take a result pointer instead.

>
>> +	switch (reg) {
>> +	case LTC2990_TINT_MSB:
>> +		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
>> +		val = (val & 0x1FFF) << 3;
>> +		result = (val * 1000) >> 7;
>> +		break;
>> +	case LTC2990_V1_MSB:
>> +	case LTC2990_V3_MSB:
>> +		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
>> +		result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
>> +		break;
>> +	case LTC2990_VCC_MSB:
>> +		/* Vcc, 305.18μV/LSB, 2.5V offset */
>> +		result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);
>> +		result += 2500;
>> +		break;
>> +	default:
>> +		result = 0; /* won't happen, keep compiler happy */
>
> Given that, we can return some error here, and ...
>
>> +		break;
>> +	}
>> +
>> +	return result;
>> +}
>> +
>> +static ssize_t ltc2990_show_value(struct device *dev,
>> +				  struct device_attribute *da, char *buf)
>> +{
>> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>> +	int value;
>> +
>> +	value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);
>
> ... we should actually check the error return here.
>
> 	if (value < 0)
> 		return value;

Yes, with the change above, it can properly return an error code if the I2C 
transaction failed.

>> +	return snprintf(buf, PAGE_SIZE, "%d\n", value);
>> +}
>> +
>> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
>> +			  LTC2990_TINT_MSB);
>> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
>> +			  LTC2990_V1_MSB);
>> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
>> +			  LTC2990_V3_MSB);
>> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
>> +			  LTC2990_VCC_MSB);
>> +
>> +static struct attribute *ltc2990_attrs[] = {
>> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
>> +	&sensor_dev_attr_curr1_input.dev_attr.attr,
>> +	&sensor_dev_attr_curr2_input.dev_attr.attr,
>> +	&sensor_dev_attr_in0_input.dev_attr.attr,
>> +	NULL,
>> +};
>> +ATTRIBUTE_GROUPS(ltc2990);
>> +
>> +static int ltc2990_i2c_probe(struct i2c_client *i2c,
>> +			     const struct i2c_device_id *id)
>> +{
>> +	int ret;
>> +	struct device *hwmon_dev;
>> +
>> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
>> +				     I2C_FUNC_SMBUS_WORD_DATA))
>> +		return -ENODEV;
>> +
>> +	/* Setup continuous mode, current monitor */
>> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
>> +					LTC2990_CONTROL_MEASURE_ALL |
>> +					LTC2990_CONTROL_MODE_CURRENT);
>> +	if (ret < 0) {
>> +		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
>> +		return ret;
>> +	}
>> +	/* Trigger once to start continuous conversion */
>> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
>> +	if (ret < 0) {
>> +		dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
>> +		return ret;
>> +	}
>> +
>> +	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
>> +							   i2c->name,
>> +							   i2c,
>> +							   ltc2990_groups);
>> +
>> +	return PTR_ERR_OR_ZERO(hwmon_dev);
>> +}
>> +
>> +static const struct i2c_device_id ltc2990_i2c_id[] = {
>> +	{ "ltc2990", 0 },
>> +	{}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
>> +
>> +static struct i2c_driver ltc2990_i2c_driver = {
>> +	.driver = {
>> +		.name = "ltc2990",
>> +	},
>> +	.probe    = ltc2990_i2c_probe,
>> +	.id_table = ltc2990_i2c_id,
>> +};
>> +
>> +module_i2c_driver(ltc2990_i2c_driver);
>> +
>> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
>> +MODULE_AUTHOR("Topic Embedded Products");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.9.1
>>



Kind regards,

Mike Looijmans
System Expert

TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

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

* Re: [lm-sensors] [PATCH v3] hwmon: Add LTC2990 sensor driver
@ 2016-01-15  9:54         ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-15  9:54 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: lm-sensors, jdelvare, linux-kernel

77u/T24gMTQtMDEtMTYgMjA6MTQsIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gV2VkLCBKYW4g
MTMsIDIwMTYgYXQgMDM6NDU6MDFQTSArMDEwMCwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IFRo
aXMgYWRkcyBzdXBwb3J0IGZvciB0aGUgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCAgSTJDIFN5
c3RlbSBNb25pdG9yLgo+PiBUaGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNvbWJpbmF0aW9uIG9mIHZv
bHRhZ2UsIGN1cnJlbnQgYW5kIHRlbXBlcmF0dXJlCj4+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVy
IGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4+IGJ5IG1lYXN1
cmluZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcyBzZXJpZXMgcmVzaXN0b3JzLCBp
bgo+PiBhZGRpdGlvbiB0byB0aGUgVmNjIHN1cHBseSB2b2x0YWdlIGFuZCBpbnRlcm5hbCB0ZW1w
ZXJhdHVyZS4KPj4KPj4gVGhpcyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1p
YW1pIFNPTSB3aGljaCB1c2VzIHRoaXMgY2hpcAo+PiB0byBtb25pdG9yIHRoZSBjdXJyZW50cyBm
bG93aW5nIGludG8gdGhlIEZQR0EgYW5kIHRoZSBDUFUgcGFydHMuCj4+Cj4+IFNpZ25lZC1vZmYt
Ynk6IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPgo+IEhpIE1pa2Us
Cj4KPiBhbG1vc3QgdGhlcmUuIFBsZWFzZSBzZWUgaW5saW5lLgoKR3JlYXQsIEknbGwgb3JkZXIg
c29tZSBjYWtlIDopCgpFeHBlY3QgdjQgaW4gYSBmZXcgbWludXRlcywgSSdtIHRlc3RpbmcgaXQg
b24gdGhlIGhhcmR3YXJlIG5vdy4KCj4gVGhhbmtzLAo+IEd1ZW50ZXIKPgo+PiAtLS0KPj4gdjM6
IFJlbW92ZSB1bnVzZWQgaW5jbHVkZXMuCj4+ICAgICAgUmVtb3ZlIChtb3N0KSB1bnVzZWQgcmVn
aXN0ZXIgZGVmaW5lcy4KPj4gICAgICBBbHNvIGNoZWNrIG9uIFNNQlVTIFdPUkQgY2FwYWJpbGl0
eS4KPj4gICAgICBVc2UgcmVnaXN0ZXIgZGVmaW5lcyBhcyB2YWx1ZSBpbmRpY2VzLgo+PiAgICAg
IEFsaWdubWVudCBmaXh1cHMgd2l0aCAiKCIuCj4+IHYyOiBQcm9jZXNzZWQgYWxsIHJldmlldyBj
b21tZW50cy4KPj4gICAgICAgUHV0IGNoaXAgaW50byBjb250aW51b3VzIG1lYXN1cmVtZW50IG1v
ZGUuCj4+ICAgICAgIEFkZGVkIGR1Y3VtZW50YXRpb24uCj4+ICAgICAgIFVzZSBzdGFuZGFyZCBo
d21vbiBpbnRlcmZhY2VzIGFuZCBtYWNyb3MuCj4+Cj4+ICAgRG9jdW1lbnRhdGlvbi9od21vbi9s
dGMyOTkwIHwgIDQ0ICsrKysrKysrKysrKwo+PiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAg
ICB8ICAxNCArKysrCj4+ICAgZHJpdmVycy9od21vbi9NYWtlZmlsZSAgICAgIHwgICAxICsKPj4g
ICBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYyAgICAgfCAxNTkgKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysKPj4gICA0IGZpbGVzIGNoYW5nZWQsIDIxOCBpbnNlcnRp
b25zKCspCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5
MAo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+Pgo+PiBk
aWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIGIvRG9jdW1lbnRhdGlvbi9o
d21vbi9sdGMyOTkwCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjgz
OGI3NGUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5
OTAKPj4gQEAgLTAsMCArMSw0NCBAQAo+PiArS2VybmVsIGRyaXZlciBsdGMyOTkwCj4+ICs9PT09
PT09PT09PT09PT09PT09PT0KPj4gKwo+PiArU3VwcG9ydGVkIGNoaXBzOgo+PiArICAqIExpbmVh
ciBUZWNobm9sb2d5IExUQzI5OTAKPj4gKyAgICBQcmVmaXg6ICdsdGMyOTkwJwo+PiArICAgIEFk
ZHJlc3NlcyBzY2FubmVkOiAtCj4+ICsgICAgRGF0YXNoZWV0OiBodHRwOi8vd3d3LmxpbmVhci5j
b20vcHJvZHVjdC9sdGMyOTkwCj4+ICsKPj4gK0F1dGhvcjogTWlrZSBMb29pam1hbnMgPG1pa2Uu
bG9vaWptYW5zQHRvcGljLm5sPgo+PiArCj4+ICsKPj4gK0Rlc2NyaXB0aW9uCj4+ICstLS0tLS0t
LS0tLQo+PiArCj4+ICtMVEMyOTkwIGlzIGEgUXVhZCBJMkMgVm9sdGFnZSwgQ3VycmVudCBhbmQg
VGVtcGVyYXR1cmUgTW9uaXRvci4KPj4gK1RoZSBjaGlwJ3MgaW5wdXRzIGNhbiBtZWFzdXJlIDQg
dm9sdGFnZXMsIG9yIHR3byBpbnB1dHMgdG9nZXRoZXIgKDErMiBhbmQgMys0KQo+PiArY2FuIGJl
IGNvbWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRpYWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlw
aWNhbGx5IHVzZWQgdG8KPj4gK21lYXN1cmUgY3VycmVudCB0aHJvdWdoIGEgc2VyaWVzIHJlc2lz
dG9yLCBvciBhIHRlbXBlcmF0dXJlLgo+PiArCj4+ICtUaGlzIGRyaXZlciBjdXJyZW50bHkgdXNl
cyB0aGUgMnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4gSW4gb3JkZXIgdG8gc3VwcG9ydAo+PiAr
b3RoZXIgbW9kZXMsIHRoZSBkcml2ZXIgd2lsbCBuZWVkIHRvIGJlIGV4cGFuZGVkLgo+PiArCj4+
ICsKPj4gK1VzYWdlIE5vdGVzCj4+ICstLS0tLS0tLS0tLQo+PiArCj4+ICtUaGlzIGRyaXZlciBk
b2VzIG5vdCBwcm9iZSBmb3IgUE1CdXMgZGV2aWNlcy4gWW91IHdpbGwgaGF2ZSB0byBpbnN0YW50
aWF0ZQo+PiArZGV2aWNlcyBleHBsaWNpdGx5Lgo+PiArCj4+ICsKPj4gK1N5c2ZzIGF0dHJpYnV0
ZXMKPj4gKy0tLS0tLS0tLS0tLS0tLS0KPj4gKwo+PiArVGhlICJjdXJyKl9pbnB1dCIgbWVhc3Vy
ZW1lbnRzIGFjdHVhbGx5IHJlcG9ydCB0aGUgdm9sdGFnZSBkcm9wIGFjcm9zcyB0aGUKPj4gK2lu
cHV0IHBpbnMgaW4gbWljcm92b2x0cy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBjdXJyZW50
IHRocm91Z2ggYSAxbU9obQo+PiArc2Vuc2UgcmVzaXN0b3IuIERpdmlkZSB0aGUgcmVwb3J0ZWQg
dmFsdWUgYnkgdGhlIGFjdHVhbCBzZW5zZSByZXNpc3RvciB2YWx1ZQo+PiAraW4gbU9obSB0byBn
ZXQgdGhlIGFjdHVhbCB2YWx1ZS4KPj4gKwo+PiAraW4wX2lucHV0ICAgICBWb2x0YWdlIGF0IFZj
YyBwaW4gaW4gbWlsbGl2b2x0IChyYW5nZSAyLjVWIHRvIDVWKQo+PiArdGVtcDFfaW5wdXQgICBJ
bnRlcm5hbCBjaGlwIHRlbXBlcmF0dXJlIGluIG1pbGxpZGVncmVlcyBDZWxjaXVzCj4+ICtjdXJy
MV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNyb3NzIHYxLXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vu
c2UgcmVzaXN0b3IuCj4+ICtjdXJyMl9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNyb3NzIHYzLXY0
IGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4+ICsKPj4gZGlmZiAtLWdpdCBhL2Ry
aXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdtb24vS2NvbmZpZwo+PiBpbmRleCA4MGE3
M2JmLi44YTMxZDY0IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2h3bW9uL0tjb25maWcKPj4gKysr
IGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02ODUsNiArNjg1LDIwIEBAIGNvbmZpZyBT
RU5TT1JTX0xUQzI5NDUKPj4gICAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBh
IG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2lsbAo+PiAgIAkgIGJlIGNhbGxlZCBsdGMyOTQ1
Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRDMjk5MAo+PiArCXRyaXN0YXRlICJMaW5lYXIgVGVj
aG5vbG9neSBMVEMyOTkwIChjdXJyZW50IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKwlkZXBl
bmRzIG9uIEkyQwo+PiArCWhlbHAKPj4gKwkgIElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IGdldCBz
dXBwb3J0IGZvciBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4+ICsJICBJMkMgU3lzdGVtIE1v
bml0b3IuIFRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9sdGFnZSwKPj4g
KwkgIGN1cnJlbnQgYW5kIHRlbXBlcmF0dXJlIG1vbml0b3JpbmcsIGJ1dCBpbiBhZGRpdGlvbiB0
byB0aGUgVmNjIHN1cHBseQo+PiArCSAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1wZXJhdHVyZSwgdGhp
cyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPj4gKwkgIHJlYWRpbmcgdHdvIGN1cnJl
bnRzIGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcwo+PiArCSAg
c2VyaWVzIHJlc2lzdG9ycy4KPj4gKwo+PiArCSAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUgYnVp
bHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPj4gKwkgIGJlIGNhbGxlZCBs
dGMyOTkwLgo+PiArCj4+ICAgY29uZmlnIFNFTlNPUlNfTFRDNDE1MQo+PiAgIAl0cmlzdGF0ZSAi
TGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKPj4gICAJZGVwZW5kcyBvbiBJMkMKPj4gZGlmZiAt
LWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4+
IGluZGV4IDEyYTMyMzkuLmU0YmQxNWIgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZlcnMvaHdtb24vTWFr
ZWZpbGUKPj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBAQCAtMTAxLDYgKzEwMSw3
IEBAIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyMzQpCSs9IGxtOTUyMzQubwo+PiAgIG9iai0k
KENPTkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxtOTUyNDEubwo+PiAgIG9iai0kKENPTkZJR19T
RU5TT1JTX0xNOTUyNDUpCSs9IGxtOTUyNDUubwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xU
QzI5NDUpCSs9IGx0YzI5NDUubwo+PiArb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk5MCkJKz0g
bHRjMjk5MC5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDE1MSkJKz0gbHRjNDE1MS5v
Cj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIxNSkJKz0gbHRjNDIxNS5vCj4+ICAgb2Jq
LSQoQ09ORklHX1NFTlNPUlNfTFRDNDIyMikJKz0gbHRjNDIyMi5vCj4+IGRpZmYgLS1naXQgYS9k
cml2ZXJzL2h3bW9uL2x0YzI5OTAuYyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jCj4+IG5ldyBm
aWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjM3Y2E1ZjQKPj4gLS0tIC9kZXYvbnVs
bAo+PiArKysgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwo+PiBAQCAtMCwwICsxLDE1OSBAQAo+
PiArLyoKPj4gKyAqIERyaXZlciBmb3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCBwb3dlciBt
b25pdG9yCj4+ICsgKgo+PiArICogQ29weXJpZ2h0IChDKSAyMDE0IFRvcGljIEVtYmVkZGVkIFBy
b2R1Y3RzCj4+ICsgKiBBdXRob3I6IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3Bp
Yy5ubD4KPj4gKyAqCj4+ICsgKiBMaWNlbnNlOiBHUEx2Mgo+PiArICoKPj4gKyAqIFRoaXMgZHJp
dmVyIGFzc3VtZXMgdGhlIGNoaXAgaXMgd2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwg
YW5kCj4+ICsgKiByZXBvcnRzIHRoZSB2b2x0YWdlIGRyb3AgYWNyb3NzIHR3byBzZXJpZXMgcmVz
aXN0b3JzLiBJdCBhbHNvIHJlcG9ydHMKPj4gKyAqIHRoZSBjaGlwJ3MgaW50ZXJuYWwgdGVtcGVy
YXR1cmUgYW5kIFZjYyBwb3dlciBzdXBwbHkgdm9sdGFnZS4KPj4gKyAqLwo+PiArCj4+ICsjaW5j
bHVkZSA8bGludXgvZXJyLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KPj4gKyNpbmNs
dWRlIDxsaW51eC9od21vbi1zeXNmcy5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgo+PiAr
I2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+
PiArCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTCTB4MDAKPj4gKyNkZWZpbmUgTFRDMjk5MF9D
T05UUk9MCTB4MDEKPj4gKyNkZWZpbmUgTFRDMjk5MF9UUklHR0VSCTB4MDIKPj4gKyNkZWZpbmUg
TFRDMjk5MF9USU5UX01TQgkweDA0Cj4+ICsjZGVmaW5lIExUQzI5OTBfVjFfTVNCCTB4MDYKPj4g
KyNkZWZpbmUgTFRDMjk5MF9WMl9NU0IJMHgwOAo+PiArI2RlZmluZSBMVEMyOTkwX1YzX01TQgkw
eDBBCj4+ICsjZGVmaW5lIExUQzI5OTBfVjRfTVNCCTB4MEMKPj4gKyNkZWZpbmUgTFRDMjk5MF9W
Q0NfTVNCCTB4MEUKPj4gKwo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfS0VMVklOCQlCSVQo
NykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX1NJTkdMRQkJQklUKDYpCj4+ICsjZGVmaW5l
IExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCj4+ICsjZGVmaW5lIExUQzI5
OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQJMHgwNgo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xf
TU9ERV9WT0xUQUdFCTB4MDcKPj4gKwo+PiArLyogY29udmVydCByYXcgcmVnaXN0ZXIgdmFsdWUg
dG8gc2lnbi1leHRlbmRlZCBpbnRlZ2VyIGluIDE2LWJpdCByYW5nZSAqLwo+PiArc3RhdGljIGlu
dCBsdGMyOTkwX3ZvbHRhZ2VfdG9faW50KGludCByYXcpCj4+ICt7Cj4+ICsJaWYgKHJhdyAmIEJJ
VCgxNCkpIHsKPj4gKwkJcmV0dXJuIC0oMHg0MDAwIC0gKHJhdyAmIDB4M0ZGRikpIDw8IDI7Cj4+
ICsJfSBlbHNlIHsKPj4gKwkJcmV0dXJuIChyYXcgJiAweDNGRkYpIDw8IDI7Cj4+ICsJfQo+Cj4g
VW5uZWNlc3NhcnkgeyB9LiBQbGVhc2Ugc2VlIGNoZWNrcGF0Y2ggd2FybmluZy4KCkknbGwgbWFr
ZSBzdXJlIHRvIHJ1biBjaGVja3BhdGNoIGFnYWluLiBJdHMgb25seSByZW1haW5pbmcgd2Fybmlu
ZyBpcyBhYm91dCAKTUFJTlRBSU5FUlMgbm93LgoKPj4gK30KPj4gKwo+PiArLyogUmV0dXJuIHRo
ZSBjb252ZXJ0ZWQgdmFsdWUgZnJvbSB0aGUgZ2l2ZW4gcmVnaXN0ZXIgaW4gdVYgb3IgbUMgKi8K
Pj4gK3N0YXRpYyBpbnQgbHRjMjk5MF9nZXRfdmFsdWUoc3RydWN0IGkyY19jbGllbnQgKmkyYywg
dTggcmVnKQo+PiArewo+PiArCWludCB2YWw7Cj4+ICsJaW50IHJlc3VsdDsKPj4gKwo+PiArCXZh
bCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChpMmMsIHJlZyk7Cj4+ICsJaWYgKHVubGlr
ZWx5KHZhbCA8IDApKQo+PiArCQlyZXR1cm4gdmFsOwo+Cj4gVGhpcyBzdWdnZXN0cyB0aGUgZnVu
Y3Rpb24gcmV0dXJucyBhIHZhbHVlIDwgMCBvbiBlcnJvciAuLi4KCk1pc2xlYWRpbmcsIHNpbmNl
IG1vc3Qgb2YgdGhlIHZhbGlkIHJlc3VsdHMgY2FuIGJlIG5lZ2F0aXZlLiBJJ2xsIGNoYW5nZSB0
aGUgCm1ldGhvZCB0byByZXR1cm4gYSByZXN1bHQgY29kZSBhbmQgdGFrZSBhIHJlc3VsdCBwb2lu
dGVyIGluc3RlYWQuCgo+Cj4+ICsJc3dpdGNoIChyZWcpIHsKPj4gKwljYXNlIExUQzI5OTBfVElO
VF9NU0I6Cj4+ICsJCS8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0
ICAqLwo+PiArCQl2YWwgPSAodmFsICYgMHgxRkZGKSA8PCAzOwo+PiArCQlyZXN1bHQgPSAodmFs
ICogMTAwMCkgPj4gNzsKPj4gKwkJYnJlYWs7Cj4+ICsJY2FzZSBMVEMyOTkwX1YxX01TQjoKPj4g
KwljYXNlIExUQzI5OTBfVjNfTVNCOgo+PiArCQkgLyogVngtVnksIDE5LjQydVYvTFNCLiBEZXBl
bmRzIG9uIG1vZGUuICovCj4+ICsJCXJlc3VsdCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFs
KSAqIDE5NDIgLyAoNCAqIDEwMCk7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgTFRDMjk5MF9WQ0Nf
TVNCOgo+PiArCQkvKiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCj4+ICsJCXJl
c3VsdCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAx
MDAwKTsKPj4gKwkJcmVzdWx0ICs9IDI1MDA7Cj4+ICsJCWJyZWFrOwo+PiArCWRlZmF1bHQ6Cj4+
ICsJCXJlc3VsdCA9IDA7IC8qIHdvbid0IGhhcHBlbiwga2VlcCBjb21waWxlciBoYXBweSAqLwo+
Cj4gR2l2ZW4gdGhhdCwgd2UgY2FuIHJldHVybiBzb21lIGVycm9yIGhlcmUsIGFuZCAuLi4KPgo+
PiArCQlicmVhazsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4gcmVzdWx0Owo+PiArfQo+PiArCj4+
ICtzdGF0aWMgc3NpemVfdCBsdGMyOTkwX3Nob3dfdmFsdWUoc3RydWN0IGRldmljZSAqZGV2LAo+
PiArCQkJCSAgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmRhLCBjaGFyICpidWYpCj4+ICt7Cj4+
ICsJc3RydWN0IHNlbnNvcl9kZXZpY2VfYXR0cmlidXRlICphdHRyID0gdG9fc2Vuc29yX2Rldl9h
dHRyKGRhKTsKPj4gKwlpbnQgdmFsdWU7Cj4+ICsKPj4gKwl2YWx1ZSA9IGx0YzI5OTBfZ2V0X3Zh
bHVlKGRldl9nZXRfZHJ2ZGF0YShkZXYpLCBhdHRyLT5pbmRleCk7Cj4KPiAuLi4gd2Ugc2hvdWxk
IGFjdHVhbGx5IGNoZWNrIHRoZSBlcnJvciByZXR1cm4gaGVyZS4KPgo+IAlpZiAodmFsdWUgPCAw
KQo+IAkJcmV0dXJuIHZhbHVlOwoKWWVzLCB3aXRoIHRoZSBjaGFuZ2UgYWJvdmUsIGl0IGNhbiBw
cm9wZXJseSByZXR1cm4gYW4gZXJyb3IgY29kZSBpZiB0aGUgSTJDIAp0cmFuc2FjdGlvbiBmYWls
ZWQuCgo+PiArCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7
Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfaW5wdXQsIFNf
SVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKPj4gKwkJCSAgTFRDMjk5MF9USU5UX01T
Qik7Cj4+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBs
dGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsCj4+ICsJCQkgIExUQzI5OTBfVjFfTVNCKTsKPj4gK3N0
YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoY3VycjJfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hv
d192YWx1ZSwgTlVMTCwKPj4gKwkJCSAgTFRDMjk5MF9WM19NU0IpOwo+PiArc3RhdGljIFNFTlNP
Ul9ERVZJQ0VfQVRUUihpbjBfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVM
TCwKPj4gKwkJCSAgTFRDMjk5MF9WQ0NfTVNCKTsKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBhdHRy
aWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPj4gKwkmc2Vuc29yX2Rldl9hdHRyX3RlbXAxX2lu
cHV0LmRldl9hdHRyLmF0dHIsCj4+ICsJJnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9pbnB1dC5kZXZf
YXR0ci5hdHRyLAo+PiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQuZGV2X2F0dHIuYXR0
ciwKPj4gKwkmc2Vuc29yX2Rldl9hdHRyX2luMF9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+PiArCU5V
TEwsCj4+ICt9Owo+PiArQVRUUklCVVRFX0dST1VQUyhsdGMyOTkwKTsKPj4gKwo+PiArc3RhdGlj
IGludCBsdGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLAo+PiArCQkJICAg
ICBjb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCAqaWQpCj4+ICt7Cj4+ICsJaW50IHJldDsKPj4g
KwlzdHJ1Y3QgZGV2aWNlICpod21vbl9kZXY7Cj4+ICsKPj4gKwlpZiAoIWkyY19jaGVja19mdW5j
dGlvbmFsaXR5KGkyYy0+YWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwKPj4gKwkJ
CQkgICAgIEkyQ19GVU5DX1NNQlVTX1dPUkRfREFUQSkpCj4+ICsJCXJldHVybiAtRU5PREVWOwo+
PiArCj4+ICsJLyogU2V0dXAgY29udGludW91cyBtb2RlLCBjdXJyZW50IG1vbml0b3IgKi8KPj4g
KwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+
PiArCQkJCQlMVEMyOTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfAo+PiArCQkJCQlMVEMyOTkwX0NP
TlRST0xfTU9ERV9DVVJSRU5UKTsKPj4gKwlpZiAocmV0IDwgMCkgewo+PiArCQlkZXZfZXJyKCZp
MmMtPmRldiwgIkVycm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArCQly
ZXR1cm4gcmV0Owo+PiArCX0KPj4gKwkvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91
cyBjb252ZXJzaW9uICovCj4+ICsJcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShpMmMs
IExUQzI5OTBfVFJJR0dFUiwgMSk7Cj4+ICsJaWYgKHJldCA8IDApIHsKPj4gKwkJZGV2X2Vycigm
aTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRvIHN0YXJ0IGFjcXVpc2l0aW9uLlxuIik7Cj4+ICsJ
CXJldHVybiByZXQ7Cj4+ICsJfQo+PiArCj4+ICsJaHdtb25fZGV2ID0gZGV2bV9od21vbl9kZXZp
Y2VfcmVnaXN0ZXJfd2l0aF9ncm91cHMoJmkyYy0+ZGV2LAo+PiArCQkJCQkJCSAgIGkyYy0+bmFt
ZSwKPj4gKwkJCQkJCQkgICBpMmMsCj4+ICsJCQkJCQkJICAgbHRjMjk5MF9ncm91cHMpOwo+PiAr
Cj4+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9kZXYpOwo+PiArfQo+PiArCj4+ICtz
dGF0aWMgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5MF9pMmNfaWRbXSA9IHsKPj4g
Kwl7ICJsdGMyOTkwIiwgMCB9LAo+PiArCXt9Cj4+ICt9Owo+PiArTU9EVUxFX0RFVklDRV9UQUJM
RShpMmMsIGx0YzI5OTBfaTJjX2lkKTsKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVy
IGx0YzI5OTBfaTJjX2RyaXZlciA9IHsKPj4gKwkuZHJpdmVyID0gewo+PiArCQkubmFtZSA9ICJs
dGMyOTkwIiwKPj4gKwl9LAo+PiArCS5wcm9iZSAgICA9IGx0YzI5OTBfaTJjX3Byb2JlLAo+PiAr
CS5pZF90YWJsZSA9IGx0YzI5OTBfaTJjX2lkLAo+PiArfTsKPj4gKwo+PiArbW9kdWxlX2kyY19k
cml2ZXIobHRjMjk5MF9pMmNfZHJpdmVyKTsKPj4gKwo+PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJM
VEMyOTkwIFNlbnNvciBEcml2ZXIiKTsKPj4gK01PRFVMRV9BVVRIT1IoIlRvcGljIEVtYmVkZGVk
IFByb2R1Y3RzIik7Cj4+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4+IC0tCj4+IDEuOS4x
Cj4+CgoKCktpbmQgcmVnYXJkcywKCk1pa2UgTG9vaWptYW5zClN5c3RlbSBFeHBlcnQKClRPUElD
IEVtYmVkZGVkIFByb2R1Y3RzCkVpbmRob3ZlbnNld2VnIDMyLUMsIE5MLTU2ODMgS0ggQmVzdApQ
b3N0YnVzIDQ0MCwgTkwtNTY4MCBBSyBCZXN0ClRlbGVmb29uOiArMzEgKDApIDQ5OSAzMyA2OSA3
OQpFLW1haWw6IG1pa2UubG9vaWptYW5zQHRvcGljcHJvZHVjdHMuY29tCldlYnNpdGU6IHd3dy50
b3BpY3Byb2R1Y3RzLmNvbQoKUGxlYXNlIGNvbnNpZGVyIHRoZSBlbnZpcm9ubWVudCBiZWZvcmUg
cHJpbnRpbmcgdGhpcyBlLW1haWwKCgoKCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1z
ZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9s
bS1zZW5zb3Jz

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

* [PATCH v4] hwmon: Add LTC2990 sensor driver
  2016-01-13 14:45     ` [lm-sensors] " Mike Looijmans
@ 2016-01-15  9:54       ` Mike Looijmans
  -1 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-15  9:54 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

This adds support for the Linear Technology LTC2990  I2C System Monitor.
The LTC2990 supports a combination of voltage, current and temperature
monitoring. This driver currently only supports reading two currents
by measuring two differential voltages across series resistors, in
addition to the Vcc supply voltage and internal temperature.

This is sufficient to support the Topic Miami SOM which uses this chip
to monitor the currents flowing into the FPGA and the CPU parts.

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
---
v4: Fix checkpatch warnings
    ltc2990_get_value can return error code
v3: Remove unused includes.
    Remove (most) unused register defines.
    Also check on SMBUS WORD capability.
    Use register defines as value indices.
    Alignment fixups with "(".
v2: Processed all review comments.
     Put chip into continuous measurement mode.
     Added ducumentation.
     Use standard hwmon interfaces and macros.
 Documentation/hwmon/ltc2990 |  44 ++++++++++++
 drivers/hwmon/Kconfig       |  14 ++++
 drivers/hwmon/Makefile      |   1 +
 drivers/hwmon/ltc2990.c     | 161 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 220 insertions(+)
 create mode 100644 Documentation/hwmon/ltc2990
 create mode 100644 drivers/hwmon/ltc2990.c

diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
new file mode 100644
index 0000000..838b74e
--- /dev/null
+++ b/Documentation/hwmon/ltc2990
@@ -0,0 +1,44 @@
+Kernel driver ltc2990
+=====================
+
+Supported chips:
+  * Linear Technology LTC2990
+    Prefix: 'ltc2990'
+    Addresses scanned: -
+    Datasheet: http://www.linear.com/product/ltc2990
+
+Author: Mike Looijmans <mike.looijmans@topic.nl>
+
+
+Description
+-----------
+
+LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
+The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
+can be combined to measure a differential voltage, which is typically used to
+measure current through a series resistor, or a temperature.
+
+This driver currently uses the 2x differential mode only. In order to support
+other modes, the driver will need to be expanded.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have to instantiate
+devices explicitly.
+
+
+Sysfs attributes
+----------------
+
+The "curr*_input" measurements actually report the voltage drop across the
+input pins in microvolts. This is equivalent to the current through a 1mOhm
+sense resistor. Divide the reported value by the actual sense resistor value
+in mOhm to get the actual value.
+
+in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
+temp1_input   Internal chip temperature in millidegrees Celcius
+curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
+curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
+
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 80a73bf..8a31d64 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -685,6 +685,20 @@ config SENSORS_LTC2945
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2945.
 
+config SENSORS_LTC2990
+	tristate "Linear Technology LTC2990 (current monitoring mode only)"
+	depends on I2C
+	help
+	  If you say yes here you get support for Linear Technology LTC2990
+	  I2C System Monitor. The LTC2990 supports a combination of voltage,
+	  current and temperature monitoring, but in addition to the Vcc supply
+	  voltage and chip temperature, this driver currently only supports
+	  reading two currents by measuring two differential voltages across
+	  series resistors.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc2990.
+
 config SENSORS_LTC4151
 	tristate "Linear Technology LTC4151"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 12a3239..e4bd15b 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
 obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
 obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
 obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
+obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
 obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
 obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
new file mode 100644
index 0000000..8f8fe05
--- /dev/null
+++ b/drivers/hwmon/ltc2990.c
@@ -0,0 +1,161 @@
+/*
+ * Driver for Linear Technology LTC2990 power monitor
+ *
+ * Copyright (C) 2014 Topic Embedded Products
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * License: GPLv2
+ *
+ * This driver assumes the chip is wired as a dual current monitor, and
+ * reports the voltage drop across two series resistors. It also reports
+ * the chip's internal temperature and Vcc power supply voltage.
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#define LTC2990_STATUS	0x00
+#define LTC2990_CONTROL	0x01
+#define LTC2990_TRIGGER	0x02
+#define LTC2990_TINT_MSB	0x04
+#define LTC2990_V1_MSB	0x06
+#define LTC2990_V2_MSB	0x08
+#define LTC2990_V3_MSB	0x0A
+#define LTC2990_V4_MSB	0x0C
+#define LTC2990_VCC_MSB	0x0E
+
+#define LTC2990_CONTROL_KELVIN		BIT(7)
+#define LTC2990_CONTROL_SINGLE		BIT(6)
+#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
+#define LTC2990_CONTROL_MODE_CURRENT	0x06
+#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
+
+/* convert raw register value to sign-extended integer in 16-bit range */
+static int ltc2990_voltage_to_int(int raw)
+{
+	if (raw & BIT(14))
+		return -(0x4000 - (raw & 0x3FFF)) << 2;
+	else
+		return (raw & 0x3FFF) << 2;
+}
+
+/* Return the converted value from the given register in uV or mC */
+static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result)
+{
+	int val;
+
+	val = i2c_smbus_read_word_swapped(i2c, reg);
+	if (unlikely(val < 0))
+		return val;
+
+	switch (reg) {
+	case LTC2990_TINT_MSB:
+		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
+		val = (val & 0x1FFF) << 3;
+		*result = (val * 1000) >> 7;
+		break;
+	case LTC2990_V1_MSB:
+	case LTC2990_V3_MSB:
+		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
+		*result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
+		break;
+	case LTC2990_VCC_MSB:
+		/* Vcc, 305.18μV/LSB, 2.5V offset */
+		*result = (ltc2990_voltage_to_int(val) * 30518 /
+			   (4 * 100 * 1000)) + 2500;
+		break;
+	default:
+		return -EINVAL; /* won't happen, keep compiler happy */
+	}
+
+	return 0;
+}
+
+static ssize_t ltc2990_show_value(struct device *dev,
+				  struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	int value;
+	int ret;
+
+	ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);
+	if (unlikely(ret < 0))
+		return ret;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_TINT_MSB);
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_V1_MSB);
+static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_V3_MSB);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
+			  LTC2990_VCC_MSB);
+
+static struct attribute *ltc2990_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr2_input.dev_attr.attr,
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(ltc2990);
+
+static int ltc2990_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
+{
+	int ret;
+	struct device *hwmon_dev;
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	/* Setup continuous mode, current monitor */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
+					LTC2990_CONTROL_MEASURE_ALL |
+					LTC2990_CONTROL_MODE_CURRENT);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
+		return ret;
+	}
+	/* Trigger once to start continuous conversion */
+	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
+		return ret;
+	}
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
+							   i2c->name,
+							   i2c,
+							   ltc2990_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id ltc2990_i2c_id[] = {
+	{ "ltc2990", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
+
+static struct i2c_driver ltc2990_i2c_driver = {
+	.driver = {
+		.name = "ltc2990",
+	},
+	.probe    = ltc2990_i2c_probe,
+	.id_table = ltc2990_i2c_id,
+};
+
+module_i2c_driver(ltc2990_i2c_driver);
+
+MODULE_DESCRIPTION("LTC2990 Sensor Driver");
+MODULE_AUTHOR("Topic Embedded Products");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [lm-sensors] [PATCH v4] hwmon: Add LTC2990 sensor driver
@ 2016-01-15  9:54       ` Mike Looijmans
  0 siblings, 0 replies; 29+ messages in thread
From: Mike Looijmans @ 2016-01-15  9:54 UTC (permalink / raw)
  To: linux, lm-sensors; +Cc: jdelvare, linux-kernel, Mike Looijmans

VGhpcyBhZGRzIHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMg
U3lzdGVtIE1vbml0b3IuClRoZSBMVEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9s
dGFnZSwgY3VycmVudCBhbmQgdGVtcGVyYXR1cmUKbW9uaXRvcmluZy4gVGhpcyBkcml2ZXIgY3Vy
cmVudGx5IG9ubHkgc3VwcG9ydHMgcmVhZGluZyB0d28gY3VycmVudHMKYnkgbWVhc3VyaW5nIHR3
byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCmFkZGl0
aW9uIHRvIHRoZSBWY2Mgc3VwcGx5IHZvbHRhZ2UgYW5kIGludGVybmFsIHRlbXBlcmF0dXJlLgoK
VGhpcyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1
c2VzIHRoaXMgY2hpcAp0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ
R0EgYW5kIHRoZSBDUFUgcGFydHMuCgpTaWduZWQtb2ZmLWJ5OiBNaWtlIExvb2lqbWFucyA8bWlr
ZS5sb29pam1hbnNAdG9waWMubmw+Ci0tLQp2NDogRml4IGNoZWNrcGF0Y2ggd2FybmluZ3MKICAg
IGx0YzI5OTBfZ2V0X3ZhbHVlIGNhbiByZXR1cm4gZXJyb3IgY29kZQp2MzogUmVtb3ZlIHVudXNl
ZCBpbmNsdWRlcy4KICAgIFJlbW92ZSAobW9zdCkgdW51c2VkIHJlZ2lzdGVyIGRlZmluZXMuCiAg
ICBBbHNvIGNoZWNrIG9uIFNNQlVTIFdPUkQgY2FwYWJpbGl0eS4KICAgIFVzZSByZWdpc3RlciBk
ZWZpbmVzIGFzIHZhbHVlIGluZGljZXMuCiAgICBBbGlnbm1lbnQgZml4dXBzIHdpdGggIigiLgp2
MjogUHJvY2Vzc2VkIGFsbCByZXZpZXcgY29tbWVudHMuCiAgICAgUHV0IGNoaXAgaW50byBjb250
aW51b3VzIG1lYXN1cmVtZW50IG1vZGUuCiAgICAgQWRkZWQgZHVjdW1lbnRhdGlvbi4KICAgICBV
c2Ugc3RhbmRhcmQgaHdtb24gaW50ZXJmYWNlcyBhbmQgbWFjcm9zLgogRG9jdW1lbnRhdGlvbi9o
d21vbi9sdGMyOTkwIHwgIDQ0ICsrKysrKysrKysrKwogZHJpdmVycy9od21vbi9LY29uZmlnICAg
ICAgIHwgIDE0ICsrKysKIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICB8ICAgMSArCiBkcml2
ZXJzL2h3bW9uL2x0YzI5OTAuYyAgICAgfCAxNjEgKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysKIDQgZmlsZXMgY2hhbmdlZCwgMjIwIGluc2VydGlvbnMoKykKIGNy
ZWF0ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKIGNyZWF0ZSBtb2Rl
IDEwMDY0NCBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwoKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRp
b24vaHdtb24vbHRjMjk5MCBiL0RvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MApuZXcgZmlsZSBt
b2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzhiNzRlCi0tLSAvZGV2L251bGwKKysrIGIvRG9j
dW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCkBAIC0wLDAgKzEsNDQgQEAKK0tlcm5lbCBkcml2ZXIg
bHRjMjk5MAorPT09PT09PT09PT09PT09PT09PT09CisKK1N1cHBvcnRlZCBjaGlwczoKKyAgKiBM
aW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCisgICAgUHJlZml4OiAnbHRjMjk5MCcKKyAgICBBZGRy
ZXNzZXMgc2Nhbm5lZDogLQorICAgIERhdGFzaGVldDogaHR0cDovL3d3dy5saW5lYXIuY29tL3By
b2R1Y3QvbHRjMjk5MAorCitBdXRob3I6IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0
b3BpYy5ubD4KKworCitEZXNjcmlwdGlvbgorLS0tLS0tLS0tLS0KKworTFRDMjk5MCBpcyBhIFF1
YWQgSTJDIFZvbHRhZ2UsIEN1cnJlbnQgYW5kIFRlbXBlcmF0dXJlIE1vbml0b3IuCitUaGUgY2hp
cCdzIGlucHV0cyBjYW4gbWVhc3VyZSA0IHZvbHRhZ2VzLCBvciB0d28gaW5wdXRzIHRvZ2V0aGVy
ICgxKzIgYW5kIDMrNCkKK2NhbiBiZSBjb21iaW5lZCB0byBtZWFzdXJlIGEgZGlmZmVyZW50aWFs
IHZvbHRhZ2UsIHdoaWNoIGlzIHR5cGljYWxseSB1c2VkIHRvCittZWFzdXJlIGN1cnJlbnQgdGhy
b3VnaCBhIHNlcmllcyByZXNpc3Rvciwgb3IgYSB0ZW1wZXJhdHVyZS4KKworVGhpcyBkcml2ZXIg
Y3VycmVudGx5IHVzZXMgdGhlIDJ4IGRpZmZlcmVudGlhbCBtb2RlIG9ubHkuIEluIG9yZGVyIHRv
IHN1cHBvcnQKK290aGVyIG1vZGVzLCB0aGUgZHJpdmVyIHdpbGwgbmVlZCB0byBiZSBleHBhbmRl
ZC4KKworCitVc2FnZSBOb3RlcworLS0tLS0tLS0tLS0KKworVGhpcyBkcml2ZXIgZG9lcyBub3Qg
cHJvYmUgZm9yIFBNQnVzIGRldmljZXMuIFlvdSB3aWxsIGhhdmUgdG8gaW5zdGFudGlhdGUKK2Rl
dmljZXMgZXhwbGljaXRseS4KKworCitTeXNmcyBhdHRyaWJ1dGVzCistLS0tLS0tLS0tLS0tLS0t
CisKK1RoZSAiY3VycipfaW5wdXQiIG1lYXN1cmVtZW50cyBhY3R1YWxseSByZXBvcnQgdGhlIHZv
bHRhZ2UgZHJvcCBhY3Jvc3MgdGhlCitpbnB1dCBwaW5zIGluIG1pY3Jvdm9sdHMuIFRoaXMgaXMg
ZXF1aXZhbGVudCB0byB0aGUgY3VycmVudCB0aHJvdWdoIGEgMW1PaG0KK3NlbnNlIHJlc2lzdG9y
LiBEaXZpZGUgdGhlIHJlcG9ydGVkIHZhbHVlIGJ5IHRoZSBhY3R1YWwgc2Vuc2UgcmVzaXN0b3Ig
dmFsdWUKK2luIG1PaG0gdG8gZ2V0IHRoZSBhY3R1YWwgdmFsdWUuCisKK2luMF9pbnB1dCAgICAg
Vm9sdGFnZSBhdCBWY2MgcGluIGluIG1pbGxpdm9sdCAocmFuZ2UgMi41ViB0byA1VikKK3RlbXAx
X2lucHV0ICAgSW50ZXJuYWwgY2hpcCB0ZW1wZXJhdHVyZSBpbiBtaWxsaWRlZ3JlZXMgQ2VsY2l1
cworY3VycjFfaW5wdXQgICBDdXJyZW50IGluIG1BIGFjcm9zcyB2MS12MiBhc3N1bWluZyBhIDFt
T2htIHNlbnNlIHJlc2lzdG9yLgorY3VycjJfaW5wdXQgICBDdXJyZW50IGluIG1BIGFjcm9zcyB2
My12NCBhc3N1bWluZyBhIDFtT2htIHNlbnNlIHJlc2lzdG9yLgorCmRpZmYgLS1naXQgYS9kcml2
ZXJzL2h3bW9uL0tjb25maWcgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKaW5kZXggODBhNzNiZi4u
OGEzMWQ2NCAxMDA2NDQKLS0tIGEvZHJpdmVycy9od21vbi9LY29uZmlnCisrKyBiL2RyaXZlcnMv
aHdtb24vS2NvbmZpZwpAQCAtNjg1LDYgKzY4NSwyMCBAQCBjb25maWcgU0VOU09SU19MVEMyOTQ1
CiAJICBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRo
ZSBtb2R1bGUgd2lsbAogCSAgYmUgY2FsbGVkIGx0YzI5NDUuCiAKK2NvbmZpZyBTRU5TT1JTX0xU
QzI5OTAKKwl0cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCAoY3VycmVudCBtb25p
dG9yaW5nIG1vZGUgb25seSkiCisJZGVwZW5kcyBvbiBJMkMKKwloZWxwCisJICBJZiB5b3Ugc2F5
IHllcyBoZXJlIHlvdSBnZXQgc3VwcG9ydCBmb3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MAor
CSAgSTJDIFN5c3RlbSBNb25pdG9yLiBUaGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNvbWJpbmF0aW9u
IG9mIHZvbHRhZ2UsCisJICBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZSBtb25pdG9yaW5nLCBidXQg
aW4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkKKwkgIHZvbHRhZ2UgYW5kIGNoaXAgdGVtcGVy
YXR1cmUsIHRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzCisJICByZWFkaW5nIHR3
byBjdXJyZW50cyBieSBtZWFzdXJpbmcgdHdvIGRpZmZlcmVudGlhbCB2b2x0YWdlcyBhY3Jvc3MK
KwkgIHNlcmllcyByZXNpc3RvcnMuCisKKwkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0
IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlIG1vZHVsZSB3aWxsCisJICBiZSBjYWxsZWQgbHRjMjk5
MC4KKwogY29uZmlnIFNFTlNPUlNfTFRDNDE1MQogCXRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9n
eSBMVEM0MTUxIgogCWRlcGVuZHMgb24gSTJDCmRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL01h
a2VmaWxlIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQppbmRleCAxMmEzMjM5Li5lNGJkMTViIDEw
MDY0NAotLS0gYS9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvaHdtb24vTWFr
ZWZpbGUKQEAgLTEwMSw2ICsxMDEsNyBAQCBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjM0KQkr
PSBsbTk1MjM0Lm8KIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxtOTUyNDEubwog
b2JqLSQoQ09ORklHX1NFTlNPUlNfTE05NTI0NSkJKz0gbG05NTI0NS5vCiBvYmotJChDT05GSUdf
U0VOU09SU19MVEMyOTQ1KQkrPSBsdGMyOTQ1Lm8KK29iai0kKENPTkZJR19TRU5TT1JTX0xUQzI5
OTApCSs9IGx0YzI5OTAubwogb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDE1MSkJKz0gbHRjNDE1
MS5vCiBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MjE1KQkrPSBsdGM0MjE1Lm8KIG9iai0kKENP
TkZJR19TRU5TT1JTX0xUQzQyMjIpCSs9IGx0YzQyMjIubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9o
d21vbi9sdGMyOTkwLmMgYi9kcml2ZXJzL2h3bW9uL2x0YzI5OTAuYwpuZXcgZmlsZSBtb2RlIDEw
MDY0NAppbmRleCAwMDAwMDAwLi44ZjhmZTA1Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9o
d21vbi9sdGMyOTkwLmMKQEAgLTAsMCArMSwxNjEgQEAKKy8qCisgKiBEcml2ZXIgZm9yIExpbmVh
ciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgorICoKKyAqIENvcHlyaWdodCAoQykg
MjAxNCBUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cworICogQXV0aG9yOiBNaWtlIExvb2lqbWFucyA8
bWlrZS5sb29pam1hbnNAdG9waWMubmw+CisgKgorICogTGljZW5zZTogR1BMdjIKKyAqCisgKiBU
aGlzIGRyaXZlciBhc3N1bWVzIHRoZSBjaGlwIGlzIHdpcmVkIGFzIGEgZHVhbCBjdXJyZW50IG1v
bml0b3IsIGFuZAorICogcmVwb3J0cyB0aGUgdm9sdGFnZSBkcm9wIGFjcm9zcyB0d28gc2VyaWVz
IHJlc2lzdG9ycy4gSXQgYWxzbyByZXBvcnRzCisgKiB0aGUgY2hpcCdzIGludGVybmFsIHRlbXBl
cmF0dXJlIGFuZCBWY2MgcG93ZXIgc3VwcGx5IHZvbHRhZ2UuCisgKi8KKworI2luY2x1ZGUgPGxp
bnV4L2Vyci5oPgorI2luY2x1ZGUgPGxpbnV4L2h3bW9uLmg+CisjaW5jbHVkZSA8bGludXgvaHdt
b24tc3lzZnMuaD4KKyNpbmNsdWRlIDxsaW51eC9pMmMuaD4KKyNpbmNsdWRlIDxsaW51eC9rZXJu
ZWwuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKworI2RlZmluZSBMVEMyOTkwX1NUQVRV
UwkweDAwCisjZGVmaW5lIExUQzI5OTBfQ09OVFJPTAkweDAxCisjZGVmaW5lIExUQzI5OTBfVFJJ
R0dFUgkweDAyCisjZGVmaW5lIExUQzI5OTBfVElOVF9NU0IJMHgwNAorI2RlZmluZSBMVEMyOTkw
X1YxX01TQgkweDA2CisjZGVmaW5lIExUQzI5OTBfVjJfTVNCCTB4MDgKKyNkZWZpbmUgTFRDMjk5
MF9WM19NU0IJMHgwQQorI2RlZmluZSBMVEMyOTkwX1Y0X01TQgkweDBDCisjZGVmaW5lIExUQzI5
OTBfVkNDX01TQgkweDBFCisKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX0tFTFZJTgkJQklUKDcp
CisjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9TSU5HTEUJCUJJVCg2KQorI2RlZmluZSBMVEMyOTkw
X0NPTlRST0xfTUVBU1VSRV9BTEwJKDB4MyA8PCAzKQorI2RlZmluZSBMVEMyOTkwX0NPTlRST0xf
TU9ERV9DVVJSRU5UCTB4MDYKKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfVk9MVEFHRQkw
eDA3CisKKy8qIGNvbnZlcnQgcmF3IHJlZ2lzdGVyIHZhbHVlIHRvIHNpZ24tZXh0ZW5kZWQgaW50
ZWdlciBpbiAxNi1iaXQgcmFuZ2UgKi8KK3N0YXRpYyBpbnQgbHRjMjk5MF92b2x0YWdlX3RvX2lu
dChpbnQgcmF3KQoreworCWlmIChyYXcgJiBCSVQoMTQpKQorCQlyZXR1cm4gLSgweDQwMDAgLSAo
cmF3ICYgMHgzRkZGKSkgPDwgMjsKKwllbHNlCisJCXJldHVybiAocmF3ICYgMHgzRkZGKSA8PCAy
OworfQorCisvKiBSZXR1cm4gdGhlIGNvbnZlcnRlZCB2YWx1ZSBmcm9tIHRoZSBnaXZlbiByZWdp
c3RlciBpbiB1ViBvciBtQyAqLworc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3Qg
aTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIGludCAqcmVzdWx0KQoreworCWludCB2YWw7CisKKwl2
YWwgPSBpMmNfc21idXNfcmVhZF93b3JkX3N3YXBwZWQoaTJjLCByZWcpOworCWlmICh1bmxpa2Vs
eSh2YWwgPCAwKSkKKwkJcmV0dXJuIHZhbDsKKworCXN3aXRjaCAocmVnKSB7CisJY2FzZSBMVEMy
OTkwX1RJTlRfTVNCOgorCQkvKiBpbnRlcm5hbCB0ZW1wLCAwLjA2MjUgZGVncmVlcy9MU0IsIDEz
LWJpdCAgKi8KKwkJdmFsID0gKHZhbCAmIDB4MUZGRikgPDwgMzsKKwkJKnJlc3VsdCA9ICh2YWwg
KiAxMDAwKSA+PiA3OworCQlicmVhazsKKwljYXNlIExUQzI5OTBfVjFfTVNCOgorCWNhc2UgTFRD
Mjk5MF9WM19NU0I6CisJCSAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IuIERlcGVuZHMgb24gbW9kZS4g
Ki8KKwkJKnJlc3VsdCA9IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDE5NDIgLyAoNCAq
IDEwMCk7CisJCWJyZWFrOworCWNhc2UgTFRDMjk5MF9WQ0NfTVNCOgorCQkvKiBWY2MsIDMwNS4x
OM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCisJCSpyZXN1bHQgPSAobHRjMjk5MF92b2x0YWdlX3Rv
X2ludCh2YWwpICogMzA1MTggLworCQkJICAgKDQgKiAxMDAgKiAxMDAwKSkgKyAyNTAwOworCQli
cmVhazsKKwlkZWZhdWx0OgorCQlyZXR1cm4gLUVJTlZBTDsgLyogd29uJ3QgaGFwcGVuLCBrZWVw
IGNvbXBpbGVyIGhhcHB5ICovCisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBzc2l6ZV90
IGx0YzI5OTBfc2hvd192YWx1ZShzdHJ1Y3QgZGV2aWNlICpkZXYsCisJCQkJICBzdHJ1Y3QgZGV2
aWNlX2F0dHJpYnV0ZSAqZGEsIGNoYXIgKmJ1ZikKK3sKKwlzdHJ1Y3Qgc2Vuc29yX2RldmljZV9h
dHRyaWJ1dGUgKmF0dHIgPSB0b19zZW5zb3JfZGV2X2F0dHIoZGEpOworCWludCB2YWx1ZTsKKwlp
bnQgcmV0OworCisJcmV0ID0gbHRjMjk5MF9nZXRfdmFsdWUoZGV2X2dldF9kcnZkYXRhKGRldiks
IGF0dHItPmluZGV4LCAmdmFsdWUpOworCWlmICh1bmxpa2VseShyZXQgPCAwKSkKKwkJcmV0dXJu
IHJldDsKKworCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7
Cit9CisKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfaW5wdXQsIFNfSVJVR08sIGx0
YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKKwkJCSAgTFRDMjk5MF9USU5UX01TQik7CitzdGF0aWMg
U0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3Nob3dfdmFs
dWUsIE5VTEwsCisJCQkgIExUQzI5OTBfVjFfTVNCKTsKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FU
VFIoY3VycjJfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKKwkJCSAg
TFRDMjk5MF9WM19NU0IpOworc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihpbjBfaW5wdXQsIFNf
SVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKKwkJCSAgTFRDMjk5MF9WQ0NfTVNCKTsK
Kworc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKKwkmc2Vuc29y
X2Rldl9hdHRyX3RlbXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCisJJnNlbnNvcl9kZXZfYXR0cl9j
dXJyMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAorCSZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQu
ZGV2X2F0dHIuYXR0ciwKKwkmc2Vuc29yX2Rldl9hdHRyX2luMF9pbnB1dC5kZXZfYXR0ci5hdHRy
LAorCU5VTEwsCit9OworQVRUUklCVVRFX0dST1VQUyhsdGMyOTkwKTsKKworc3RhdGljIGludCBs
dGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLAorCQkJICAgICBjb25zdCBz
dHJ1Y3QgaTJjX2RldmljZV9pZCAqaWQpCit7CisJaW50IHJldDsKKwlzdHJ1Y3QgZGV2aWNlICpo
d21vbl9kZXY7CisKKwlpZiAoIWkyY19jaGVja19mdW5jdGlvbmFsaXR5KGkyYy0+YWRhcHRlciwg
STJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwKKwkJCQkgICAgIEkyQ19GVU5DX1NNQlVTX1dPUkRf
REFUQSkpCisJCXJldHVybiAtRU5PREVWOworCisJLyogU2V0dXAgY29udGludW91cyBtb2RlLCBj
dXJyZW50IG1vbml0b3IgKi8KKwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywg
TFRDMjk5MF9DT05UUk9MLAorCQkJCQlMVEMyOTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfAorCQkJ
CQlMVEMyOTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZf
ZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwor
CQlyZXR1cm4gcmV0OworCX0KKwkvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBj
b252ZXJzaW9uICovCisJcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShpMmMsIExUQzI5
OTBfVFJJR0dFUiwgMSk7CisJaWYgKHJldCA8IDApIHsKKwkJZGV2X2VycigmaTJjLT5kZXYsICJF
cnJvcjogRmFpbGVkIHRvIHN0YXJ0IGFjcXVpc2l0aW9uLlxuIik7CisJCXJldHVybiByZXQ7CisJ
fQorCisJaHdtb25fZGV2ID0gZGV2bV9od21vbl9kZXZpY2VfcmVnaXN0ZXJfd2l0aF9ncm91cHMo
JmkyYy0+ZGV2LAorCQkJCQkJCSAgIGkyYy0+bmFtZSwKKwkJCQkJCQkgICBpMmMsCisJCQkJCQkJ
ICAgbHRjMjk5MF9ncm91cHMpOworCisJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9kZXYp
OworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5MF9pMmNfaWRb
XSA9IHsKKwl7ICJsdGMyOTkwIiwgMCB9LAorCXt9Cit9OworTU9EVUxFX0RFVklDRV9UQUJMRShp
MmMsIGx0YzI5OTBfaTJjX2lkKTsKKworc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVyIGx0YzI5OTBf
aTJjX2RyaXZlciA9IHsKKwkuZHJpdmVyID0geworCQkubmFtZSA9ICJsdGMyOTkwIiwKKwl9LAor
CS5wcm9iZSAgICA9IGx0YzI5OTBfaTJjX3Byb2JlLAorCS5pZF90YWJsZSA9IGx0YzI5OTBfaTJj
X2lkLAorfTsKKworbW9kdWxlX2kyY19kcml2ZXIobHRjMjk5MF9pMmNfZHJpdmVyKTsKKworTU9E
VUxFX0RFU0NSSVBUSU9OKCJMVEMyOTkwIFNlbnNvciBEcml2ZXIiKTsKK01PRFVMRV9BVVRIT1Io
IlRvcGljIEVtYmVkZGVkIFByb2R1Y3RzIik7CitNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Ci0t
IAoxLjkuMQoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
CmxtLXNlbnNvcnMgbWFpbGluZyBsaXN0CmxtLXNlbnNvcnNAbG0tc2Vuc29ycy5vcmcKaHR0cDov
L2xpc3RzLmxtLXNlbnNvcnMub3JnL21haWxtYW4vbGlzdGluZm8vbG0tc2Vuc29ycw=

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

* Re: [PATCH v4] hwmon: Add LTC2990 sensor driver
  2016-01-15  9:54       ` [lm-sensors] " Mike Looijmans
@ 2016-01-15 15:40         ` Guenter Roeck
  -1 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-15 15:40 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

On 01/15/2016 01:54 AM, Mike Looijmans wrote:
> This adds support for the Linear Technology LTC2990  I2C System Monitor.
> The LTC2990 supports a combination of voltage, current and temperature
> monitoring. This driver currently only supports reading two currents
> by measuring two differential voltages across series resistors, in
> addition to the Vcc supply voltage and internal temperature.
>
> This is sufficient to support the Topic Miami SOM which uses this chip
> to monitor the currents flowing into the FPGA and the CPU parts.
>
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>

Applied to -next.

Thanks,
Guenter

> ---
> v4: Fix checkpatch warnings
>      ltc2990_get_value can return error code
> v3: Remove unused includes.
>      Remove (most) unused register defines.
>      Also check on SMBUS WORD capability.
>      Use register defines as value indices.
>      Alignment fixups with "(".
> v2: Processed all review comments.
>       Put chip into continuous measurement mode.
>       Added ducumentation.
>       Use standard hwmon interfaces and macros.
>   Documentation/hwmon/ltc2990 |  44 ++++++++++++
>   drivers/hwmon/Kconfig       |  14 ++++
>   drivers/hwmon/Makefile      |   1 +
>   drivers/hwmon/ltc2990.c     | 161 ++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 220 insertions(+)
>   create mode 100644 Documentation/hwmon/ltc2990
>   create mode 100644 drivers/hwmon/ltc2990.c
>
> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
> new file mode 100644
> index 0000000..838b74e
> --- /dev/null
> +++ b/Documentation/hwmon/ltc2990
> @@ -0,0 +1,44 @@
> +Kernel driver ltc2990
> +=====================
> +
> +Supported chips:
> +  * Linear Technology LTC2990
> +    Prefix: 'ltc2990'
> +    Addresses scanned: -
> +    Datasheet: http://www.linear.com/product/ltc2990
> +
> +Author: Mike Looijmans <mike.looijmans@topic.nl>
> +
> +
> +Description
> +-----------
> +
> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
> +can be combined to measure a differential voltage, which is typically used to
> +measure current through a series resistor, or a temperature.
> +
> +This driver currently uses the 2x differential mode only. In order to support
> +other modes, the driver will need to be expanded.
> +
> +
> +Usage Notes
> +-----------
> +
> +This driver does not probe for PMBus devices. You will have to instantiate
> +devices explicitly.
> +
> +
> +Sysfs attributes
> +----------------
> +
> +The "curr*_input" measurements actually report the voltage drop across the
> +input pins in microvolts. This is equivalent to the current through a 1mOhm
> +sense resistor. Divide the reported value by the actual sense resistor value
> +in mOhm to get the actual value.
> +
> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
> +temp1_input   Internal chip temperature in millidegrees Celcius
> +curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
> +curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
> +
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 80a73bf..8a31d64 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -685,6 +685,20 @@ config SENSORS_LTC2945
>   	  This driver can also be built as a module. If so, the module will
>   	  be called ltc2945.
>
> +config SENSORS_LTC2990
> +	tristate "Linear Technology LTC2990 (current monitoring mode only)"
> +	depends on I2C
> +	help
> +	  If you say yes here you get support for Linear Technology LTC2990
> +	  I2C System Monitor. The LTC2990 supports a combination of voltage,
> +	  current and temperature monitoring, but in addition to the Vcc supply
> +	  voltage and chip temperature, this driver currently only supports
> +	  reading two currents by measuring two differential voltages across
> +	  series resistors.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called ltc2990.
> +
>   config SENSORS_LTC4151
>   	tristate "Linear Technology LTC4151"
>   	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 12a3239..e4bd15b 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)	+= lm95234.o
>   obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
>   obj-$(CONFIG_SENSORS_LM95245)	+= lm95245.o
>   obj-$(CONFIG_SENSORS_LTC2945)	+= ltc2945.o
> +obj-$(CONFIG_SENSORS_LTC2990)	+= ltc2990.o
>   obj-$(CONFIG_SENSORS_LTC4151)	+= ltc4151.o
>   obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
>   obj-$(CONFIG_SENSORS_LTC4222)	+= ltc4222.o
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> new file mode 100644
> index 0000000..8f8fe05
> --- /dev/null
> +++ b/drivers/hwmon/ltc2990.c
> @@ -0,0 +1,161 @@
> +/*
> + * Driver for Linear Technology LTC2990 power monitor
> + *
> + * Copyright (C) 2014 Topic Embedded Products
> + * Author: Mike Looijmans <mike.looijmans@topic.nl>
> + *
> + * License: GPLv2
> + *
> + * This driver assumes the chip is wired as a dual current monitor, and
> + * reports the voltage drop across two series resistors. It also reports
> + * the chip's internal temperature and Vcc power supply voltage.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define LTC2990_STATUS	0x00
> +#define LTC2990_CONTROL	0x01
> +#define LTC2990_TRIGGER	0x02
> +#define LTC2990_TINT_MSB	0x04
> +#define LTC2990_V1_MSB	0x06
> +#define LTC2990_V2_MSB	0x08
> +#define LTC2990_V3_MSB	0x0A
> +#define LTC2990_V4_MSB	0x0C
> +#define LTC2990_VCC_MSB	0x0E
> +
> +#define LTC2990_CONTROL_KELVIN		BIT(7)
> +#define LTC2990_CONTROL_SINGLE		BIT(6)
> +#define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
> +#define LTC2990_CONTROL_MODE_CURRENT	0x06
> +#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
> +
> +/* convert raw register value to sign-extended integer in 16-bit range */
> +static int ltc2990_voltage_to_int(int raw)
> +{
> +	if (raw & BIT(14))
> +		return -(0x4000 - (raw & 0x3FFF)) << 2;
> +	else
> +		return (raw & 0x3FFF) << 2;
> +}
> +
> +/* Return the converted value from the given register in uV or mC */
> +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result)
> +{
> +	int val;
> +
> +	val = i2c_smbus_read_word_swapped(i2c, reg);
> +	if (unlikely(val < 0))
> +		return val;
> +
> +	switch (reg) {
> +	case LTC2990_TINT_MSB:
> +		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
> +		val = (val & 0x1FFF) << 3;
> +		*result = (val * 1000) >> 7;
> +		break;
> +	case LTC2990_V1_MSB:
> +	case LTC2990_V3_MSB:
> +		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
> +		*result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);
> +		break;
> +	case LTC2990_VCC_MSB:
> +		/* Vcc, 305.18μV/LSB, 2.5V offset */
> +		*result = (ltc2990_voltage_to_int(val) * 30518 /
> +			   (4 * 100 * 1000)) + 2500;
> +		break;
> +	default:
> +		return -EINVAL; /* won't happen, keep compiler happy */
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t ltc2990_show_value(struct device *dev,
> +				  struct device_attribute *da, char *buf)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +	int value;
> +	int ret;
> +
> +	ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);
> +	if (unlikely(ret < 0))
> +		return ret;
> +
> +	return snprintf(buf, PAGE_SIZE, "%d\n", value);
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_TINT_MSB);
> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_V1_MSB);
> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_V3_MSB);
> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_VCC_MSB);
> +
> +static struct attribute *ltc2990_attrs[] = {
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr1_input.dev_attr.attr,
> +	&sensor_dev_attr_curr2_input.dev_attr.attr,
> +	&sensor_dev_attr_in0_input.dev_attr.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(ltc2990);
> +
> +static int ltc2990_i2c_probe(struct i2c_client *i2c,
> +			     const struct i2c_device_id *id)
> +{
> +	int ret;
> +	struct device *hwmon_dev;
> +
> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
> +				     I2C_FUNC_SMBUS_WORD_DATA))
> +		return -ENODEV;
> +
> +	/* Setup continuous mode, current monitor */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
> +					LTC2990_CONTROL_MEASURE_ALL |
> +					LTC2990_CONTROL_MODE_CURRENT);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
> +		return ret;
> +	}
> +	/* Trigger once to start continuous conversion */
> +	ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Error: Failed to start acquisition.\n");
> +		return ret;
> +	}
> +
> +	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
> +							   i2c->name,
> +							   i2c,
> +							   ltc2990_groups);
> +
> +	return PTR_ERR_OR_ZERO(hwmon_dev);
> +}
> +
> +static const struct i2c_device_id ltc2990_i2c_id[] = {
> +	{ "ltc2990", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);
> +
> +static struct i2c_driver ltc2990_i2c_driver = {
> +	.driver = {
> +		.name = "ltc2990",
> +	},
> +	.probe    = ltc2990_i2c_probe,
> +	.id_table = ltc2990_i2c_id,
> +};
> +
> +module_i2c_driver(ltc2990_i2c_driver);
> +
> +MODULE_DESCRIPTION("LTC2990 Sensor Driver");
> +MODULE_AUTHOR("Topic Embedded Products");
> +MODULE_LICENSE("GPL v2");
>

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

* Re: [lm-sensors] [PATCH v4] hwmon: Add LTC2990 sensor driver
@ 2016-01-15 15:40         ` Guenter Roeck
  0 siblings, 0 replies; 29+ messages in thread
From: Guenter Roeck @ 2016-01-15 15:40 UTC (permalink / raw)
  To: Mike Looijmans, lm-sensors; +Cc: jdelvare, linux-kernel

T24gMDEvMTUvMjAxNiAwMTo1NCBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4gVGhpcyBhZGRz
IHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMgU3lzdGVtIE1v
bml0b3IuCj4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBj
dXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRs
eSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4gYnkgbWVhc3VyaW5nIHR3byBk
aWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCj4gYWRkaXRp
b24gdG8gdGhlIFZjYyBzdXBwbHkgdm9sdGFnZSBhbmQgaW50ZXJuYWwgdGVtcGVyYXR1cmUuCj4K
PiBUaGlzIGlzIHN1ZmZpY2llbnQgdG8gc3VwcG9ydCB0aGUgVG9waWMgTWlhbWkgU09NIHdoaWNo
IHVzZXMgdGhpcyBjaGlwCj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRo
ZSBGUEdBIGFuZCB0aGUgQ1BVIHBhcnRzLgo+Cj4gU2lnbmVkLW9mZi1ieTogTWlrZSBMb29pam1h
bnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgoKQXBwbGllZCB0byAtbmV4dC4KClRoYW5rcywK
R3VlbnRlcgoKPiAtLS0KPiB2NDogRml4IGNoZWNrcGF0Y2ggd2FybmluZ3MKPiAgICAgIGx0YzI5
OTBfZ2V0X3ZhbHVlIGNhbiByZXR1cm4gZXJyb3IgY29kZQo+IHYzOiBSZW1vdmUgdW51c2VkIGlu
Y2x1ZGVzLgo+ICAgICAgUmVtb3ZlIChtb3N0KSB1bnVzZWQgcmVnaXN0ZXIgZGVmaW5lcy4KPiAg
ICAgIEFsc28gY2hlY2sgb24gU01CVVMgV09SRCBjYXBhYmlsaXR5Lgo+ICAgICAgVXNlIHJlZ2lz
dGVyIGRlZmluZXMgYXMgdmFsdWUgaW5kaWNlcy4KPiAgICAgIEFsaWdubWVudCBmaXh1cHMgd2l0
aCAiKCIuCj4gdjI6IFByb2Nlc3NlZCBhbGwgcmV2aWV3IGNvbW1lbnRzLgo+ICAgICAgIFB1dCBj
aGlwIGludG8gY29udGludW91cyBtZWFzdXJlbWVudCBtb2RlLgo+ICAgICAgIEFkZGVkIGR1Y3Vt
ZW50YXRpb24uCj4gICAgICAgVXNlIHN0YW5kYXJkIGh3bW9uIGludGVyZmFjZXMgYW5kIG1hY3Jv
cy4KPiAgIERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MCB8ICA0NCArKysrKysrKysrKysKPiAg
IGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4gICBkcml2ZXJzL2h3bW9u
L01ha2VmaWxlICAgICAgfCAgIDEgKwo+ICAgZHJpdmVycy9od21vbi9sdGMyOTkwLmMgICAgIHwg
MTYxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gICA0IGZp
bGVzIGNoYW5nZWQsIDIyMCBpbnNlcnRpb25zKCspCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgRG9j
dW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9o
d21vbi9sdGMyOTkwLmMKPgo+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5
OTAgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+
IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvRG9jdW1lbnRh
dGlvbi9od21vbi9sdGMyOTkwCj4gQEAgLTAsMCArMSw0NCBAQAo+ICtLZXJuZWwgZHJpdmVyIGx0
YzI5OTAKPiArPT09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtTdXBwb3J0ZWQgY2hpcHM6Cj4g
KyAgKiBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKyAgICBQcmVmaXg6ICdsdGMyOTkwJwo+
ICsgICAgQWRkcmVzc2VzIHNjYW5uZWQ6IC0KPiArICAgIERhdGFzaGVldDogaHR0cDovL3d3dy5s
aW5lYXIuY29tL3Byb2R1Y3QvbHRjMjk5MAo+ICsKPiArQXV0aG9yOiBNaWtlIExvb2lqbWFucyA8
bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKwo+ICsKPiArRGVzY3JpcHRpb24KPiArLS0tLS0t
LS0tLS0KPiArCj4gK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdlLCBDdXJyZW50IGFuZCBU
ZW1wZXJhdHVyZSBNb25pdG9yLgo+ICtUaGUgY2hpcCdzIGlucHV0cyBjYW4gbWVhc3VyZSA0IHZv
bHRhZ2VzLCBvciB0d28gaW5wdXRzIHRvZ2V0aGVyICgxKzIgYW5kIDMrNCkKPiArY2FuIGJlIGNv
bWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRpYWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNh
bGx5IHVzZWQgdG8KPiArbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBzZXJpZXMgcmVzaXN0b3Is
IG9yIGEgdGVtcGVyYXR1cmUuCj4gKwo+ICtUaGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUg
MnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4gSW4gb3JkZXIgdG8gc3VwcG9ydAo+ICtvdGhlciBt
b2RlcywgdGhlIGRyaXZlciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQuCj4gKwo+ICsKPiArVXNh
Z2UgTm90ZXMKPiArLS0tLS0tLS0tLS0KPiArCj4gK1RoaXMgZHJpdmVyIGRvZXMgbm90IHByb2Jl
IGZvciBQTUJ1cyBkZXZpY2VzLiBZb3Ugd2lsbCBoYXZlIHRvIGluc3RhbnRpYXRlCj4gK2Rldmlj
ZXMgZXhwbGljaXRseS4KPiArCj4gKwo+ICtTeXNmcyBhdHRyaWJ1dGVzCj4gKy0tLS0tLS0tLS0t
LS0tLS0KPiArCj4gK1RoZSAiY3VycipfaW5wdXQiIG1lYXN1cmVtZW50cyBhY3R1YWxseSByZXBv
cnQgdGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdGhlCj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0
cy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+ICtz
ZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSByZXBvcnRlZCB2YWx1ZSBieSB0aGUgYWN0dWFsIHNl
bnNlIHJlc2lzdG9yIHZhbHVlCj4gK2luIG1PaG0gdG8gZ2V0IHRoZSBhY3R1YWwgdmFsdWUuCj4g
Kwo+ICtpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNjIHBpbiBpbiBtaWxsaXZvbHQgKHJhbmdl
IDIuNVYgdG8gNVYpCj4gK3RlbXAxX2lucHV0ICAgSW50ZXJuYWwgY2hpcCB0ZW1wZXJhdHVyZSBp
biBtaWxsaWRlZ3JlZXMgQ2VsY2l1cwo+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNy
b3NzIHYxLXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4gK2N1cnIyX2lucHV0
ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNp
c3Rvci4KPiArCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMv
aHdtb24vS2NvbmZpZwo+IGluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAwNjQ0Cj4gLS0tIGEvZHJp
dmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gQEAgLTY4
NSw2ICs2ODUsMjAgQEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQo+ICAgCSAgVGhpcyBkcml2ZXIg
Y2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPiAg
IAkgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Cj4gK2NvbmZpZyBTRU5TT1JTX0xUQzI5OTAKPiArCXRy
aXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50IG1vbml0b3JpbmcgbW9k
ZSBvbmx5KSIKPiArCWRlcGVuZHMgb24gSTJDCj4gKwloZWxwCj4gKwkgIElmIHlvdSBzYXkgeWVz
IGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKwkg
IEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBv
ZiB2b2x0YWdlLAo+ICsJICBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZSBtb25pdG9yaW5nLCBidXQg
aW4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkKPiArCSAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1w
ZXJhdHVyZSwgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPiArCSAgcmVhZGlu
ZyB0d28gY3VycmVudHMgYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNy
b3NzCj4gKwkgIHNlcmllcyByZXNpc3RvcnMuCj4gKwo+ICsJICBUaGlzIGRyaXZlciBjYW4gYWxz
byBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2lsbAo+ICsJICBiZSBj
YWxsZWQgbHRjMjk5MC4KPiArCj4gICBjb25maWcgU0VOU09SU19MVEM0MTUxCj4gICAJdHJpc3Rh
dGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEiCj4gICAJZGVwZW5kcyBvbiBJMkMKPiBkaWZm
IC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUK
PiBpbmRleCAxMmEzMjM5Li5lNGJkMTViIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvaHdtb24vTWFr
ZWZpbGUKPiArKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4gQEAgLTEwMSw2ICsxMDEsNyBA
QCBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjM0KQkrPSBsbTk1MjM0Lm8KPiAgIG9iai0kKENP
TkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxtOTUyNDEubwo+ICAgb2JqLSQoQ09ORklHX1NFTlNP
UlNfTE05NTI0NSkJKz0gbG05NTI0NS5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1
KQkrPSBsdGMyOTQ1Lm8KPiArb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk5MCkJKz0gbHRjMjk5
MC5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MTUxKQkrPSBsdGM0MTUxLm8KPiAgIG9i
ai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpCSs9IGx0YzQyMTUubwo+ICAgb2JqLSQoQ09ORklH
X1NFTlNPUlNfTFRDNDIyMikJKz0gbHRjNDIyMi5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdt
b24vbHRjMjk5MC5jIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPiBuZXcgZmlsZSBtb2RlIDEw
MDY0NAo+IGluZGV4IDAwMDAwMDAuLjhmOGZlMDUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJp
dmVycy9od21vbi9sdGMyOTkwLmMKPiBAQCAtMCwwICsxLDE2MSBAQAo+ICsvKgo+ICsgKiBEcml2
ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgo+ICsgKgo+ICsg
KiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMKPiArICogQXV0aG9y
OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKyAqCj4gKyAqIExp
Y2Vuc2U6IEdQTHYyCj4gKyAqCj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAgaXMg
d2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4gKyAqIHJlcG9ydHMgdGhlIHZv
bHRhZ2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0IGFsc28gcmVwb3J0cwo+
ICsgKiB0aGUgY2hpcCdzIGludGVybmFsIHRlbXBlcmF0dXJlIGFuZCBWY2MgcG93ZXIgc3VwcGx5
IHZvbHRhZ2UuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVk
ZSA8bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNp
bmNsdWRlIDxsaW51eC9pMmMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5j
bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTCTB4MDAK
PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQo+ICsjZGVmaW5lIExUQzI5OTBfVFJJR0dF
UgkweDAyCj4gKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0Cj4gKyNkZWZpbmUgTFRDMjk5
MF9WMV9NU0IJMHgwNgo+ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCCTB4MDgKPiArI2RlZmluZSBM
VEMyOTkwX1YzX01TQgkweDBBCj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IJMHgwQwo+ICsjZGVm
aW5lIExUQzI5OTBfVkNDX01TQgkweDBFCj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9L
RUxWSU4JCUJJVCg3KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9TSU5HTEUJCUJJVCg2KQo+
ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCj4gKyNkZWZp
bmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkweDA2Cj4gKyNkZWZpbmUgTFRDMjk5MF9D
T05UUk9MX01PREVfVk9MVEFHRQkweDA3Cj4gKwo+ICsvKiBjb252ZXJ0IHJhdyByZWdpc3RlciB2
YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0IHJhbmdlICovCj4gK3N0YXRp
YyBpbnQgbHRjMjk5MF92b2x0YWdlX3RvX2ludChpbnQgcmF3KQo+ICt7Cj4gKwlpZiAocmF3ICYg
QklUKDE0KSkKPiArCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPiAr
CWVsc2UKPiArCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPiArfQo+ICsKPiArLyogUmV0
dXJuIHRoZSBjb252ZXJ0ZWQgdmFsdWUgZnJvbSB0aGUgZ2l2ZW4gcmVnaXN0ZXIgaW4gdVYgb3Ig
bUMgKi8KPiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgaTJjX2NsaWVudCAq
aTJjLCB1OCByZWcsIGludCAqcmVzdWx0KQo+ICt7Cj4gKwlpbnQgdmFsOwo+ICsKPiArCXZhbCA9
IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChpMmMsIHJlZyk7Cj4gKwlpZiAodW5saWtlbHko
dmFsIDwgMCkpCj4gKwkJcmV0dXJuIHZhbDsKPiArCj4gKwlzd2l0Y2ggKHJlZykgewo+ICsJY2Fz
ZSBMVEMyOTkwX1RJTlRfTVNCOgo+ICsJCS8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVz
L0xTQiwgMTMtYml0ICAqLwo+ICsJCXZhbCA9ICh2YWwgJiAweDFGRkYpIDw8IDM7Cj4gKwkJKnJl
c3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3Owo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkwX1Yx
X01TQjoKPiArCWNhc2UgTFRDMjk5MF9WM19NU0I6Cj4gKwkJIC8qIFZ4LVZ5LCAxOS40MnVWL0xT
Qi4gRGVwZW5kcyBvbiBtb2RlLiAqLwo+ICsJCSpyZXN1bHQgPSBsdGMyOTkwX3ZvbHRhZ2VfdG9f
aW50KHZhbCkgKiAxOTQyIC8gKDQgKiAxMDApOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkw
X1ZDQ19NU0I6Cj4gKwkJLyogVmNjLCAzMDUuMTjOvFYvTFNCLCAyLjVWIG9mZnNldCAqLwo+ICsJ
CSpyZXN1bHQgPSAobHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMzA1MTggLwo+ICsJCQkg
ICAoNCAqIDEwMCAqIDEwMDApKSArIDI1MDA7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJ
CXJldHVybiAtRUlOVkFMOyAvKiB3b24ndCBoYXBwZW4sIGtlZXAgY29tcGlsZXIgaGFwcHkgKi8K
PiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHNzaXplX3QgbHRjMjk5
MF9zaG93X3ZhbHVlKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJCSAgc3RydWN0IGRldmljZV9h
dHRyaWJ1dGUgKmRhLCBjaGFyICpidWYpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0
dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4gKwlpbnQgdmFsdWU7Cj4g
KwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IGx0YzI5OTBfZ2V0X3ZhbHVlKGRldl9nZXRfZHJ2ZGF0
YShkZXYpLCBhdHRyLT5pbmRleCwgJnZhbHVlKTsKPiArCWlmICh1bmxpa2VseShyZXQgPCAwKSkK
PiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwg
IiVkXG4iLCB2YWx1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVt
cDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKPiArCQkJICBMVEMy
OTkwX1RJTlRfTVNCKTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMV9pbnB1dCwg
U19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjFfTVNC
KTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRj
Mjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjNfTVNCKTsKPiArc3RhdGlj
IFNFTlNPUl9ERVZJQ0VfQVRUUihpbjBfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1
ZSwgTlVMTCwKPiArCQkJICBMVEMyOTkwX1ZDQ19NU0IpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBh
dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPiArCSZzZW5zb3JfZGV2X2F0dHJfdGVtcDFf
aW5wdXQuZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjFfaW5wdXQuZGV2
X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQuZGV2X2F0dHIuYXR0
ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwlOVUxM
LAo+ICt9Owo+ICtBVFRSSUJVVEVfR1JPVVBTKGx0YzI5OTApOwo+ICsKPiArc3RhdGljIGludCBs
dGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLAo+ICsJCQkgICAgIGNvbnN0
IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPiArewo+ICsJaW50IHJldDsKPiArCXN0cnVjdCBk
ZXZpY2UgKmh3bW9uX2RldjsKPiArCj4gKwlpZiAoIWkyY19jaGVja19mdW5jdGlvbmFsaXR5KGky
Yy0+YWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwKPiArCQkJCSAgICAgSTJDX0ZV
TkNfU01CVVNfV09SRF9EQVRBKSkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwkvKiBTZXR1
cCBjb250aW51b3VzIG1vZGUsIGN1cnJlbnQgbW9uaXRvciAqLwo+ICsJcmV0ID0gaTJjX3NtYnVz
X3dyaXRlX2J5dGVfZGF0YShpMmMsIExUQzI5OTBfQ09OVFJPTCwKPiArCQkJCQlMVEMyOTkwX0NP
TlRST0xfTUVBU1VSRV9BTEwgfAo+ICsJCQkJCUxUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQp
Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWls
ZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwkv
KiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBjb252ZXJzaW9uICovCj4gKwlyZXQg
PSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9UUklHR0VSLCAxKTsKPiAr
CWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRv
IHN0YXJ0IGFjcXVpc2l0aW9uLlxuIik7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlo
d21vbl9kZXYgPSBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygmaTJjLT5k
ZXYsCj4gKwkJCQkJCQkgICBpMmMtPm5hbWUsCj4gKwkJCQkJCQkgICBpMmMsCj4gKwkJCQkJCQkg
ICBsdGMyOTkwX2dyb3Vwcyk7Cj4gKwo+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9k
ZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5
MF9pMmNfaWRbXSA9IHsKPiArCXsgImx0YzI5OTAiLCAwIH0sCj4gKwl7fQo+ICt9Owo+ICtNT0RV
TEVfREVWSUNFX1RBQkxFKGkyYywgbHRjMjk5MF9pMmNfaWQpOwo+ICsKPiArc3RhdGljIHN0cnVj
dCBpMmNfZHJpdmVyIGx0YzI5OTBfaTJjX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJ
Lm5hbWUgPSAibHRjMjk5MCIsCj4gKwl9LAo+ICsJLnByb2JlICAgID0gbHRjMjk5MF9pMmNfcHJv
YmUsCj4gKwkuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19pZCwKPiArfTsKPiArCj4gK21vZHVsZV9p
MmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfREVTQ1JJUFRJT04o
IkxUQzI5OTAgU2Vuc29yIERyaXZlciIpOwo+ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRl
ZCBQcm9kdWN0cyIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4KCgpfX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcg
bGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9y
Zy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM

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

end of thread, other threads:[~2016-01-15 15:40 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-06  8:07 [PATCH] hwmon: Add LTC2990 sensor driver Mike Looijmans
2016-01-06  8:07 ` [lm-sensors] " Mike Looijmans
2016-01-06 15:22 ` Guenter Roeck
2016-01-07 18:59   ` Mike Looijmans
2016-01-07 18:59     ` [lm-sensors] " Mike Looijmans
2016-01-08 15:09     ` Guenter Roeck
2016-01-08 15:09       ` [lm-sensors] " Guenter Roeck
2016-01-13 11:22       ` Mike Looijmans
2016-01-13 11:22         ` [lm-sensors] " Mike Looijmans
2016-01-13 11:05 ` [PATCH v2] " Mike Looijmans
2016-01-13 11:05   ` [lm-sensors] " Mike Looijmans
2016-01-13 13:24   ` Guenter Roeck
2016-01-13 13:24     ` [lm-sensors] " Guenter Roeck
2016-01-13 13:51     ` Mike Looijmans
2016-01-13 13:51       ` [lm-sensors] " Mike Looijmans
2016-01-13 13:57       ` Guenter Roeck
2016-01-13 13:57         ` [lm-sensors] " Guenter Roeck
2016-01-13 14:03         ` Mike Looijmans
2016-01-13 14:03           ` [lm-sensors] " Mike Looijmans
2016-01-13 14:45   ` [PATCH v3] " Mike Looijmans
2016-01-13 14:45     ` [lm-sensors] " Mike Looijmans
2016-01-14 19:14     ` Guenter Roeck
2016-01-14 19:14       ` [lm-sensors] " Guenter Roeck
2016-01-15  9:54       ` Mike Looijmans
2016-01-15  9:54         ` [lm-sensors] " Mike Looijmans
2016-01-15  9:54     ` [PATCH v4] " Mike Looijmans
2016-01-15  9:54       ` [lm-sensors] " Mike Looijmans
2016-01-15 15:40       ` Guenter Roeck
2016-01-15 15:40         ` [lm-sensors] " Guenter Roeck

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.