* [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
@ 2012-05-08 17:43 Felten, Lothar
2012-05-08 17:49 ` Guenter Roeck
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Felten, Lothar @ 2012-05-08 17:43 UTC (permalink / raw)
To: lm-sensors
Hello,
This patch brings support for the Texas Instruments INA219 and INA226 power monitors.
Signed-off-by: Lothar Felten <l-felten@ti.com>
--
diff -uprN linux-3.3.4/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx
--- linux-3.3.4/Documentation/hwmon/ina2xx 1970-01-01 01:00:00.000000000 +0100
+++ b/Documentation/hwmon/ina2xx 2012-05-07 15:27:56.142307748 +0200
@@ -0,0 +1,29 @@
+Kernel driver ina2xx
+==========
+
+Supported chips:
+ * Texas Instruments INA219
+ Prefix: 'ina219'
+ Addresses: I2C 0x40 - 0x4f
+ Datasheet: Publicly available at the Texas Instruments website
+ http://www.ti.com/
+
+ * Texas Instruments INA226
+ Prefix: 'ina226'
+ Addresses: I2C 0x40 - 0x4f
+ Datasheet: Publicly available at the Texas Instruments website
+ http://www.ti.com/
+
+Author: Lothar Felten <l-felten@ti.com>
+
+Description
+-----------
+
+The INA219 is a high-side current shunt and power monitor with an I2C
+interface. The INA219 monitors both shunt drop and supply voltage, with
+programmable conversion times and filtering.
+
+The INA226 is a current shunt and power monitor with an I2C interface.
+The INA226 monitors both a shunt voltage drop and bus supply voltage.
+
+The shunt value in milliohms can be set via the kernel config.
diff -uprN linux-3.3.4/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
--- linux-3.3.4/drivers/hwmon/ina2xx.c 1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/hwmon/ina2xx.c 2012-05-08 19:02:26.305202216 +0200
@@ -0,0 +1,369 @@
+/*
+ * Driver for Texas Instruments INA219, INA226 power monitor chips
+ *
+ * INA219:
+ * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina219
+ *
+ * INA226:
+ * Bi-Directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina226
+ *
+ * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Thanks to Jan Volkering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <linux/platform_data/ina2xx.h>
+
+/* common register definitions */
+#define INA2XX_CONFIG 0x00
+#define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */
+#define INA2XX_BUS_VOLTAGE 0x02 /* readonly */
+#define INA2XX_POWER 0x03 /* readonly */
+#define INA2XX_CURRENT 0x04 /* readonly */
+#define INA2XX_CALIBRATION 0x05
+
+/* INA226 register definitions */
+#define INA226_MASK_ENABLE 0x06
+#define INA226_ALERT_LIMIT 0x07
+#define INA226_DIE_ID 0xFF
+
+
+/* register count */
+#define INA219_REGISTERS 6
+#define INA226_REGISTERS 8
+
+#define INA2XX_MAX_REGISTERS 8
+
+/* settings - depend on use case */
+#define INA219_CONFIG_DEFAULT 0x219F /* PGA=1 */
+#define INA226_CONFIG_DEFAULT 0x4527 /* averages\x16 */
+
+/* worst case is 68.10 ms (~14.6Hz, ina219) */
+#define INA2XX_CONVERSION_RATE 15
+
+enum ina2xx_ids { ina219, ina226 };
+
+struct ina2xx_data {
+ struct device *hwmon_dev;
+
+ struct mutex update_lock;
+ bool valid;
+ unsigned long last_updated;
+
+ int kind;
+ int registers;
+ u16 regs[INA2XX_MAX_REGISTERS];
+};
+
+int ina2xx_read_word(struct i2c_client *client, int reg)
+{
+ int val = i2c_smbus_read_word_data(client, reg);
+ if (unlikely(val < 0)) {
+ dev_dbg(&client->dev,
+ "Failed to read register: %d\n", reg);
+ return val;
+ }
+ return be16_to_cpu(val);
+}
+
+void ina2xx_write_word(struct i2c_client *client, int reg, int data)
+{
+ i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
+}
+
+static struct ina2xx_data *ina2xx_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ina2xx_data *data = i2c_get_clientdata(client);
+ struct ina2xx_data *ret = data;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated +
+ HZ / INA2XX_CONVERSION_RATE) || !data->valid) {
+
+ int i;
+
+ dev_dbg(&client->dev, "Starting ina2xx update\n");
+
+ /* Read all registers */
+ for (i = 0; i < data->registers; i++) {
+ int rv = ina2xx_read_word(client, i);
+ if (rv < 0) {
+ ret = ERR_PTR(rv);
+ goto abort;
+ }
+ data->regs[i] = rv;
+ }
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+abort:
+ mutex_unlock(&data->update_lock);
+ return ret;
+}
+
+static int ina219_get_value(struct ina2xx_data *data, u8 reg)
+{
+ /*
+ * calculate exact value for the given register
+ * we assume default power-on reset settings:
+ * bus voltage range 32V
+ * gain = /8
+ * adc 1 & 2 -> conversion time 532uS
+ * mode is continuous shunt and bus
+ * calibration value is INA219_CALIBRATION_VALUE
+ */
+ int val = data->regs[reg];
+
+ switch (reg) {
+ case INA2XX_SHUNT_VOLTAGE:
+ /* LSB\x10uV. Convert to mV. */
+ val = DIV_ROUND_CLOSEST(val, 100);
+ break;
+ case INA2XX_BUS_VOLTAGE:
+ /* LSB=4mV. Register is not right aligned, convert to mV. */
+ val = (val >> 3) * 4;
+ break;
+ case INA2XX_POWER:
+ /* LSB mW. Convert to uW */
+ val = val * 20 * 1000;
+ break;
+ case INA2XX_CURRENT:
+ /* LSB=1mA (selected). Is in mA */
+ break;
+ default:
+ /* programmer goofed */
+ WARN_ON_ONCE(1);
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static int ina226_get_value(struct ina2xx_data *data, u8 reg)
+{
+ /*
+ * calculate exact value for the given register
+ * we assume default power-on reset settings:
+ * bus voltage range 32V
+ * gain = /8
+ * adc 1 & 2 -> conversion time 532uS
+ * mode is continuous shunt and bus
+ * calibration value is INA226_CALIBRATION_VALUE
+ */
+ int val = data->regs[reg];
+
+ switch (reg) {
+ case INA2XX_SHUNT_VOLTAGE:
+ /* LSB=2.5uV. Convert to mV. */
+ val = DIV_ROUND_CLOSEST(val, 400);
+ break;
+ case INA2XX_BUS_VOLTAGE:
+ /* LSB=1.25mV. Convert to mV. */
+ val = val + DIV_ROUND_CLOSEST(val, 4);
+ break;
+ case INA2XX_POWER:
+ /* LSB%mW. Convert to uW */
+ val = val * 25 * 1000;
+ break;
+ case INA2XX_CURRENT:
+ /* LSB=1mA (selected). Is in mA */
+ break;
+ default:
+ /* programmer goofed */
+ WARN_ON_ONCE(1);
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static ssize_t ina2xx_show_value(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ina2xx_data *data = ina2xx_update_device(dev);
+ int value = 0;
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ switch (data->kind) {
+ case ina219:
+ value = ina219_get_value(data, attr->index);
+ break;
+ case ina226:
+ value = ina226_get_value(data, attr->index);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+/* shunt voltage */
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_SHUNT_VOLTAGE);
+
+/* bus voltage */
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_BUS_VOLTAGE);
+
+/* calculated current */
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_CURRENT);
+
+/* calculated power */
+static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_POWER);
+
+/* pointers to created device attributes */
+static struct attribute *ina2xx_attributes[] = {
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_curr1_input.dev_attr.attr,
+ &sensor_dev_attr_power1_input.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ina2xx_group = {
+ .attrs = ina2xx_attributes,
+};
+
+static int ina2xx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = client->adapter;
+ struct ina2xx_data *data;
+ struct ina2xx_platform_data *pdata;
+ int ret = 0;
+ long shunt = 10000; /* default shunt value 10mOhms */
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (client->dev.platform_data) {
+ pdata = (struct ina2xx_platform_data *)
+ client->dev.platform_data;
+ shunt = pdata->shunt_uohms;
+ }
+
+ if (shunt <= 0)
+ return -ENODEV;
+
+ /* set the device type */
+ data->kind = id->driver_data;
+
+ switch (data->kind) {
+ case ina219:
+ /* device configuration */
+ ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT);
+
+ /* set current LSB to 1mA, shunt is in uOhms */
+ /* (equation 13 in datasheet) */
+ ina2xx_write_word(client, INA2XX_CALIBRATION, (40960 / shunt));
+ dev_info(&client->dev,
+ "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);
+ data->registers = INA219_REGISTERS;
+ break;
+ case ina226:
+ /* device configuration */
+ ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT);
+
+ /* set current LSB to 1mA, shunt is in uOhms */
+ /* (equation 1 in datasheet)*/
+ ina2xx_write_word(client, INA2XX_CALIBRATION, (5120 / shunt));
+ dev_info(&client->dev,
+ "power monitor INA226 (Rshunt = %li uOhm)\n", shunt);
+ data->registers = INA226_REGISTERS;
+ break;
+ default:
+ /* unknown device id */
+ return -ENODEV;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ ret = sysfs_create_group(&client->dev.kobj, &ina2xx_group);
+ if (ret)
+ return ret;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto out_err_hwmon;
+
+ }
+
+ return 0;
+
+out_err_hwmon:
+ sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
+ return ret;
+}
+
+static int ina2xx_remove(struct i2c_client *client)
+{
+ struct ina2xx_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
+
+ return 0;
+}
+
+static const struct i2c_device_id ina2xx_id[] = {
+ { "ina219", ina219 },
+ { "ina226", ina226 },
+ { }
+}
+MODULE_DEVICE_TABLE(i2c, ina2xx_id);
+
+static struct i2c_driver ina2xx_driver = {
+ .driver = {
+ .name = "ina2xx",
+ },
+ .probe = ina2xx_probe,
+ .remove = ina2xx_remove,
+ .id_table = ina2xx_id,
+};
+
+static int __init ina2xx_init(void)
+{
+ return i2c_add_driver(&ina2xx_driver);
+}
+
+static void __exit ina2xx_exit(void)
+{
+ i2c_del_driver(&ina2xx_driver);
+}
+
+MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");
+MODULE_DESCRIPTION("ina2xx driver");
+MODULE_LICENSE("GPL");
+
+module_init(ina2xx_init);
+module_exit(ina2xx_exit);
diff -uprN linux-3.3.4/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
--- linux-3.3.4/drivers/hwmon/Kconfig 2012-04-27 19:17:35.000000000 +0200
+++ b/drivers/hwmon/Kconfig 2012-05-08 17:37:10.385113357 +0200
@@ -1088,6 +1088,19 @@ config SENSORS_AMC6821
This driver can also be build as a module. If so, the module
will be called amc6821.
+config SENSORS_INA2XX
+ tristate "Texas Instruments INA219, INA226"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for INA219 and INA226 power
+ monitor chips.
+
+ The INA2xx driver is configured for the default configuration of
+ the part as described in the datasheet.
+ Default value for Rshunt is 10 mOhms.
+ This driver can also be built as a module. If so, the module
+ will be called ina2xx.
+
config SENSORS_THMC50
tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
depends on I2C
diff -uprN linux-3.3.4/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
--- linux-3.3.4/drivers/hwmon/Makefile 2012-04-27 19:17:35.000000000 +0200
+++ b/drivers/hwmon/Makefile 2012-05-07 17:08:52.978200050 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45
obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
+obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_JC42) += jc42.o
obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o
diff -uprN linux-3.3.4/include/linux/platform_data/ina2xx.h b/include/linux/platform_data/ina2xx.h
--- linux-3.3.4/include/linux/platform_data/ina2xx.h 1970-01-01 01:00:00.000000000 +0100
+++ b/include/linux/platform_data/ina2xx.h 2012-05-08 12:36:48.616800341 +0200
@@ -0,0 +1,20 @@
+/*
+ * Driver for Texas Instruments INA219, INA226 power monitor chips
+ *
+ * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * For further information, see the Documentation/hwmon/ina2xx file.
+ */
+
+/**
+ * struct ina2xx_platform_data - ina2xx info
+ * @shunt_uohms shunt resistance in microohms
+ */
+struct ina2xx_platform_data {
+ long shunt_uohms;
+};
+
Texas Instruments Belgium SA, Rond Point Schuman 6- Bo?te 5, 1040 Bruxelles. BCE: 0414.207.123. RPM Bruxelles. IBAN: BE83570121895615. Swift: CITIBEBX. TVA BE 0414.207.123
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
@ 2012-05-08 17:49 ` Guenter Roeck
2012-05-08 17:57 ` Guenter Roeck
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2012-05-08 17:49 UTC (permalink / raw)
To: lm-sensors
On Tue, 2012-05-08 at 13:43 -0400, Felten, Lothar wrote:
> Hello,
>
> This patch brings support for the Texas Instruments INA219 and INA226 power monitors.
>
> Signed-off-by: Lothar Felten <l-felten@ti.com>
Hi Lothar,
couple of minors. See inline. No need to resubmit, I already took care
of it.
> --
> diff -uprN linux-3.3.4/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx
> --- linux-3.3.4/Documentation/hwmon/ina2xx 1970-01-01 01:00:00.000000000 +0100
> +++ b/Documentation/hwmon/ina2xx 2012-05-07 15:27:56.142307748 +0200
> @@ -0,0 +1,29 @@
> +Kernel driver ina2xx
> +==========
> +
> +Supported chips:
> + * Texas Instruments INA219
> + Prefix: 'ina219'
> + Addresses: I2C 0x40 - 0x4f
> + Datasheet: Publicly available at the Texas Instruments website
> + http://www.ti.com/
> +
> + * Texas Instruments INA226
> + Prefix: 'ina226'
> + Addresses: I2C 0x40 - 0x4f
> + Datasheet: Publicly available at the Texas Instruments website
> + http://www.ti.com/
> +
> +Author: Lothar Felten <l-felten@ti.com>
> +
> +Description
> +-----------
> +
> +The INA219 is a high-side current shunt and power monitor with an I2C
> +interface. The INA219 monitors both shunt drop and supply voltage, with
> +programmable conversion times and filtering.
> +
> +The INA226 is a current shunt and power monitor with an I2C interface.
> +The INA226 monitors both a shunt voltage drop and bus supply voltage.
> +
> +The shunt value in milliohms can be set via the kernel config.
No longer true; via platform data and micro-ohm.
> diff -uprN linux-3.3.4/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
> --- linux-3.3.4/drivers/hwmon/ina2xx.c 1970-01-01 01:00:00.000000000 +0100
> +++ b/drivers/hwmon/ina2xx.c 2012-05-08 19:02:26.305202216 +0200
> @@ -0,0 +1,369 @@
[ ... ]
> +
> +static const struct i2c_device_id ina2xx_id[] = {
> + { "ina219", ina219 },
> + { "ina226", ina226 },
> + { }
> +}
I get a compile error here, due to the missing semicolon above. Wonder
why you don't see it. Did you compile it into the kernel (ie not as
module) ? That might explain it.
> +MODULE_DEVICE_TABLE(i2c, ina2xx_id);
> +
> +
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] 7+ messages in thread
* Re: [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
2012-05-08 17:49 ` Guenter Roeck
@ 2012-05-08 17:57 ` Guenter Roeck
2012-05-12 19:50 ` Guenter Roeck
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2012-05-08 17:57 UTC (permalink / raw)
To: lm-sensors
On Tue, 2012-05-08 at 13:43 -0400, Felten, Lothar wrote:
> Hello,
>
> This patch brings support for the Texas Instruments INA219 and INA226 power monitors.
>
> Signed-off-by: Lothar Felten <l-felten@ti.com>
Ah, just found something else:
[ ... ]
> + switch (data->kind) {
> + case ina219:
> + /* device configuration */
> + ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT);
> +
> + /* set current LSB to 1mA, shunt is in uOhms */
> + /* (equation 13 in datasheet) */
> + ina2xx_write_word(client, INA2XX_CALIBRATION, (40960 / shunt));
shunt is now in uOhm, so I suspect the above is probably no longer
correct. Can you verify ?
> + dev_info(&client->dev,
> + "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);
> + data->registers = INA219_REGISTERS;
> + break;
> + case ina226:
> + /* device configuration */
> + ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT);
> +
> + /* set current LSB to 1mA, shunt is in uOhms */
> + /* (equation 1 in datasheet)*/
> + ina2xx_write_word(client, INA2XX_CALIBRATION, (5120 / shunt));
Same here. With 10,000 uOhm default, the above doesn't really make sense
anymore, and should probably be something like
5120000 / shunt
[ Oh, and the ( ) around the equation isn't needed ... ]
Please have a look and resubmit.
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] 7+ messages in thread
* [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
2012-05-08 17:49 ` Guenter Roeck
2012-05-08 17:57 ` Guenter Roeck
@ 2012-05-12 19:50 ` Guenter Roeck
2012-05-21 16:44 ` Guenter Roeck
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2012-05-12 19:50 UTC (permalink / raw)
To: lm-sensors
From: "Felten, Lothar" <l-felten@ti.com>
Add support for the Texas Instruments INA219 and INA226 power monitors.
Signed-off-by: Lothar Felten <l-felten@ti.com>
[guenter.roeck@ericsson.com: Cosmetic formatting changes]
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
---
Just realized Lothar forgot to copy the list on this. So here it is.
Documentation/hwmon/ina2xx | 29 +++
drivers/hwmon/Kconfig | 13 ++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ina2xx.c | 368 ++++++++++++++++++++++++++++++++++
include/linux/platform_data/ina2xx.h | 19 ++
5 files changed, 430 insertions(+), 0 deletions(-)
create mode 100644 Documentation/hwmon/ina2xx
create mode 100644 drivers/hwmon/ina2xx.c
create mode 100644 include/linux/platform_data/ina2xx.h
diff --git a/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx
new file mode 100644
index 0000000..f50a6cc
--- /dev/null
+++ b/Documentation/hwmon/ina2xx
@@ -0,0 +1,29 @@
+Kernel driver ina2xx
+==========
+
+Supported chips:
+ * Texas Instruments INA219
+ Prefix: 'ina219'
+ Addresses: I2C 0x40 - 0x4f
+ Datasheet: Publicly available at the Texas Instruments website
+ http://www.ti.com/
+
+ * Texas Instruments INA226
+ Prefix: 'ina226'
+ Addresses: I2C 0x40 - 0x4f
+ Datasheet: Publicly available at the Texas Instruments website
+ http://www.ti.com/
+
+Author: Lothar Felten <l-felten@ti.com>
+
+Description
+-----------
+
+The INA219 is a high-side current shunt and power monitor with an I2C
+interface. The INA219 monitors both shunt drop and supply voltage, with
+programmable conversion times and filtering.
+
+The INA226 is a current shunt and power monitor with an I2C interface.
+The INA226 monitors both a shunt voltage drop and bus supply voltage.
+
+The shunt value in micro-ohms can be set via platform data.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 8deedc1..1c7bbd4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1102,6 +1102,19 @@ config SENSORS_AMC6821
This driver can also be build as a module. If so, the module
will be called amc6821.
+config SENSORS_INA2XX
+ tristate "Texas Instruments INA219, INA226"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for INA219 and INA226 power
+ monitor chips.
+
+ The INA2xx driver is configured for the default configuration of
+ the part as described in the datasheet.
+ Default value for Rshunt is 10 mOhms.
+ This driver can also be built as a module. If so, the module
+ will be called ina2xx.
+
config SENSORS_THMC50
tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 6d3f11f..e1eeac1 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
+obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_JC42) += jc42.o
obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
new file mode 100644
index 0000000..94a8743
--- /dev/null
+++ b/drivers/hwmon/ina2xx.c
@@ -0,0 +1,368 @@
+/*
+ * Driver for Texas Instruments INA219, INA226 power monitor chips
+ *
+ * INA219:
+ * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina219
+ *
+ * INA226:
+ * Bi-Directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina226
+ *
+ * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Thanks to Jan Volkering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <linux/platform_data/ina2xx.h>
+
+/* common register definitions */
+#define INA2XX_CONFIG 0x00
+#define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */
+#define INA2XX_BUS_VOLTAGE 0x02 /* readonly */
+#define INA2XX_POWER 0x03 /* readonly */
+#define INA2XX_CURRENT 0x04 /* readonly */
+#define INA2XX_CALIBRATION 0x05
+
+/* INA226 register definitions */
+#define INA226_MASK_ENABLE 0x06
+#define INA226_ALERT_LIMIT 0x07
+#define INA226_DIE_ID 0xFF
+
+
+/* register count */
+#define INA219_REGISTERS 6
+#define INA226_REGISTERS 8
+
+#define INA2XX_MAX_REGISTERS 8
+
+/* settings - depend on use case */
+#define INA219_CONFIG_DEFAULT 0x219F /* PGA=1 */
+#define INA226_CONFIG_DEFAULT 0x4527 /* averages\x16 */
+
+/* worst case is 68.10 ms (~14.6Hz, ina219) */
+#define INA2XX_CONVERSION_RATE 15
+
+enum ina2xx_ids { ina219, ina226 };
+
+struct ina2xx_data {
+ struct device *hwmon_dev;
+
+ struct mutex update_lock;
+ bool valid;
+ unsigned long last_updated;
+
+ int kind;
+ int registers;
+ u16 regs[INA2XX_MAX_REGISTERS];
+};
+
+int ina2xx_read_word(struct i2c_client *client, int reg)
+{
+ int val = i2c_smbus_read_word_data(client, reg);
+ if (unlikely(val < 0)) {
+ dev_dbg(&client->dev,
+ "Failed to read register: %d\n", reg);
+ return val;
+ }
+ return be16_to_cpu(val);
+}
+
+void ina2xx_write_word(struct i2c_client *client, int reg, int data)
+{
+ i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
+}
+
+static struct ina2xx_data *ina2xx_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ina2xx_data *data = i2c_get_clientdata(client);
+ struct ina2xx_data *ret = data;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated +
+ HZ / INA2XX_CONVERSION_RATE) || !data->valid) {
+
+ int i;
+
+ dev_dbg(&client->dev, "Starting ina2xx update\n");
+
+ /* Read all registers */
+ for (i = 0; i < data->registers; i++) {
+ int rv = ina2xx_read_word(client, i);
+ if (rv < 0) {
+ ret = ERR_PTR(rv);
+ goto abort;
+ }
+ data->regs[i] = rv;
+ }
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+abort:
+ mutex_unlock(&data->update_lock);
+ return ret;
+}
+
+static int ina219_get_value(struct ina2xx_data *data, u8 reg)
+{
+ /*
+ * calculate exact value for the given register
+ * we assume default power-on reset settings:
+ * bus voltage range 32V
+ * gain = /8
+ * adc 1 & 2 -> conversion time 532uS
+ * mode is continuous shunt and bus
+ * calibration value is INA219_CALIBRATION_VALUE
+ */
+ int val = data->regs[reg];
+
+ switch (reg) {
+ case INA2XX_SHUNT_VOLTAGE:
+ /* LSB\x10uV. Convert to mV. */
+ val = DIV_ROUND_CLOSEST(val, 100);
+ break;
+ case INA2XX_BUS_VOLTAGE:
+ /* LSB=4mV. Register is not right aligned, convert to mV. */
+ val = (val >> 3) * 4;
+ break;
+ case INA2XX_POWER:
+ /* LSB mW. Convert to uW */
+ val = val * 20 * 1000;
+ break;
+ case INA2XX_CURRENT:
+ /* LSB=1mA (selected). Is in mA */
+ break;
+ default:
+ /* programmer goofed */
+ WARN_ON_ONCE(1);
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static int ina226_get_value(struct ina2xx_data *data, u8 reg)
+{
+ /*
+ * calculate exact value for the given register
+ * we assume default power-on reset settings:
+ * bus voltage range 32V
+ * gain = /8
+ * adc 1 & 2 -> conversion time 532uS
+ * mode is continuous shunt and bus
+ * calibration value is INA226_CALIBRATION_VALUE
+ */
+ int val = data->regs[reg];
+
+ switch (reg) {
+ case INA2XX_SHUNT_VOLTAGE:
+ /* LSB=2.5uV. Convert to mV. */
+ val = DIV_ROUND_CLOSEST(val, 400);
+ break;
+ case INA2XX_BUS_VOLTAGE:
+ /* LSB=1.25mV. Convert to mV. */
+ val = val + DIV_ROUND_CLOSEST(val, 4);
+ break;
+ case INA2XX_POWER:
+ /* LSB%mW. Convert to uW */
+ val = val * 25 * 1000;
+ break;
+ case INA2XX_CURRENT:
+ /* LSB=1mA (selected). Is in mA */
+ break;
+ default:
+ /* programmer goofed */
+ WARN_ON_ONCE(1);
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static ssize_t ina2xx_show_value(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ina2xx_data *data = ina2xx_update_device(dev);
+ int value = 0;
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ switch (data->kind) {
+ case ina219:
+ value = ina219_get_value(data, attr->index);
+ break;
+ case ina226:
+ value = ina226_get_value(data, attr->index);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+/* shunt voltage */
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_SHUNT_VOLTAGE);
+
+/* bus voltage */
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_BUS_VOLTAGE);
+
+/* calculated current */
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_CURRENT);
+
+/* calculated power */
+static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, \
+ ina2xx_show_value, NULL, INA2XX_POWER);
+
+/* pointers to created device attributes */
+static struct attribute *ina2xx_attributes[] = {
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_curr1_input.dev_attr.attr,
+ &sensor_dev_attr_power1_input.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ina2xx_group = {
+ .attrs = ina2xx_attributes,
+};
+
+static int ina2xx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = client->adapter;
+ struct ina2xx_data *data;
+ struct ina2xx_platform_data *pdata;
+ int ret = 0;
+ long shunt = 10000; /* default shunt value 10mOhms */
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (client->dev.platform_data) {
+ pdata + (struct ina2xx_platform_data *)client->dev.platform_data;
+ shunt = pdata->shunt_uohms;
+ }
+
+ if (shunt <= 0)
+ return -ENODEV;
+
+ /* set the device type */
+ data->kind = id->driver_data;
+
+ switch (data->kind) {
+ case ina219:
+ /* device configuration */
+ ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT);
+
+ /* set current LSB to 1mA, shunt is in uOhms */
+ /* (equation 13 in datasheet) */
+ ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt);
+ dev_info(&client->dev,
+ "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);
+ data->registers = INA219_REGISTERS;
+ break;
+ case ina226:
+ /* device configuration */
+ ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT);
+
+ /* set current LSB to 1mA, shunt is in uOhms */
+ /* (equation 1 in datasheet)*/
+ ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt);
+ dev_info(&client->dev,
+ "power monitor INA226 (Rshunt = %li uOhm)\n", shunt);
+ data->registers = INA226_REGISTERS;
+ break;
+ default:
+ /* unknown device id */
+ return -ENODEV;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ ret = sysfs_create_group(&client->dev.kobj, &ina2xx_group);
+ if (ret)
+ return ret;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto out_err_hwmon;
+ }
+
+ return 0;
+
+out_err_hwmon:
+ sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
+ return ret;
+}
+
+static int ina2xx_remove(struct i2c_client *client)
+{
+ struct ina2xx_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
+
+ return 0;
+}
+
+static const struct i2c_device_id ina2xx_id[] = {
+ { "ina219", ina219 },
+ { "ina226", ina226 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ina2xx_id);
+
+static struct i2c_driver ina2xx_driver = {
+ .driver = {
+ .name = "ina2xx",
+ },
+ .probe = ina2xx_probe,
+ .remove = ina2xx_remove,
+ .id_table = ina2xx_id,
+};
+
+static int __init ina2xx_init(void)
+{
+ return i2c_add_driver(&ina2xx_driver);
+}
+
+static void __exit ina2xx_exit(void)
+{
+ i2c_del_driver(&ina2xx_driver);
+}
+
+MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");
+MODULE_DESCRIPTION("ina2xx driver");
+MODULE_LICENSE("GPL");
+
+module_init(ina2xx_init);
+module_exit(ina2xx_exit);
diff --git a/include/linux/platform_data/ina2xx.h b/include/linux/platform_data/ina2xx.h
new file mode 100644
index 0000000..9abc0ca
--- /dev/null
+++ b/include/linux/platform_data/ina2xx.h
@@ -0,0 +1,19 @@
+/*
+ * Driver for Texas Instruments INA219, INA226 power monitor chips
+ *
+ * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * For further information, see the Documentation/hwmon/ina2xx file.
+ */
+
+/**
+ * struct ina2xx_platform_data - ina2xx info
+ * @shunt_uohms shunt resistance in microohms
+ */
+struct ina2xx_platform_data {
+ long shunt_uohms;
+};
--
1.7.9.48.g85da4d
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
` (2 preceding siblings ...)
2012-05-12 19:50 ` Guenter Roeck
@ 2012-05-21 16:44 ` Guenter Roeck
2012-05-22 7:13 ` Felten, Lothar
2012-05-22 13:47 ` Guenter Roeck
5 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2012-05-21 16:44 UTC (permalink / raw)
To: lm-sensors
Hi Lothar,
On Tue, 2012-05-08 at 13:43 -0400, Felten, Lothar wrote:
> Hello,
>
> This patch brings support for the Texas Instruments INA219 and INA226 power monitors.
>
I have a couple of observations.
[ ... ]
> diff -uprN linux-3.3.4/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
> --- linux-3.3.4/drivers/hwmon/ina2xx.c 1970-01-01 01:00:00.000000000 +0100
> +++ b/drivers/hwmon/ina2xx.c 2012-05-08 19:02:26.305202216 +0200
[ ... ]
> +
> +/* settings - depend on use case */
> +#define INA219_CONFIG_DEFAULT 0x219F /* PGA=1 */
> +#define INA226_CONFIG_DEFAULT 0x4527 /* averages\x16 */
> +
With this configuration (PGA=1), the dynamic range for the shunt
resistor voltage is 40 mV. Since we report the value in mV, it does not
provide much value to do that. It might be better to use PGA=8 instead,
for a dynamic range of 320 mV.
Did you have a special reason for selecting PGA=1 ? Otherwise, I think
we should change it to PGA=8.
[ ... ]
> +
> + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
> + return -ENODEV;
> +
This is actually wrong; we need to check for I2C_FUNC_SMBUS_WORD_DATA
instead. I fixed that already.
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] 7+ messages in thread
* Re: [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
` (3 preceding siblings ...)
2012-05-21 16:44 ` Guenter Roeck
@ 2012-05-22 7:13 ` Felten, Lothar
2012-05-22 13:47 ` Guenter Roeck
5 siblings, 0 replies; 7+ messages in thread
From: Felten, Lothar @ 2012-05-22 7:13 UTC (permalink / raw)
To: lm-sensors
SGkgR3VlbnRlciwNCg0KPiBIaSBMb3RoYXIsDQo+DQo+ID4gSGVsbG8sDQo+ID4NCj4gPiBUaGlz
IHBhdGNoIGJyaW5ncyBzdXBwb3J0IGZvciB0aGUgVGV4YXMgSW5zdHJ1bWVudHMgSU5BMjE5IGFu
ZCBJTkEyMjYNCj4gcG93ZXIgbW9uaXRvcnMuDQo+ID4NCj4gSSBoYXZlIGEgY291cGxlIG9mIG9i
c2VydmF0aW9ucy4NCj4NCj4gWyAuLi4gXQ0KPiA+ICsNCj4gPiArLyogc2V0dGluZ3MgLSBkZXBl
bmQgb24gdXNlIGNhc2UgKi8NCj4gPiArI2RlZmluZSBJTkEyMTlfQ09ORklHX0RFRkFVTFQgICAg
ICAgICAgMHgyMTlGICAvKiBQR0E9MSAqLw0KPiA+ICsjZGVmaW5lIElOQTIyNl9DT05GSUdfREVG
QVVMVCAgICAgICAgICAweDQ1MjcgIC8qIGF2ZXJhZ2VzPTE2ICovDQo+ID4gKw0KPg0KPiBXaXRo
IHRoaXMgY29uZmlndXJhdGlvbiAoUEdBPTEpLCB0aGUgZHluYW1pYyByYW5nZSBmb3IgdGhlIHNo
dW50DQo+IHJlc2lzdG9yIHZvbHRhZ2UgaXMgNDAgbVYuIFNpbmNlIHdlIHJlcG9ydCB0aGUgdmFs
dWUgaW4gbVYsIGl0IGRvZXMgbm90DQo+IHByb3ZpZGUgbXVjaCB2YWx1ZSB0byBkbyB0aGF0LiBJ
dCBtaWdodCBiZSBiZXR0ZXIgdG8gdXNlIFBHQT04IGluc3RlYWQsDQo+IGZvciBhIGR5bmFtaWMg
cmFuZ2Ugb2YgMzIwIG1WLg0KPg0KPiBEaWQgeW91IGhhdmUgYSBzcGVjaWFsIHJlYXNvbiBmb3Ig
c2VsZWN0aW5nIFBHQT0xID8gT3RoZXJ3aXNlLCBJIHRoaW5rDQo+IHdlIHNob3VsZCBjaGFuZ2Ug
aXQgdG8gUEdBPTguDQoNCk5vIHRoZXJlIHdhcyBubyBzcGVjaWFsIHJlYXNvbiwgdGhlIGRlZmF1
bHQgc2V0dGluZyBhZnRlciByZXNldCBpcyBQR0E9OCwgdGhpcw0KSXMgcHJvYmFibHkgdGhlIGJl
c3Qgc2VsZWN0aW9uLiBTbyB0aGF0IHNob3VsZCBiZToNCiNkZWZpbmUgSU5BMjE5X0NPTkZJR19E
RUZBVUxUICAgICAgICAgIDB4Mzk5RiAgLyogZGVmYXVsdCB2YWx1ZXMgKi8NCg0KSU5BMlhYX1NI
VU5UX1ZPTFRBR0Ugd2lsbCB0aGVuIGdvIGZyb20gLTMyMG1WIHRvICszMjBtViwgdGhhdCBzaG91
bGQgYmUgb2suDQoNCj4gWyAuLi4gXQ0KPg0KPiA+ICsNCj4gPiArICAgICAgIGlmICghaTJjX2No
ZWNrX2Z1bmN0aW9uYWxpdHkoYWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBKSkNCj4g
PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTk9ERVY7DQo+ID4gKw0KPg0KPiBUaGlzIGlzIGFj
dHVhbGx5IHdyb25nOyB3ZSBuZWVkIHRvIGNoZWNrIGZvciBJMkNfRlVOQ19TTUJVU19XT1JEX0RB
VEENCj4gaW5zdGVhZC4gSSBmaXhlZCB0aGF0IGFscmVhZHkuDQo+DQo+IFRoYW5rcywNCj4gR3Vl
bnRlcg0KDQpCZXN0IHJlZ2FyZHMsDQpMb3RoYXINCg0KDQoNCg0KVGV4YXMgSW5zdHJ1bWVudHMg
QmVsZ2l1bSBTQSwgUm9uZCBQb2ludCBTY2h1bWFuIDbigJMgQm/DrnRlIDUsIDEwNDAgQnJ1eGVs
bGVzLiBCQ0U6IDA0MTQuMjA3LjEyMy4gUlBNIEJydXhlbGxlcy4gSUJBTjogQkU4MzU3MDEyMTg5
NTYxNS4gU3dpZnQ6IENJVElCRUJYLiBUVkEgQkUgMDQxNC4yMDcuMTIzDQoNCg0KX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5n
IGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5v
cmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [lm-sensors] [PATCH] hwmon: INA219 and INA226 support
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
` (4 preceding siblings ...)
2012-05-22 7:13 ` Felten, Lothar
@ 2012-05-22 13:47 ` Guenter Roeck
5 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2012-05-22 13:47 UTC (permalink / raw)
To: lm-sensors
On Tue, May 22, 2012 at 03:13:35AM -0400, Felten, Lothar wrote:
> Hi Guenter,
>
> > Hi Lothar,
> >
> > > Hello,
> > >
> > > This patch brings support for the Texas Instruments INA219 and INA226
> > power monitors.
> > >
> > I have a couple of observations.
> >
> > [ ... ]
> > > +
> > > +/* settings - depend on use case */
> > > +#define INA219_CONFIG_DEFAULT 0x219F /* PGA=1 */
> > > +#define INA226_CONFIG_DEFAULT 0x4527 /* averages\x16 */
> > > +
> >
> > With this configuration (PGA=1), the dynamic range for the shunt
> > resistor voltage is 40 mV. Since we report the value in mV, it does not
> > provide much value to do that. It might be better to use PGA=8 instead,
> > for a dynamic range of 320 mV.
> >
> > Did you have a special reason for selecting PGA=1 ? Otherwise, I think
> > we should change it to PGA=8.
>
> No there was no special reason, the default setting after reset is PGA=8, this
> Is probably the best selection. So that should be:
> #define INA219_CONFIG_DEFAULT 0x399F /* default values */
>
> INA2XX_SHUNT_VOLTAGE will then go from -320mV to +320mV, that should be ok.
>
Ok, I updated that in the pending patch.
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] 7+ messages in thread
end of thread, other threads:[~2012-05-22 13:47 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-08 17:43 [lm-sensors] [PATCH] hwmon: INA219 and INA226 support Felten, Lothar
2012-05-08 17:49 ` Guenter Roeck
2012-05-08 17:57 ` Guenter Roeck
2012-05-12 19:50 ` Guenter Roeck
2012-05-21 16:44 ` Guenter Roeck
2012-05-22 7:13 ` Felten, Lothar
2012-05-22 13:47 ` 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.