diff options
| -rw-r--r-- | Documentation/hwmon/ina2xx | 29 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/ina2xx.c | 368 | ||||
| -rw-r--r-- | include/linux/platform_data/ina2xx.h | 19 |
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 @@ | |||
| 1 | Kernel driver ina2xx | ||
| 2 | ==================== | ||
| 3 | |||
| 4 | Supported 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 | |||
| 17 | Author: Lothar Felten <l-felten@ti.com> | ||
| 18 | |||
| 19 | Description | ||
| 20 | ----------- | ||
| 21 | |||
| 22 | The INA219 is a high-side current shunt and power monitor with an I2C | ||
| 23 | interface. The INA219 monitors both shunt drop and supply voltage, with | ||
| 24 | programmable conversion times and filtering. | ||
| 25 | |||
| 26 | The INA226 is a current shunt and power monitor with an I2C interface. | ||
| 27 | The INA226 monitors both a shunt voltage drop and bus supply voltage. | ||
| 28 | |||
| 29 | The 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 | ||
| 1105 | config 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 | |||
| 1105 | config SENSORS_THMC50 | 1118 | config 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 | |||
| 62 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | 62 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o |
| 63 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | 63 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o |
| 64 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 64 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
| 65 | obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o | ||
| 65 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 66 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
| 66 | obj-$(CONFIG_SENSORS_JC42) += jc42.o | 67 | obj-$(CONFIG_SENSORS_JC42) += jc42.o |
| 67 | obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o | 68 | obj-$(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 | |||
| 58 | enum ina2xx_ids { ina219, ina226 }; | ||
| 59 | |||
| 60 | struct 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 | |||
| 72 | int 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 | |||
| 83 | void 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 | |||
| 88 | static 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 | } | ||
| 115 | abort: | ||
| 116 | mutex_unlock(&data->update_lock); | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | static 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 | |||
