aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/ina2xx29
-rw-r--r--drivers/hwmon/Kconfig13
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ina2xx.c368
-rw-r--r--include/linux/platform_data/ina2xx.h19
5 files changed, 430 insertions, 0 deletions
diff --git a/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx
new file mode 100644
index 000000000000..f50a6cc27616
--- /dev/null
+++ b/Documentation/hwmon/ina2xx
@@ -0,0 +1,29 @@
1Kernel driver ina2xx
2====================
3
4Supported chips:
5 * Texas Instruments INA219
6 Prefix: 'ina219'
7 Addresses: I2C 0x40 - 0x4f
8 Datasheet: Publicly available at the Texas Instruments website
9 http://www.ti.com/
10
11 * Texas Instruments INA226
12 Prefix: 'ina226'
13 Addresses: I2C 0x40 - 0x4f
14 Datasheet: Publicly available at the Texas Instruments website
15 http://www.ti.com/
16
17Author: Lothar Felten <l-felten@ti.com>
18
19Description
20-----------
21
22The INA219 is a high-side current shunt and power monitor with an I2C
23interface. The INA219 monitors both shunt drop and supply voltage, with
24programmable conversion times and filtering.
25
26The INA226 is a current shunt and power monitor with an I2C interface.
27The INA226 monitors both a shunt voltage drop and bus supply voltage.
28
29The shunt value in micro-ohms can be set via platform data.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 8deedc1b9840..1c7bbd458902 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1102,6 +1102,19 @@ config SENSORS_AMC6821
1102 This driver can also be build as a module. If so, the module 1102 This driver can also be build as a module. If so, the module
1103 will be called amc6821. 1103 will be called amc6821.
1104 1104
1105config SENSORS_INA2XX
1106 tristate "Texas Instruments INA219, INA226"
1107 depends on I2C && EXPERIMENTAL
1108 help
1109 If you say yes here you get support for INA219 and INA226 power
1110 monitor chips.
1111
1112 The INA2xx driver is configured for the default configuration of
1113 the part as described in the datasheet.
1114 Default value for Rshunt is 10 mOhms.
1115 This driver can also be built as a module. If so, the module
1116 will be called ina2xx.
1117
1105config SENSORS_THMC50 1118config SENSORS_THMC50
1106 tristate "Texas Instruments THMC50 / Analog Devices ADM1022" 1119 tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
1107 depends on I2C 1120 depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 6d3f11f71815..e1eeac13b851 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
62obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o 62obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
63obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o 63obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
64obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o 64obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
65obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
65obj-$(CONFIG_SENSORS_IT87) += it87.o 66obj-$(CONFIG_SENSORS_IT87) += it87.o
66obj-$(CONFIG_SENSORS_JC42) += jc42.o 67obj-$(CONFIG_SENSORS_JC42) += jc42.o
67obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o 68obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
new file mode 100644
index 000000000000..7f3f4a385729
--- /dev/null
+++ b/drivers/hwmon/ina2xx.c
@@ -0,0 +1,368 @@
1/*
2 * Driver for Texas Instruments INA219, INA226 power monitor chips
3 *
4 * INA219:
5 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
6 * Datasheet: http://www.ti.com/product/ina219
7 *
8 * INA226:
9 * Bi-Directional Current/Power Monitor with I2C Interface
10 * Datasheet: http://www.ti.com/product/ina226
11 *
12 * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
13 * Thanks to Jan Volkering
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; version 2 of the License.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/err.h>
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/hwmon.h>
27#include <linux/hwmon-sysfs.h>
28
29#include <linux/platform_data/ina2xx.h>
30
31/* common register definitions */
32#define INA2XX_CONFIG 0x00
33#define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */
34#define INA2XX_BUS_VOLTAGE 0x02 /* readonly */
35#define INA2XX_POWER 0x03 /* readonly */
36#define INA2XX_CURRENT 0x04 /* readonly */
37#define INA2XX_CALIBRATION 0x05
38
39/* INA226 register definitions */
40#define INA226_MASK_ENABLE 0x06
41#define INA226_ALERT_LIMIT 0x07
42#define INA226_DIE_ID 0xFF
43
44
45/* register count */
46#define INA219_REGISTERS 6
47#define INA226_REGISTERS 8
48
49#define INA2XX_MAX_REGISTERS 8
50
51/* settings - depend on use case */
52#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */
53#define INA226_CONFIG_DEFAULT 0x4527 /* averages=16 */
54
55/* worst case is 68.10 ms (~14.6Hz, ina219) */
56#define INA2XX_CONVERSION_RATE 15
57
58enum ina2xx_ids { ina219, ina226 };
59
60struct ina2xx_data {
61 struct device *hwmon_dev;
62
63 struct mutex update_lock;
64 bool valid;
65 unsigned long last_updated;
66
67 int kind;
68 int registers;
69 u16 regs[INA2XX_MAX_REGISTERS];
70};
71
72int ina2xx_read_word(struct i2c_client *client, int reg)
73{
74 int val = i2c_smbus_read_word_data(client, reg);
75 if (unlikely(val < 0)) {
76 dev_dbg(&client->dev,
77 "Failed to read register: %d\n", reg);
78 return val;
79 }
80 return be16_to_cpu(val);
81}
82
83void ina2xx_write_word(struct i2c_client *client, int reg, int data)
84{
85 i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
86}
87
88static struct ina2xx_data *ina2xx_update_device(struct device *dev)
89{
90 struct i2c_client *client = to_i2c_client(dev);
91 struct ina2xx_data *data = i2c_get_clientdata(client);
92 struct ina2xx_data *ret = data;
93
94 mutex_lock(&data->update_lock);
95
96 if (time_after(jiffies, data->last_updated +
97 HZ / INA2XX_CONVERSION_RATE) || !data->valid) {
98
99 int i;
100
101 dev_dbg(&client->dev, "Starting ina2xx update\n");
102
103 /* Read all registers */
104 for (i = 0; i < data->registers; i++) {
105 int rv = ina2xx_read_word(client, i);
106 if (rv < 0) {
107 ret = ERR_PTR(rv);
108 goto abort;
109 }
110 data->regs[i] = rv;
111 }
112 data->last_updated = jiffies;
113 data->valid = 1;
114 }
115abort:
116 mutex_unlock(&data->update_lock);
117 return ret;
118}
119
120static int ina219_get_value(struct ina2xx_data *data, u8 reg)
121{
122 /*
123 * calculate exact value for the given register
124 * we assume default power-on reset settings:
125 * bus voltage range 32V
126 * gain = /8
127 * adc 1 & 2 -> conversion time 532uS
128 * mode is continuous shunt and bus
129 * calibration value is INA219_CALIBRATION_VALUE
130 */
131 int val = data->regs[reg];
132