1f7c2fe38SFelten, Lothar /* 2f7c2fe38SFelten, Lothar * Driver for Texas Instruments INA219, INA226 power monitor chips 3f7c2fe38SFelten, Lothar * 4f7c2fe38SFelten, Lothar * INA219: 5f7c2fe38SFelten, Lothar * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface 6f7c2fe38SFelten, Lothar * Datasheet: http://www.ti.com/product/ina219 7f7c2fe38SFelten, Lothar * 8dc92cd0cSGuenter Roeck * INA220: 9dc92cd0cSGuenter Roeck * Bi-Directional Current/Power Monitor with I2C Interface 10dc92cd0cSGuenter Roeck * Datasheet: http://www.ti.com/product/ina220 11dc92cd0cSGuenter Roeck * 12f7c2fe38SFelten, Lothar * INA226: 13f7c2fe38SFelten, Lothar * Bi-Directional Current/Power Monitor with I2C Interface 14f7c2fe38SFelten, Lothar * Datasheet: http://www.ti.com/product/ina226 15f7c2fe38SFelten, Lothar * 16dc92cd0cSGuenter Roeck * INA230: 17dc92cd0cSGuenter Roeck * Bi-directional Current/Power Monitor with I2C Interface 18dc92cd0cSGuenter Roeck * Datasheet: http://www.ti.com/product/ina230 19dc92cd0cSGuenter Roeck * 20f7c2fe38SFelten, Lothar * Copyright (C) 2012 Lothar Felten <l-felten@ti.com> 21f7c2fe38SFelten, Lothar * Thanks to Jan Volkering 22f7c2fe38SFelten, Lothar * 23f7c2fe38SFelten, Lothar * This program is free software; you can redistribute it and/or modify 24f7c2fe38SFelten, Lothar * it under the terms of the GNU General Public License as published by 25f7c2fe38SFelten, Lothar * the Free Software Foundation; version 2 of the License. 26f7c2fe38SFelten, Lothar */ 27f7c2fe38SFelten, Lothar 28f7c2fe38SFelten, Lothar #include <linux/kernel.h> 29f7c2fe38SFelten, Lothar #include <linux/module.h> 30f7c2fe38SFelten, Lothar #include <linux/init.h> 31f7c2fe38SFelten, Lothar #include <linux/err.h> 32f7c2fe38SFelten, Lothar #include <linux/slab.h> 33f7c2fe38SFelten, Lothar #include <linux/i2c.h> 34f7c2fe38SFelten, Lothar #include <linux/hwmon.h> 35f7c2fe38SFelten, Lothar #include <linux/hwmon-sysfs.h> 36dcd8f392SJean Delvare #include <linux/jiffies.h> 3731e7ad74STang Yuantian #include <linux/of.h> 38509416a8SBartosz Golaszewski #include <linux/delay.h> 39d38df34eSBartosz Golaszewski #include <linux/util_macros.h> 40*a0de56c8SMarc Titinger #include <linux/regmap.h> 41f7c2fe38SFelten, Lothar 42f7c2fe38SFelten, Lothar #include <linux/platform_data/ina2xx.h> 43f7c2fe38SFelten, Lothar 44f7c2fe38SFelten, Lothar /* common register definitions */ 45f7c2fe38SFelten, Lothar #define INA2XX_CONFIG 0x00 46f7c2fe38SFelten, Lothar #define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */ 47f7c2fe38SFelten, Lothar #define INA2XX_BUS_VOLTAGE 0x02 /* readonly */ 48f7c2fe38SFelten, Lothar #define INA2XX_POWER 0x03 /* readonly */ 49f7c2fe38SFelten, Lothar #define INA2XX_CURRENT 0x04 /* readonly */ 50f7c2fe38SFelten, Lothar #define INA2XX_CALIBRATION 0x05 51f7c2fe38SFelten, Lothar 52f7c2fe38SFelten, Lothar /* INA226 register definitions */ 53f7c2fe38SFelten, Lothar #define INA226_MASK_ENABLE 0x06 54f7c2fe38SFelten, Lothar #define INA226_ALERT_LIMIT 0x07 55f7c2fe38SFelten, Lothar #define INA226_DIE_ID 0xFF 56f7c2fe38SFelten, Lothar 57f7c2fe38SFelten, Lothar /* register count */ 58f7c2fe38SFelten, Lothar #define INA219_REGISTERS 6 59f7c2fe38SFelten, Lothar #define INA226_REGISTERS 8 60f7c2fe38SFelten, Lothar 61f7c2fe38SFelten, Lothar #define INA2XX_MAX_REGISTERS 8 62f7c2fe38SFelten, Lothar 63f7c2fe38SFelten, Lothar /* settings - depend on use case */ 64f7c2fe38SFelten, Lothar #define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ 65f7c2fe38SFelten, Lothar #define INA226_CONFIG_DEFAULT 0x4527 /* averages=16 */ 66f7c2fe38SFelten, Lothar 67f7c2fe38SFelten, Lothar /* worst case is 68.10 ms (~14.6Hz, ina219) */ 68f7c2fe38SFelten, Lothar #define INA2XX_CONVERSION_RATE 15 69509416a8SBartosz Golaszewski #define INA2XX_MAX_DELAY 69 /* worst case delay in ms */ 70509416a8SBartosz Golaszewski 71509416a8SBartosz Golaszewski #define INA2XX_RSHUNT_DEFAULT 10000 72f7c2fe38SFelten, Lothar 7372a87a47SBartosz Golaszewski /* bit mask for reading the averaging setting in the configuration register */ 7472a87a47SBartosz Golaszewski #define INA226_AVG_RD_MASK 0x0E00 7572a87a47SBartosz Golaszewski 7672a87a47SBartosz Golaszewski #define INA226_READ_AVG(reg) (((reg) & INA226_AVG_RD_MASK) >> 9) 7772a87a47SBartosz Golaszewski #define INA226_SHIFT_AVG(val) ((val) << 9) 7872a87a47SBartosz Golaszewski 7972a87a47SBartosz Golaszewski /* common attrs, ina226 attrs and NULL */ 8072a87a47SBartosz Golaszewski #define INA2XX_MAX_ATTRIBUTE_GROUPS 3 8172a87a47SBartosz Golaszewski 8272a87a47SBartosz Golaszewski /* 8372a87a47SBartosz Golaszewski * Both bus voltage and shunt voltage conversion times for ina226 are set 8472a87a47SBartosz Golaszewski * to 0b0100 on POR, which translates to 2200 microseconds in total. 8572a87a47SBartosz Golaszewski */ 8672a87a47SBartosz Golaszewski #define INA226_TOTAL_CONV_TIME_DEFAULT 2200 8772a87a47SBartosz Golaszewski 88*a0de56c8SMarc Titinger static struct regmap_config ina2xx_regmap_config = { 89*a0de56c8SMarc Titinger .reg_bits = 8, 90*a0de56c8SMarc Titinger .val_bits = 16, 91*a0de56c8SMarc Titinger }; 92*a0de56c8SMarc Titinger 93f7c2fe38SFelten, Lothar enum ina2xx_ids { ina219, ina226 }; 94f7c2fe38SFelten, Lothar 956106db25SGuenter Roeck struct ina2xx_config { 966106db25SGuenter Roeck u16 config_default; 976106db25SGuenter Roeck int calibration_factor; 986106db25SGuenter Roeck int registers; 996106db25SGuenter Roeck int shunt_div; 1006106db25SGuenter Roeck int bus_voltage_shift; 1016106db25SGuenter Roeck int bus_voltage_lsb; /* uV */ 1026106db25SGuenter Roeck int power_lsb; /* uW */ 1036106db25SGuenter Roeck }; 1046106db25SGuenter Roeck 105f7c2fe38SFelten, Lothar struct ina2xx_data { 1066106db25SGuenter Roeck const struct ina2xx_config *config; 107f7c2fe38SFelten, Lothar 108509416a8SBartosz Golaszewski long rshunt; 109*a0de56c8SMarc Titinger struct mutex config_lock; 110*a0de56c8SMarc Titinger struct regmap *regmap; 111f7c2fe38SFelten, Lothar 112f7c2fe38SFelten, Lothar int kind; 11372a87a47SBartosz Golaszewski const struct attribute_group *groups[INA2XX_MAX_ATTRIBUTE_GROUPS]; 114f7c2fe38SFelten, Lothar }; 115f7c2fe38SFelten, Lothar 1166106db25SGuenter Roeck static const struct ina2xx_config ina2xx_config[] = { 1176106db25SGuenter Roeck [ina219] = { 1186106db25SGuenter Roeck .config_default = INA219_CONFIG_DEFAULT, 1196106db25SGuenter Roeck .calibration_factor = 40960000, 1206106db25SGuenter Roeck .registers = INA219_REGISTERS, 1216106db25SGuenter Roeck .shunt_div = 100, 1226106db25SGuenter Roeck .bus_voltage_shift = 3, 1236106db25SGuenter Roeck .bus_voltage_lsb = 4000, 1246106db25SGuenter Roeck .power_lsb = 20000, 1256106db25SGuenter Roeck }, 1266106db25SGuenter Roeck [ina226] = { 1276106db25SGuenter Roeck .config_default = INA226_CONFIG_DEFAULT, 1286106db25SGuenter Roeck .calibration_factor = 5120000, 1296106db25SGuenter Roeck .registers = INA226_REGISTERS, 1306106db25SGuenter Roeck .shunt_div = 400, 1316106db25SGuenter Roeck .bus_voltage_shift = 0, 1326106db25SGuenter Roeck .bus_voltage_lsb = 1250, 1336106db25SGuenter Roeck .power_lsb = 25000, 1346106db25SGuenter Roeck }, 1356106db25SGuenter Roeck }; 1366106db25SGuenter Roeck 13772a87a47SBartosz Golaszewski /* 13872a87a47SBartosz Golaszewski * Available averaging rates for ina226. The indices correspond with 13972a87a47SBartosz Golaszewski * the bit values expected by the chip (according to the ina226 datasheet, 14072a87a47SBartosz Golaszewski * table 3 AVG bit settings, found at 14172a87a47SBartosz Golaszewski * http://www.ti.com/lit/ds/symlink/ina226.pdf. 14272a87a47SBartosz Golaszewski */ 14372a87a47SBartosz Golaszewski static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; 14472a87a47SBartosz Golaszewski 14572a87a47SBartosz Golaszewski static int ina226_reg_to_interval(u16 config) 14672a87a47SBartosz Golaszewski { 14772a87a47SBartosz Golaszewski int avg = ina226_avg_tab[INA226_READ_AVG(config)]; 14872a87a47SBartosz Golaszewski 14972a87a47SBartosz Golaszewski /* 15072a87a47SBartosz Golaszewski * Multiply the total conversion time by the number of averages. 15172a87a47SBartosz Golaszewski * Return the result in milliseconds. 15272a87a47SBartosz Golaszewski */ 15372a87a47SBartosz Golaszewski return DIV_ROUND_CLOSEST(avg * INA226_TOTAL_CONV_TIME_DEFAULT, 1000); 15472a87a47SBartosz Golaszewski } 15572a87a47SBartosz Golaszewski 156*a0de56c8SMarc Titinger /* 157*a0de56c8SMarc Titinger * Return the new, shifted AVG field value of CONFIG register, 158*a0de56c8SMarc Titinger * to use with regmap_update_bits 159*a0de56c8SMarc Titinger */ 160*a0de56c8SMarc Titinger static u16 ina226_interval_to_reg(int interval) 16172a87a47SBartosz Golaszewski { 16272a87a47SBartosz Golaszewski int avg, avg_bits; 16372a87a47SBartosz Golaszewski 16472a87a47SBartosz Golaszewski avg = DIV_ROUND_CLOSEST(interval * 1000, 16572a87a47SBartosz Golaszewski INA226_TOTAL_CONV_TIME_DEFAULT); 166d38df34eSBartosz Golaszewski avg_bits = find_closest(avg, ina226_avg_tab, 167d38df34eSBartosz Golaszewski ARRAY_SIZE(ina226_avg_tab)); 16872a87a47SBartosz Golaszewski 169*a0de56c8SMarc Titinger return INA226_SHIFT_AVG(avg_bits); 17072a87a47SBartosz Golaszewski } 17172a87a47SBartosz Golaszewski 1728a5fc795SBartosz Golaszewski static int ina2xx_calibrate(struct ina2xx_data *data) 1738a5fc795SBartosz Golaszewski { 174b721fe2aSBartosz Golaszewski u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor, 175b721fe2aSBartosz Golaszewski data->rshunt); 176b721fe2aSBartosz Golaszewski 177*a0de56c8SMarc Titinger return regmap_write(data->regmap, INA2XX_CALIBRATION, val); 1788a5fc795SBartosz Golaszewski } 1798a5fc795SBartosz Golaszewski 180509416a8SBartosz Golaszewski /* 181509416a8SBartosz Golaszewski * Initialize the configuration and calibration registers. 182509416a8SBartosz Golaszewski */ 183509416a8SBartosz Golaszewski static int ina2xx_init(struct ina2xx_data *data) 184509416a8SBartosz Golaszewski { 185*a0de56c8SMarc Titinger int ret = regmap_write(data->regmap, INA2XX_CONFIG, 186*a0de56c8SMarc Titinger data->config->config_default); 187509416a8SBartosz Golaszewski if (ret < 0) 188509416a8SBartosz Golaszewski return ret; 189509416a8SBartosz Golaszewski 190509416a8SBartosz Golaszewski /* 191509416a8SBartosz Golaszewski * Set current LSB to 1mA, shunt is in uOhms 192509416a8SBartosz Golaszewski * (equation 13 in datasheet). 193509416a8SBartosz Golaszewski */ 1948a5fc795SBartosz Golaszewski return ina2xx_calibrate(data); 195509416a8SBartosz Golaszewski } 196509416a8SBartosz Golaszewski 197*a0de56c8SMarc Titinger static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) 198f7c2fe38SFelten, Lothar { 199468bf0e3SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 200*a0de56c8SMarc Titinger int ret, retry; 201509416a8SBartosz Golaszewski 202*a0de56c8SMarc Titinger dev_dbg(dev, "Starting register %d read\n", reg); 203509416a8SBartosz Golaszewski 204509416a8SBartosz Golaszewski for (retry = 5; retry; retry--) { 205*a0de56c8SMarc Titinger 206*a0de56c8SMarc Titinger ret = regmap_read(data->regmap, reg, regval); 207*a0de56c8SMarc Titinger if (ret < 0) 208*a0de56c8SMarc Titinger return ret; 209*a0de56c8SMarc Titinger 210*a0de56c8SMarc Titinger dev_dbg(dev, "read %d, val = 0x%04x\n", reg, *regval); 211509416a8SBartosz Golaszewski 212509416a8SBartosz Golaszewski /* 213509416a8SBartosz Golaszewski * If the current value in the calibration register is 0, the 214509416a8SBartosz Golaszewski * power and current registers will also remain at 0. In case 215509416a8SBartosz Golaszewski * the chip has been reset let's check the calibration 216509416a8SBartosz Golaszewski * register and reinitialize if needed. 217*a0de56c8SMarc Titinger * We do that extra read of the calibration register if there 218*a0de56c8SMarc Titinger * is some hint of a chip reset. 219509416a8SBartosz Golaszewski */ 220*a0de56c8SMarc Titinger if (*regval == 0) { 221*a0de56c8SMarc Titinger unsigned int cal; 222*a0de56c8SMarc Titinger 223*a0de56c8SMarc Titinger ret = regmap_read(data->regmap, INA2XX_CALIBRATION, 224*a0de56c8SMarc Titinger &cal); 225*a0de56c8SMarc Titinger if (ret < 0) 226*a0de56c8SMarc Titinger return ret; 227*a0de56c8SMarc Titinger 228*a0de56c8SMarc Titinger if (cal == 0) { 229509416a8SBartosz Golaszewski dev_warn(dev, "chip not calibrated, reinitializing\n"); 230509416a8SBartosz Golaszewski 231*a0de56c8SMarc Titinger ret = ina2xx_init(data); 232*a0de56c8SMarc Titinger if (ret < 0) 233*a0de56c8SMarc Titinger return ret; 234509416a8SBartosz Golaszewski /* 235*a0de56c8SMarc Titinger * Let's make sure the power and current 236*a0de56c8SMarc Titinger * registers have been updated before trying 237*a0de56c8SMarc Titinger * again. 238509416a8SBartosz Golaszewski */ 239509416a8SBartosz Golaszewski msleep(INA2XX_MAX_DELAY); 240509416a8SBartosz Golaszewski continue; 241509416a8SBartosz Golaszewski } 242*a0de56c8SMarc Titinger } 243509416a8SBartosz Golaszewski return 0; 244509416a8SBartosz Golaszewski } 245509416a8SBartosz Golaszewski 246509416a8SBartosz Golaszewski /* 247509416a8SBartosz Golaszewski * If we're here then although all write operations succeeded, the 248509416a8SBartosz Golaszewski * chip still returns 0 in the calibration register. Nothing more we 249509416a8SBartosz Golaszewski * can do here. 250509416a8SBartosz Golaszewski */ 251509416a8SBartosz Golaszewski dev_err(dev, "unable to reinitialize the chip\n"); 252509416a8SBartosz Golaszewski return -ENODEV; 253509416a8SBartosz Golaszewski } 254509416a8SBartosz Golaszewski 255*a0de56c8SMarc Titinger static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, 256*a0de56c8SMarc Titinger unsigned int regval) 257f7c2fe38SFelten, Lothar { 2586106db25SGuenter Roeck int val; 259f7c2fe38SFelten, Lothar 260f7c2fe38SFelten, Lothar switch (reg) { 261f7c2fe38SFelten, Lothar case INA2XX_SHUNT_VOLTAGE: 262c0214f98SFabio Baltieri /* signed register */ 263*a0de56c8SMarc Titinger val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div); 264f7c2fe38SFelten, Lothar break; 265f7c2fe38SFelten, Lothar case INA2XX_BUS_VOLTAGE: 266*a0de56c8SMarc Titinger val = (regval >> data->config->bus_voltage_shift) 2676106db25SGuenter Roeck * data->config->bus_voltage_lsb; 2686106db25SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 1000); 269f7c2fe38SFelten, Lothar break; 270f7c2fe38SFelten, Lothar case INA2XX_POWER: 271*a0de56c8SMarc Titinger val = regval * data->config->power_lsb; 272f7c2fe38SFelten, Lothar break; 273f7c2fe38SFelten, Lothar case INA2XX_CURRENT: 274c0214f98SFabio Baltieri /* signed register, LSB=1mA (selected), in mA */ 275*a0de56c8SMarc Titinger val = (s16)regval; 276f7c2fe38SFelten, Lothar break; 2778a5fc795SBartosz Golaszewski case INA2XX_CALIBRATION: 278b721fe2aSBartosz Golaszewski val = DIV_ROUND_CLOSEST(data->config->calibration_factor, 279*a0de56c8SMarc Titinger regval); 2808a5fc795SBartosz Golaszewski break; 281f7c2fe38SFelten, Lothar default: 282f7c2fe38SFelten, Lothar /* programmer goofed */ 283f7c2fe38SFelten, Lothar WARN_ON_ONCE(1); 284f7c2fe38SFelten, Lothar val = 0; 285f7c2fe38SFelten, Lothar break; 286f7c2fe38SFelten, Lothar } 287f7c2fe38SFelten, Lothar 288f7c2fe38SFelten, Lothar return val; 289f7c2fe38SFelten, Lothar } 290f7c2fe38SFelten, Lothar 291f7c2fe38SFelten, Lothar static ssize_t ina2xx_show_value(struct device *dev, 292f7c2fe38SFelten, Lothar struct device_attribute *da, char *buf) 293f7c2fe38SFelten, Lothar { 294f7c2fe38SFelten, Lothar struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 295*a0de56c8SMarc Titinger struct ina2xx_data *data = dev_get_drvdata(dev); 296*a0de56c8SMarc Titinger unsigned int regval; 297f7c2fe38SFelten, Lothar 298*a0de56c8SMarc Titinger int err = ina2xx_read_reg(dev, attr->index, ®val); 299*a0de56c8SMarc Titinger 300*a0de56c8SMarc Titinger if (err < 0) 301*a0de56c8SMarc Titinger return err; 302f7c2fe38SFelten, Lothar 3036106db25SGuenter Roeck return snprintf(buf, PAGE_SIZE, "%d\n", 304*a0de56c8SMarc Titinger ina2xx_get_value(data, attr->index, regval)); 305f7c2fe38SFelten, Lothar } 306f7c2fe38SFelten, Lothar 3078a5fc795SBartosz Golaszewski static ssize_t ina2xx_set_shunt(struct device *dev, 3088a5fc795SBartosz Golaszewski struct device_attribute *da, 3098a5fc795SBartosz Golaszewski const char *buf, size_t count) 3108a5fc795SBartosz Golaszewski { 3118a5fc795SBartosz Golaszewski unsigned long val; 3128a5fc795SBartosz Golaszewski int status; 313*a0de56c8SMarc Titinger struct ina2xx_data *data = dev_get_drvdata(dev); 3148a5fc795SBartosz Golaszewski 3158a5fc795SBartosz Golaszewski status = kstrtoul(buf, 10, &val); 3168a5fc795SBartosz Golaszewski if (status < 0) 3178a5fc795SBartosz Golaszewski return status; 3188a5fc795SBartosz Golaszewski 3198a5fc795SBartosz Golaszewski if (val == 0 || 3208a5fc795SBartosz Golaszewski /* Values greater than the calibration factor make no sense. */ 3218a5fc795SBartosz Golaszewski val > data->config->calibration_factor) 3228a5fc795SBartosz Golaszewski return -EINVAL; 3238a5fc795SBartosz Golaszewski 324*a0de56c8SMarc Titinger mutex_lock(&data->config_lock); 3258a5fc795SBartosz Golaszewski data->rshunt = val; 3268a5fc795SBartosz Golaszewski status = ina2xx_calibrate(data); 327*a0de56c8SMarc Titinger mutex_unlock(&data->config_lock); 3288a5fc795SBartosz Golaszewski if (status < 0) 3298a5fc795SBartosz Golaszewski return status; 3308a5fc795SBartosz Golaszewski 3318a5fc795SBartosz Golaszewski return count; 3328a5fc795SBartosz Golaszewski } 3338a5fc795SBartosz Golaszewski 33472a87a47SBartosz Golaszewski static ssize_t ina226_set_interval(struct device *dev, 33572a87a47SBartosz Golaszewski struct device_attribute *da, 33672a87a47SBartosz Golaszewski const char *buf, size_t count) 33772a87a47SBartosz Golaszewski { 33872a87a47SBartosz Golaszewski struct ina2xx_data *data = dev_get_drvdata(dev); 33972a87a47SBartosz Golaszewski unsigned long val; 34072a87a47SBartosz Golaszewski int status; 34172a87a47SBartosz Golaszewski 34272a87a47SBartosz Golaszewski status = kstrtoul(buf, 10, &val); 34372a87a47SBartosz Golaszewski if (status < 0) 34472a87a47SBartosz Golaszewski return status; 34572a87a47SBartosz Golaszewski 34672a87a47SBartosz Golaszewski if (val > INT_MAX || val == 0) 34772a87a47SBartosz Golaszewski return -EINVAL; 34872a87a47SBartosz Golaszewski 349*a0de56c8SMarc Titinger status = regmap_update_bits(data->regmap, INA2XX_CONFIG, 350*a0de56c8SMarc Titinger INA226_AVG_RD_MASK, 351*a0de56c8SMarc Titinger ina226_interval_to_reg(val)); 35272a87a47SBartosz Golaszewski if (status < 0) 35372a87a47SBartosz Golaszewski return status; 35472a87a47SBartosz Golaszewski 35572a87a47SBartosz Golaszewski return count; 35672a87a47SBartosz Golaszewski } 35772a87a47SBartosz Golaszewski 35872a87a47SBartosz Golaszewski static ssize_t ina226_show_interval(struct device *dev, 35972a87a47SBartosz Golaszewski struct device_attribute *da, char *buf) 36072a87a47SBartosz Golaszewski { 361*a0de56c8SMarc Titinger struct ina2xx_data *data = dev_get_drvdata(dev); 362*a0de56c8SMarc Titinger int status; 363*a0de56c8SMarc Titinger unsigned int regval; 36472a87a47SBartosz Golaszewski 365*a0de56c8SMarc Titinger status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); 366*a0de56c8SMarc Titinger if (status) 367*a0de56c8SMarc Titinger return status; 36872a87a47SBartosz Golaszewski 369*a0de56c8SMarc Titinger return snprintf(buf, PAGE_SIZE, "%d\n", ina226_reg_to_interval(regval)); 37072a87a47SBartosz Golaszewski } 37172a87a47SBartosz Golaszewski 372f7c2fe38SFelten, Lothar /* shunt voltage */ 373f0df0fd9SGuenter Roeck static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL, 374f0df0fd9SGuenter Roeck INA2XX_SHUNT_VOLTAGE); 375f7c2fe38SFelten, Lothar 376f7c2fe38SFelten, Lothar /* bus voltage */ 377f0df0fd9SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina2xx_show_value, NULL, 378f0df0fd9SGuenter Roeck INA2XX_BUS_VOLTAGE); 379f7c2fe38SFelten, Lothar 380f7c2fe38SFelten, Lothar /* calculated current */ 381f0df0fd9SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina2xx_show_value, NULL, 382f0df0fd9SGuenter Roeck INA2XX_CURRENT); 383f7c2fe38SFelten, Lothar 384f7c2fe38SFelten, Lothar /* calculated power */ 385f0df0fd9SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, 386f0df0fd9SGuenter Roeck INA2XX_POWER); 387f7c2fe38SFelten, Lothar 3888a5fc795SBartosz Golaszewski /* shunt resistance */ 3898a5fc795SBartosz Golaszewski static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, 3908a5fc795SBartosz Golaszewski ina2xx_show_value, ina2xx_set_shunt, 3918a5fc795SBartosz Golaszewski INA2XX_CALIBRATION); 3928a5fc795SBartosz Golaszewski 39372a87a47SBartosz Golaszewski /* update interval (ina226 only) */ 39472a87a47SBartosz Golaszewski static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, 39572a87a47SBartosz Golaszewski ina226_show_interval, ina226_set_interval, 0); 39672a87a47SBartosz Golaszewski 397f7c2fe38SFelten, Lothar /* pointers to created device attributes */ 398468bf0e3SGuenter Roeck static struct attribute *ina2xx_attrs[] = { 399f7c2fe38SFelten, Lothar &sensor_dev_attr_in0_input.dev_attr.attr, 400f7c2fe38SFelten, Lothar &sensor_dev_attr_in1_input.dev_attr.attr, 401f7c2fe38SFelten, Lothar &sensor_dev_attr_curr1_input.dev_attr.attr, 402f7c2fe38SFelten, Lothar &sensor_dev_attr_power1_input.dev_attr.attr, 4038a5fc795SBartosz Golaszewski &sensor_dev_attr_shunt_resistor.dev_attr.attr, 404f7c2fe38SFelten, Lothar NULL, 405f7c2fe38SFelten, Lothar }; 40672a87a47SBartosz Golaszewski 40772a87a47SBartosz Golaszewski static const struct attribute_group ina2xx_group = { 40872a87a47SBartosz Golaszewski .attrs = ina2xx_attrs, 40972a87a47SBartosz Golaszewski }; 41072a87a47SBartosz Golaszewski 41172a87a47SBartosz Golaszewski static struct attribute *ina226_attrs[] = { 41272a87a47SBartosz Golaszewski &sensor_dev_attr_update_interval.dev_attr.attr, 41372a87a47SBartosz Golaszewski NULL, 41472a87a47SBartosz Golaszewski }; 41572a87a47SBartosz Golaszewski 41672a87a47SBartosz Golaszewski static const struct attribute_group ina226_group = { 41772a87a47SBartosz Golaszewski .attrs = ina226_attrs, 41872a87a47SBartosz Golaszewski }; 419f7c2fe38SFelten, Lothar 420f7c2fe38SFelten, Lothar static int ina2xx_probe(struct i2c_client *client, 421f7c2fe38SFelten, Lothar const struct i2c_device_id *id) 422f7c2fe38SFelten, Lothar { 423f7c2fe38SFelten, Lothar struct ina2xx_platform_data *pdata; 424468bf0e3SGuenter Roeck struct device *dev = &client->dev; 425468bf0e3SGuenter Roeck struct ina2xx_data *data; 426468bf0e3SGuenter Roeck struct device *hwmon_dev; 427468bf0e3SGuenter Roeck u32 val; 42872a87a47SBartosz Golaszewski int ret, group = 0; 429f7c2fe38SFelten, Lothar 430468bf0e3SGuenter Roeck data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 431f7c2fe38SFelten, Lothar if (!data) 432f7c2fe38SFelten, Lothar return -ENOMEM; 433f7c2fe38SFelten, Lothar 434468bf0e3SGuenter Roeck if (dev_get_platdata(dev)) { 435468bf0e3SGuenter Roeck pdata = dev_get_platdata(dev); 436509416a8SBartosz Golaszewski data->rshunt = pdata->shunt_uohms; 437468bf0e3SGuenter Roeck } else if (!of_property_read_u32(dev->of_node, 43831e7ad74STang Yuantian "shunt-resistor", &val)) { 439509416a8SBartosz Golaszewski data->rshunt = val; 440509416a8SBartosz Golaszewski } else { 441509416a8SBartosz Golaszewski data->rshunt = INA2XX_RSHUNT_DEFAULT; 442f7c2fe38SFelten, Lothar } 443f7c2fe38SFelten, Lothar 444f7c2fe38SFelten, Lothar /* set the device type */ 445f7c2fe38SFelten, Lothar data->kind = id->driver_data; 4466106db25SGuenter Roeck data->config = &ina2xx_config[data->kind]; 44772a87a47SBartosz Golaszewski 448e7947040SBartosz Golaszewski if (data->rshunt <= 0 || 449e7947040SBartosz Golaszewski data->rshunt > data->config->calibration_factor) 450509416a8SBartosz Golaszewski return -ENODEV; 451509416a8SBartosz Golaszewski 452*a0de56c8SMarc Titinger ina2xx_regmap_config.max_register = data->config->registers; 453*a0de56c8SMarc Titinger 454*a0de56c8SMarc Titinger data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); 455*a0de56c8SMarc Titinger if (IS_ERR(data->regmap)) { 456*a0de56c8SMarc Titinger dev_err(dev, "failed to allocate register map\n"); 457*a0de56c8SMarc Titinger return PTR_ERR(data->regmap); 458*a0de56c8SMarc Titinger } 459*a0de56c8SMarc Titinger 460509416a8SBartosz Golaszewski ret = ina2xx_init(data); 461509416a8SBartosz Golaszewski if (ret < 0) { 462509416a8SBartosz Golaszewski dev_err(dev, "error configuring the device: %d\n", ret); 463509416a8SBartosz Golaszewski return -ENODEV; 464509416a8SBartosz Golaszewski } 465509416a8SBartosz Golaszewski 466*a0de56c8SMarc Titinger mutex_init(&data->config_lock); 467f7c2fe38SFelten, Lothar 46872a87a47SBartosz Golaszewski data->groups[group++] = &ina2xx_group; 46972a87a47SBartosz Golaszewski if (data->kind == ina226) 47072a87a47SBartosz Golaszewski data->groups[group++] = &ina226_group; 47172a87a47SBartosz Golaszewski 472468bf0e3SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 47372a87a47SBartosz Golaszewski data, data->groups); 474468bf0e3SGuenter Roeck if (IS_ERR(hwmon_dev)) 475468bf0e3SGuenter Roeck return PTR_ERR(hwmon_dev); 476f7c2fe38SFelten, Lothar 477468bf0e3SGuenter Roeck dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n", 478509416a8SBartosz Golaszewski id->name, data->rshunt); 4796106db25SGuenter Roeck 480f7c2fe38SFelten, Lothar return 0; 481f7c2fe38SFelten, Lothar } 482f7c2fe38SFelten, Lothar 483f7c2fe38SFelten, Lothar static const struct i2c_device_id ina2xx_id[] = { 484f7c2fe38SFelten, Lothar { "ina219", ina219 }, 485dc92cd0cSGuenter Roeck { "ina220", ina219 }, 486f7c2fe38SFelten, Lothar { "ina226", ina226 }, 487dc92cd0cSGuenter Roeck { "ina230", ina226 }, 488add513beSKevin Hilman { "ina231", ina226 }, 489f7c2fe38SFelten, Lothar { } 490f7c2fe38SFelten, Lothar }; 491f7c2fe38SFelten, Lothar MODULE_DEVICE_TABLE(i2c, ina2xx_id); 492f7c2fe38SFelten, Lothar 493f7c2fe38SFelten, Lothar static struct i2c_driver ina2xx_driver = { 494f7c2fe38SFelten, Lothar .driver = { 495f7c2fe38SFelten, Lothar .name = "ina2xx", 496f7c2fe38SFelten, Lothar }, 497f7c2fe38SFelten, Lothar .probe = ina2xx_probe, 498f7c2fe38SFelten, Lothar .id_table = ina2xx_id, 499f7c2fe38SFelten, Lothar }; 500f7c2fe38SFelten, Lothar 501d835ca0fSWei Yongjun module_i2c_driver(ina2xx_driver); 502f7c2fe38SFelten, Lothar 503f7c2fe38SFelten, Lothar MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>"); 504f7c2fe38SFelten, Lothar MODULE_DESCRIPTION("ina2xx driver"); 505f7c2fe38SFelten, Lothar MODULE_LICENSE("GPL"); 506