1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f7c2fe38SFelten, Lothar /* 3f7c2fe38SFelten, Lothar * Driver for Texas Instruments INA219, INA226 power monitor chips 4f7c2fe38SFelten, Lothar * 5f7c2fe38SFelten, Lothar * INA219: 6f7c2fe38SFelten, Lothar * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface 749dc2fb0SAlexander A. Klimov * Datasheet: https://www.ti.com/product/ina219 8f7c2fe38SFelten, Lothar * 9dc92cd0cSGuenter Roeck * INA220: 10dc92cd0cSGuenter Roeck * Bi-Directional Current/Power Monitor with I2C Interface 1149dc2fb0SAlexander A. Klimov * Datasheet: https://www.ti.com/product/ina220 12dc92cd0cSGuenter Roeck * 13f7c2fe38SFelten, Lothar * INA226: 14f7c2fe38SFelten, Lothar * Bi-Directional Current/Power Monitor with I2C Interface 1549dc2fb0SAlexander A. Klimov * Datasheet: https://www.ti.com/product/ina226 16f7c2fe38SFelten, Lothar * 17dc92cd0cSGuenter Roeck * INA230: 18dc92cd0cSGuenter Roeck * Bi-directional Current/Power Monitor with I2C Interface 1949dc2fb0SAlexander A. Klimov * Datasheet: https://www.ti.com/product/ina230 20dc92cd0cSGuenter Roeck * 213ad86700SLothar Felten * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com> 22f7c2fe38SFelten, Lothar * Thanks to Jan Volkering 23f7c2fe38SFelten, Lothar */ 24f7c2fe38SFelten, Lothar 25232177a3SGuenter Roeck #include <linux/bitfield.h> 26232177a3SGuenter Roeck #include <linux/bits.h> 279e60bb81SGuenter Roeck #include <linux/delay.h> 28814db9f1SGuenter Roeck #include <linux/device.h> 29f7c2fe38SFelten, Lothar #include <linux/err.h> 30f7c2fe38SFelten, Lothar #include <linux/hwmon.h> 319e60bb81SGuenter Roeck #include <linux/i2c.h> 329e60bb81SGuenter Roeck #include <linux/init.h> 339e60bb81SGuenter Roeck #include <linux/kernel.h> 349e60bb81SGuenter Roeck #include <linux/module.h> 3561a4a841SGuenter Roeck #include <linux/property.h> 36a0de56c8SMarc Titinger #include <linux/regmap.h> 379e60bb81SGuenter Roeck #include <linux/slab.h> 38814db9f1SGuenter Roeck #include <linux/sysfs.h> 399e60bb81SGuenter Roeck #include <linux/util_macros.h> 40f7c2fe38SFelten, Lothar 41f7c2fe38SFelten, Lothar /* common register definitions */ 42f7c2fe38SFelten, Lothar #define INA2XX_CONFIG 0x00 43f7c2fe38SFelten, Lothar #define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */ 44f7c2fe38SFelten, Lothar #define INA2XX_BUS_VOLTAGE 0x02 /* readonly */ 45f7c2fe38SFelten, Lothar #define INA2XX_POWER 0x03 /* readonly */ 46f7c2fe38SFelten, Lothar #define INA2XX_CURRENT 0x04 /* readonly */ 47f7c2fe38SFelten, Lothar #define INA2XX_CALIBRATION 0x05 48f7c2fe38SFelten, Lothar 49f7c2fe38SFelten, Lothar /* INA226 register definitions */ 50f7c2fe38SFelten, Lothar #define INA226_MASK_ENABLE 0x06 51f7c2fe38SFelten, Lothar #define INA226_ALERT_LIMIT 0x07 52f7c2fe38SFelten, Lothar #define INA226_DIE_ID 0xFF 53f7c2fe38SFelten, Lothar 54f7c2fe38SFelten, Lothar #define INA2XX_MAX_REGISTERS 8 55f7c2fe38SFelten, Lothar 56f7c2fe38SFelten, Lothar /* settings - depend on use case */ 57f7c2fe38SFelten, Lothar #define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ 58f7c2fe38SFelten, Lothar #define INA226_CONFIG_DEFAULT 0x4527 /* averages=16 */ 59f7c2fe38SFelten, Lothar 60f7c2fe38SFelten, Lothar /* worst case is 68.10 ms (~14.6Hz, ina219) */ 61f7c2fe38SFelten, Lothar #define INA2XX_CONVERSION_RATE 15 62509416a8SBartosz Golaszewski #define INA2XX_MAX_DELAY 69 /* worst case delay in ms */ 63509416a8SBartosz Golaszewski 64509416a8SBartosz Golaszewski #define INA2XX_RSHUNT_DEFAULT 10000 65f7c2fe38SFelten, Lothar 6672a87a47SBartosz Golaszewski /* bit mask for reading the averaging setting in the configuration register */ 67232177a3SGuenter Roeck #define INA226_AVG_RD_MASK GENMASK(11, 9) 6872a87a47SBartosz Golaszewski 69232177a3SGuenter Roeck #define INA226_READ_AVG(reg) FIELD_GET(INA226_AVG_RD_MASK, reg) 7072a87a47SBartosz Golaszewski 71aa7d1763SGuenter Roeck #define INA226_ALERT_LATCH_ENABLE BIT(0) 7251c6fa32SGuenter Roeck #define INA226_ALERT_POLARITY BIT(1) 73ec5d234fSAmna Waseem 745a56a39bSAlex Qiu /* bit number of alert functions in Mask/Enable Register */ 75232177a3SGuenter Roeck #define INA226_SHUNT_OVER_VOLTAGE_MASK BIT(15) 76232177a3SGuenter Roeck #define INA226_SHUNT_UNDER_VOLTAGE_MASK BIT(14) 77232177a3SGuenter Roeck #define INA226_BUS_OVER_VOLTAGE_MASK BIT(13) 78232177a3SGuenter Roeck #define INA226_BUS_UNDER_VOLTAGE_MASK BIT(12) 79232177a3SGuenter Roeck #define INA226_POWER_OVER_LIMIT_MASK BIT(11) 805a56a39bSAlex Qiu 815a56a39bSAlex Qiu /* bit mask for alert config bits of Mask/Enable Register */ 82232177a3SGuenter Roeck #define INA226_ALERT_CONFIG_MASK GENMASK(15, 10) 835a56a39bSAlex Qiu #define INA226_ALERT_FUNCTION_FLAG BIT(4) 845a56a39bSAlex Qiu 8572a87a47SBartosz Golaszewski /* 8672a87a47SBartosz Golaszewski * Both bus voltage and shunt voltage conversion times for ina226 are set 8772a87a47SBartosz Golaszewski * to 0b0100 on POR, which translates to 2200 microseconds in total. 8872a87a47SBartosz Golaszewski */ 8972a87a47SBartosz Golaszewski #define INA226_TOTAL_CONV_TIME_DEFAULT 2200 9072a87a47SBartosz Golaszewski 91bb25cdc2SGuenter Roeck static bool ina2xx_writeable_reg(struct device *dev, unsigned int reg) 92bb25cdc2SGuenter Roeck { 93bb25cdc2SGuenter Roeck switch (reg) { 94bb25cdc2SGuenter Roeck case INA2XX_CONFIG: 95bb25cdc2SGuenter Roeck case INA2XX_CALIBRATION: 96bb25cdc2SGuenter Roeck case INA226_MASK_ENABLE: 97bb25cdc2SGuenter Roeck case INA226_ALERT_LIMIT: 98bb25cdc2SGuenter Roeck return true; 99bb25cdc2SGuenter Roeck default: 100bb25cdc2SGuenter Roeck return false; 101bb25cdc2SGuenter Roeck } 102bb25cdc2SGuenter Roeck } 103bb25cdc2SGuenter Roeck 104bb25cdc2SGuenter Roeck static bool ina2xx_volatile_reg(struct device *dev, unsigned int reg) 105bb25cdc2SGuenter Roeck { 106bb25cdc2SGuenter Roeck switch (reg) { 107bb25cdc2SGuenter Roeck case INA2XX_SHUNT_VOLTAGE: 108bb25cdc2SGuenter Roeck case INA2XX_BUS_VOLTAGE: 109bb25cdc2SGuenter Roeck case INA2XX_POWER: 110bb25cdc2SGuenter Roeck case INA2XX_CURRENT: 111bb25cdc2SGuenter Roeck return true; 112bb25cdc2SGuenter Roeck default: 113bb25cdc2SGuenter Roeck return false; 114bb25cdc2SGuenter Roeck } 115bb25cdc2SGuenter Roeck } 116bb25cdc2SGuenter Roeck 1172bb47652SGuenter Roeck static const struct regmap_config ina2xx_regmap_config = { 118a0de56c8SMarc Titinger .reg_bits = 8, 119a0de56c8SMarc Titinger .val_bits = 16, 120bb25cdc2SGuenter Roeck .use_single_write = true, 121bb25cdc2SGuenter Roeck .use_single_read = true, 1222bb47652SGuenter Roeck .max_register = INA2XX_MAX_REGISTERS, 123bb25cdc2SGuenter Roeck .cache_type = REGCACHE_MAPLE, 124bb25cdc2SGuenter Roeck .volatile_reg = ina2xx_volatile_reg, 125bb25cdc2SGuenter Roeck .writeable_reg = ina2xx_writeable_reg, 126a0de56c8SMarc Titinger }; 127a0de56c8SMarc Titinger 128f7c2fe38SFelten, Lothar enum ina2xx_ids { ina219, ina226 }; 129f7c2fe38SFelten, Lothar 1306106db25SGuenter Roeck struct ina2xx_config { 1316106db25SGuenter Roeck u16 config_default; 1325d389b12SMaciej Purski int calibration_value; 1336106db25SGuenter Roeck int shunt_div; 1346106db25SGuenter Roeck int bus_voltage_shift; 1356106db25SGuenter Roeck int bus_voltage_lsb; /* uV */ 1365d389b12SMaciej Purski int power_lsb_factor; 1376106db25SGuenter Roeck }; 1386106db25SGuenter Roeck 139f7c2fe38SFelten, Lothar struct ina2xx_data { 1406106db25SGuenter Roeck const struct ina2xx_config *config; 14151c6fa32SGuenter Roeck enum ina2xx_ids chip; 142f7c2fe38SFelten, Lothar 143509416a8SBartosz Golaszewski long rshunt; 1445d389b12SMaciej Purski long current_lsb_uA; 1455d389b12SMaciej Purski long power_lsb_uW; 146a0de56c8SMarc Titinger struct mutex config_lock; 147a0de56c8SMarc Titinger struct regmap *regmap; 148f7c2fe38SFelten, Lothar }; 149f7c2fe38SFelten, Lothar 1506106db25SGuenter Roeck static const struct ina2xx_config ina2xx_config[] = { 1516106db25SGuenter Roeck [ina219] = { 1526106db25SGuenter Roeck .config_default = INA219_CONFIG_DEFAULT, 1535d389b12SMaciej Purski .calibration_value = 4096, 1546106db25SGuenter Roeck .shunt_div = 100, 1556106db25SGuenter Roeck .bus_voltage_shift = 3, 1566106db25SGuenter Roeck .bus_voltage_lsb = 4000, 1575d389b12SMaciej Purski .power_lsb_factor = 20, 1586106db25SGuenter Roeck }, 1596106db25SGuenter Roeck [ina226] = { 1606106db25SGuenter Roeck .config_default = INA226_CONFIG_DEFAULT, 1615d389b12SMaciej Purski .calibration_value = 2048, 1626106db25SGuenter Roeck .shunt_div = 400, 1636106db25SGuenter Roeck .bus_voltage_shift = 0, 1646106db25SGuenter Roeck .bus_voltage_lsb = 1250, 1655d389b12SMaciej Purski .power_lsb_factor = 25, 1666106db25SGuenter Roeck }, 1676106db25SGuenter Roeck }; 1686106db25SGuenter Roeck 16972a87a47SBartosz Golaszewski /* 17072a87a47SBartosz Golaszewski * Available averaging rates for ina226. The indices correspond with 17172a87a47SBartosz Golaszewski * the bit values expected by the chip (according to the ina226 datasheet, 17272a87a47SBartosz Golaszewski * table 3 AVG bit settings, found at 17349dc2fb0SAlexander A. Klimov * https://www.ti.com/lit/ds/symlink/ina226.pdf. 17472a87a47SBartosz Golaszewski */ 17572a87a47SBartosz Golaszewski static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; 17672a87a47SBartosz Golaszewski 17772a87a47SBartosz Golaszewski static int ina226_reg_to_interval(u16 config) 17872a87a47SBartosz Golaszewski { 17972a87a47SBartosz Golaszewski int avg = ina226_avg_tab[INA226_READ_AVG(config)]; 18072a87a47SBartosz Golaszewski 18172a87a47SBartosz Golaszewski /* 18272a87a47SBartosz Golaszewski * Multiply the total conversion time by the number of averages. 18372a87a47SBartosz Golaszewski * Return the result in milliseconds. 18472a87a47SBartosz Golaszewski */ 18572a87a47SBartosz Golaszewski return DIV_ROUND_CLOSEST(avg * INA226_TOTAL_CONV_TIME_DEFAULT, 1000); 18672a87a47SBartosz Golaszewski } 18772a87a47SBartosz Golaszewski 188a0de56c8SMarc Titinger /* 189a0de56c8SMarc Titinger * Return the new, shifted AVG field value of CONFIG register, 190a0de56c8SMarc Titinger * to use with regmap_update_bits 191a0de56c8SMarc Titinger */ 192814db9f1SGuenter Roeck static u16 ina226_interval_to_reg(long interval) 19372a87a47SBartosz Golaszewski { 19472a87a47SBartosz Golaszewski int avg, avg_bits; 19572a87a47SBartosz Golaszewski 196ab7fbee4SGuenter Roeck /* 197ab7fbee4SGuenter Roeck * The maximum supported interval is 1,024 * (2 * 8.244ms) ~= 16.8s. 198ab7fbee4SGuenter Roeck * Clamp to 32 seconds before calculations to avoid overflows. 199ab7fbee4SGuenter Roeck */ 200ab7fbee4SGuenter Roeck interval = clamp_val(interval, 0, 32000); 201ab7fbee4SGuenter Roeck 20272a87a47SBartosz Golaszewski avg = DIV_ROUND_CLOSEST(interval * 1000, 20372a87a47SBartosz Golaszewski INA226_TOTAL_CONV_TIME_DEFAULT); 204d38df34eSBartosz Golaszewski avg_bits = find_closest(avg, ina226_avg_tab, 205d38df34eSBartosz Golaszewski ARRAY_SIZE(ina226_avg_tab)); 20672a87a47SBartosz Golaszewski 207232177a3SGuenter Roeck return FIELD_PREP(INA226_AVG_RD_MASK, avg_bits); 20872a87a47SBartosz Golaszewski } 20972a87a47SBartosz Golaszewski 210c263d916SGuenter Roeck static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, 211c263d916SGuenter Roeck unsigned int regval) 212c263d916SGuenter Roeck { 213c263d916SGuenter Roeck int val; 214c263d916SGuenter Roeck 215c263d916SGuenter Roeck switch (reg) { 216c263d916SGuenter Roeck case INA2XX_SHUNT_VOLTAGE: 217c263d916SGuenter Roeck /* signed register */ 218c263d916SGuenter Roeck val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div); 219c263d916SGuenter Roeck break; 220c263d916SGuenter Roeck case INA2XX_BUS_VOLTAGE: 221c263d916SGuenter Roeck val = (regval >> data->config->bus_voltage_shift) * 222c263d916SGuenter Roeck data->config->bus_voltage_lsb; 223c263d916SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 1000); 224c263d916SGuenter Roeck break; 225c263d916SGuenter Roeck case INA2XX_POWER: 226c263d916SGuenter Roeck val = regval * data->power_lsb_uW; 227c263d916SGuenter Roeck break; 228c263d916SGuenter Roeck case INA2XX_CURRENT: 229c263d916SGuenter Roeck /* signed register, result in mA */ 230c263d916SGuenter Roeck val = (s16)regval * data->current_lsb_uA; 231c263d916SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 1000); 232c263d916SGuenter Roeck break; 233c263d916SGuenter Roeck case INA2XX_CALIBRATION: 234c263d916SGuenter Roeck val = regval; 235c263d916SGuenter Roeck break; 236c263d916SGuenter Roeck default: 237c263d916SGuenter Roeck /* programmer goofed */ 238c263d916SGuenter Roeck WARN_ON_ONCE(1); 239c263d916SGuenter Roeck val = 0; 240c263d916SGuenter Roeck break; 241c263d916SGuenter Roeck } 242c263d916SGuenter Roeck 243c263d916SGuenter Roeck return val; 244c263d916SGuenter Roeck } 245c263d916SGuenter Roeck 246814db9f1SGuenter Roeck /* 247814db9f1SGuenter Roeck * Read and convert register value from chip. If the register value is 0, 248814db9f1SGuenter Roeck * check if the chip has been power cycled or reset. If so, re-initialize it. 249814db9f1SGuenter Roeck */ 250814db9f1SGuenter Roeck static int ina2xx_read_init(struct device *dev, int reg, long *val) 251f7c2fe38SFelten, Lothar { 252468bf0e3SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 253d491e781SGuenter Roeck struct regmap *regmap = data->regmap; 254814db9f1SGuenter Roeck unsigned int regval; 255a0de56c8SMarc Titinger int ret, retry; 256509416a8SBartosz Golaszewski 257509416a8SBartosz Golaszewski for (retry = 5; retry; retry--) { 258814db9f1SGuenter Roeck ret = regmap_read(regmap, reg, ®val); 259a0de56c8SMarc Titinger if (ret < 0) 260a0de56c8SMarc Titinger return ret; 261a0de56c8SMarc Titinger 262509416a8SBartosz Golaszewski /* 263509416a8SBartosz Golaszewski * If the current value in the calibration register is 0, the 264509416a8SBartosz Golaszewski * power and current registers will also remain at 0. In case 265509416a8SBartosz Golaszewski * the chip has been reset let's check the calibration 266509416a8SBartosz Golaszewski * register and reinitialize if needed. 267a0de56c8SMarc Titinger * We do that extra read of the calibration register if there 268a0de56c8SMarc Titinger * is some hint of a chip reset. 269509416a8SBartosz Golaszewski */ 270814db9f1SGuenter Roeck if (regval == 0) { 271a0de56c8SMarc Titinger unsigned int cal; 272a0de56c8SMarc Titinger 273bb25cdc2SGuenter Roeck ret = regmap_read_bypassed(regmap, INA2XX_CALIBRATION, &cal); 274a0de56c8SMarc Titinger if (ret < 0) 275a0de56c8SMarc Titinger return ret; 276a0de56c8SMarc Titinger 277a0de56c8SMarc Titinger if (cal == 0) { 278509416a8SBartosz Golaszewski dev_warn(dev, "chip not calibrated, reinitializing\n"); 279509416a8SBartosz Golaszewski 280bb25cdc2SGuenter Roeck regcache_mark_dirty(regmap); 281bb25cdc2SGuenter Roeck regcache_sync(regmap); 282bb25cdc2SGuenter Roeck 283509416a8SBartosz Golaszewski /* 284a0de56c8SMarc Titinger * Let's make sure the power and current 285a0de56c8SMarc Titinger * registers have been updated before trying 286a0de56c8SMarc Titinger * again. 287509416a8SBartosz Golaszewski */ 288509416a8SBartosz Golaszewski msleep(INA2XX_MAX_DELAY); 289509416a8SBartosz Golaszewski continue; 290509416a8SBartosz Golaszewski } 291a0de56c8SMarc Titinger } 292814db9f1SGuenter Roeck *val = ina2xx_get_value(data, reg, regval); 293509416a8SBartosz Golaszewski return 0; 294509416a8SBartosz Golaszewski } 295509416a8SBartosz Golaszewski 296509416a8SBartosz Golaszewski /* 297509416a8SBartosz Golaszewski * If we're here then although all write operations succeeded, the 298509416a8SBartosz Golaszewski * chip still returns 0 in the calibration register. Nothing more we 299509416a8SBartosz Golaszewski * can do here. 300509416a8SBartosz Golaszewski */ 301509416a8SBartosz Golaszewski dev_err(dev, "unable to reinitialize the chip\n"); 302509416a8SBartosz Golaszewski return -ENODEV; 303509416a8SBartosz Golaszewski } 304509416a8SBartosz Golaszewski 3055a56a39bSAlex Qiu /* 3065a56a39bSAlex Qiu * Turns alert limit values into register values. 3075a56a39bSAlex Qiu * Opposite of the formula in ina2xx_get_value(). 3085a56a39bSAlex Qiu */ 309*4d5c2d98SGuenter Roeck static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val) 3105a56a39bSAlex Qiu { 3119965ebd1SGuenter Roeck switch (reg) { 3129965ebd1SGuenter Roeck case INA2XX_SHUNT_VOLTAGE: 313ab7fbee4SGuenter Roeck val = clamp_val(val, 0, SHRT_MAX * data->config->shunt_div); 3145a56a39bSAlex Qiu val *= data->config->shunt_div; 315ab7fbee4SGuenter Roeck return clamp_val(val, 0, SHRT_MAX); 3169965ebd1SGuenter Roeck case INA2XX_BUS_VOLTAGE: 317ab7fbee4SGuenter Roeck val = clamp_val(val, 0, 200000); 3185a56a39bSAlex Qiu val = (val * 1000) << data->config->bus_voltage_shift; 3195a56a39bSAlex Qiu val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb); 320ab7fbee4SGuenter Roeck return clamp_val(val, 0, USHRT_MAX); 3219965ebd1SGuenter Roeck case INA2XX_POWER: 322ab7fbee4SGuenter Roeck val = clamp_val(val, 0, UINT_MAX - data->power_lsb_uW); 3235a56a39bSAlex Qiu val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW); 3245a56a39bSAlex Qiu return clamp_val(val, 0, USHRT_MAX); 325*4d5c2d98SGuenter Roeck case INA2XX_CURRENT: 326*4d5c2d98SGuenter Roeck val = clamp_val(val, INT_MIN / 1000, INT_MAX / 1000); 327*4d5c2d98SGuenter Roeck /* signed register, result in mA */ 328*4d5c2d98SGuenter Roeck val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb_uA); 329*4d5c2d98SGuenter Roeck return clamp_val(val, SHRT_MIN, SHRT_MAX); 3305a56a39bSAlex Qiu default: 3315a56a39bSAlex Qiu /* programmer goofed */ 3325a56a39bSAlex Qiu WARN_ON_ONCE(1); 3335a56a39bSAlex Qiu return 0; 3345a56a39bSAlex Qiu } 3355a56a39bSAlex Qiu } 3365a56a39bSAlex Qiu 337814db9f1SGuenter Roeck static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg, long *val) 3385a56a39bSAlex Qiu { 339d491e781SGuenter Roeck struct regmap *regmap = data->regmap; 3405a56a39bSAlex Qiu int regval; 3415a56a39bSAlex Qiu int ret; 3425a56a39bSAlex Qiu 3435a56a39bSAlex Qiu mutex_lock(&data->config_lock); 344d491e781SGuenter Roeck ret = regmap_read(regmap, INA226_MASK_ENABLE, ®val); 3455a56a39bSAlex Qiu if (ret) 3465a56a39bSAlex Qiu goto abort; 3475a56a39bSAlex Qiu 348814db9f1SGuenter Roeck if (regval & mask) { 349d491e781SGuenter Roeck ret = regmap_read(regmap, INA226_ALERT_LIMIT, ®val); 3505a56a39bSAlex Qiu if (ret) 3515a56a39bSAlex Qiu goto abort; 352814db9f1SGuenter Roeck *val = ina2xx_get_value(data, reg, regval); 353814db9f1SGuenter Roeck } else { 354814db9f1SGuenter Roeck *val = 0; 3555a56a39bSAlex Qiu } 3565a56a39bSAlex Qiu abort: 3575a56a39bSAlex Qiu mutex_unlock(&data->config_lock); 3585a56a39bSAlex Qiu return ret; 3595a56a39bSAlex Qiu } 3605a56a39bSAlex Qiu 3619965ebd1SGuenter Roeck static int ina226_alert_limit_write(struct ina2xx_data *data, u32 mask, int reg, long val) 3625a56a39bSAlex Qiu { 363d491e781SGuenter Roeck struct regmap *regmap = data->regmap; 3645a56a39bSAlex Qiu int ret; 3655a56a39bSAlex Qiu 366814db9f1SGuenter Roeck if (val < 0) 367814db9f1SGuenter Roeck return -EINVAL; 3685a56a39bSAlex Qiu 3695a56a39bSAlex Qiu /* 3705a56a39bSAlex Qiu * Clear all alerts first to avoid accidentally triggering ALERT pin 3715a56a39bSAlex Qiu * due to register write sequence. Then, only enable the alert 3725a56a39bSAlex Qiu * if the value is non-zero. 3735a56a39bSAlex Qiu */ 3745a56a39bSAlex Qiu mutex_lock(&data->config_lock); 375d491e781SGuenter Roeck ret = regmap_update_bits(regmap, INA226_MASK_ENABLE, 3765a56a39bSAlex Qiu INA226_ALERT_CONFIG_MASK, 0); 3775a56a39bSAlex Qiu if (ret < 0) 3785a56a39bSAlex Qiu goto abort; 3795a56a39bSAlex Qiu 380d491e781SGuenter Roeck ret = regmap_write(regmap, INA226_ALERT_LIMIT, 3819965ebd1SGuenter Roeck ina226_alert_to_reg(data, reg, val)); 3825a56a39bSAlex Qiu if (ret < 0) 3835a56a39bSAlex Qiu goto abort; 3845a56a39bSAlex Qiu 385814db9f1SGuenter Roeck if (val) 386d491e781SGuenter Roeck ret = regmap_update_bits(regmap, INA226_MASK_ENABLE, 387814db9f1SGuenter Roeck INA226_ALERT_CONFIG_MASK, mask); 3885a56a39bSAlex Qiu abort: 3895a56a39bSAlex Qiu mutex_unlock(&data->config_lock); 3905a56a39bSAlex Qiu return ret; 3915a56a39bSAlex Qiu } 3925a56a39bSAlex Qiu 393814db9f1SGuenter Roeck static int ina2xx_chip_read(struct device *dev, u32 attr, long *val) 3945a56a39bSAlex Qiu { 3955a56a39bSAlex Qiu struct ina2xx_data *data = dev_get_drvdata(dev); 396814db9f1SGuenter Roeck u32 regval; 3975a56a39bSAlex Qiu int ret; 3985a56a39bSAlex Qiu 399814db9f1SGuenter Roeck switch (attr) { 400814db9f1SGuenter Roeck case hwmon_chip_update_interval: 401814db9f1SGuenter Roeck ret = regmap_read(data->regmap, INA2XX_CONFIG, ®val); 4025a56a39bSAlex Qiu if (ret) 4035a56a39bSAlex Qiu return ret; 4045a56a39bSAlex Qiu 405814db9f1SGuenter Roeck *val = ina226_reg_to_interval(regval); 406814db9f1SGuenter Roeck break; 407814db9f1SGuenter Roeck default: 408814db9f1SGuenter Roeck return -EOPNOTSUPP; 4095a56a39bSAlex Qiu } 410814db9f1SGuenter Roeck return 0; 411814db9f1SGuenter Roeck } 412814db9f1SGuenter Roeck 413814db9f1SGuenter Roeck static int ina226_alert_read(struct regmap *regmap, u32 mask, long *val) 414814db9f1SGuenter Roeck { 415814db9f1SGuenter Roeck unsigned int regval; 416814db9f1SGuenter Roeck int ret; 417814db9f1SGuenter Roeck 418814db9f1SGuenter Roeck ret = regmap_read_bypassed(regmap, INA226_MASK_ENABLE, ®val); 419814db9f1SGuenter Roeck if (ret) 420814db9f1SGuenter Roeck return ret; 421814db9f1SGuenter Roeck 422814db9f1SGuenter Roeck *val = (regval & mask) && (regval & INA226_ALERT_FUNCTION_FLAG); 423814db9f1SGuenter Roeck 424814db9f1SGuenter Roeck return 0; 425814db9f1SGuenter Roeck } 426814db9f1SGuenter Roeck 427814db9f1SGuenter Roeck static int ina2xx_in_read(struct device *dev, u32 attr, int channel, long *val) 428814db9f1SGuenter Roeck { 429814db9f1SGuenter Roeck int voltage_reg = channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE; 430814db9f1SGuenter Roeck u32 under_voltage_mask = channel ? INA226_BUS_UNDER_VOLTAGE_MASK 431814db9f1SGuenter Roeck : INA226_SHUNT_UNDER_VOLTAGE_MASK; 432814db9f1SGuenter Roeck u32 over_voltage_mask = channel ? INA226_BUS_OVER_VOLTAGE_MASK 433814db9f1SGuenter Roeck : INA226_SHUNT_OVER_VOLTAGE_MASK; 434814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 435814db9f1SGuenter Roeck struct regmap *regmap = data->regmap; 436814db9f1SGuenter Roeck unsigned int regval; 437814db9f1SGuenter Roeck int ret; 438814db9f1SGuenter Roeck 439814db9f1SGuenter Roeck switch (attr) { 440814db9f1SGuenter Roeck case hwmon_in_input: 441814db9f1SGuenter Roeck ret = regmap_read(regmap, voltage_reg, ®val); 442814db9f1SGuenter Roeck if (ret) 443814db9f1SGuenter Roeck return ret; 444814db9f1SGuenter Roeck *val = ina2xx_get_value(data, voltage_reg, regval); 445814db9f1SGuenter Roeck break; 446814db9f1SGuenter Roeck case hwmon_in_lcrit: 447814db9f1SGuenter Roeck return ina226_alert_limit_read(data, under_voltage_mask, 448814db9f1SGuenter Roeck voltage_reg, val); 449814db9f1SGuenter Roeck case hwmon_in_crit: 450814db9f1SGuenter Roeck return ina226_alert_limit_read(data, over_voltage_mask, 451814db9f1SGuenter Roeck voltage_reg, val); 452814db9f1SGuenter Roeck case hwmon_in_lcrit_alarm: 453814db9f1SGuenter Roeck return ina226_alert_read(regmap, under_voltage_mask, val); 454814db9f1SGuenter Roeck case hwmon_in_crit_alarm: 455814db9f1SGuenter Roeck return ina226_alert_read(regmap, over_voltage_mask, val); 456814db9f1SGuenter Roeck default: 457814db9f1SGuenter Roeck return -EOPNOTSUPP; 458814db9f1SGuenter Roeck } 459814db9f1SGuenter Roeck return 0; 460814db9f1SGuenter Roeck } 461814db9f1SGuenter Roeck 462814db9f1SGuenter Roeck static int ina2xx_power_read(struct device *dev, u32 attr, long *val) 463814db9f1SGuenter Roeck { 464814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 465814db9f1SGuenter Roeck 466814db9f1SGuenter Roeck switch (attr) { 467814db9f1SGuenter Roeck case hwmon_power_input: 468814db9f1SGuenter Roeck return ina2xx_read_init(dev, INA2XX_POWER, val); 469814db9f1SGuenter Roeck case hwmon_power_crit: 470814db9f1SGuenter Roeck return ina226_alert_limit_read(data, INA226_POWER_OVER_LIMIT_MASK, 471814db9f1SGuenter Roeck INA2XX_POWER, val); 472814db9f1SGuenter Roeck case hwmon_power_crit_alarm: 473814db9f1SGuenter Roeck return ina226_alert_read(data->regmap, INA226_POWER_OVER_LIMIT_MASK, val); 474814db9f1SGuenter Roeck default: 475814db9f1SGuenter Roeck return -EOPNOTSUPP; 476814db9f1SGuenter Roeck } 477814db9f1SGuenter Roeck } 478814db9f1SGuenter Roeck 479814db9f1SGuenter Roeck static int ina2xx_curr_read(struct device *dev, u32 attr, long *val) 480814db9f1SGuenter Roeck { 481*4d5c2d98SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 482*4d5c2d98SGuenter Roeck struct regmap *regmap = data->regmap; 483*4d5c2d98SGuenter Roeck 484*4d5c2d98SGuenter Roeck /* 485*4d5c2d98SGuenter Roeck * While the chips supported by this driver do not directly support 486*4d5c2d98SGuenter Roeck * current limits, they do support setting shunt voltage limits. 487*4d5c2d98SGuenter Roeck * The shunt voltage divided by the shunt resistor value is the current. 488*4d5c2d98SGuenter Roeck * On top of that, calibration values are set such that in the shunt 489*4d5c2d98SGuenter Roeck * voltage register and the current register report the same values. 490*4d5c2d98SGuenter Roeck * That means we can report and configure current limits based on shunt 491*4d5c2d98SGuenter Roeck * voltage limits. 492*4d5c2d98SGuenter Roeck */ 493814db9f1SGuenter Roeck switch (attr) { 494814db9f1SGuenter Roeck case hwmon_curr_input: 495814db9f1SGuenter Roeck return ina2xx_read_init(dev, INA2XX_CURRENT, val); 496*4d5c2d98SGuenter Roeck case hwmon_curr_lcrit: 497*4d5c2d98SGuenter Roeck return ina226_alert_limit_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK, 498*4d5c2d98SGuenter Roeck INA2XX_CURRENT, val); 499*4d5c2d98SGuenter Roeck case hwmon_curr_crit: 500*4d5c2d98SGuenter Roeck return ina226_alert_limit_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK, 501*4d5c2d98SGuenter Roeck INA2XX_CURRENT, val); 502*4d5c2d98SGuenter Roeck case hwmon_curr_lcrit_alarm: 503*4d5c2d98SGuenter Roeck return ina226_alert_read(regmap, INA226_SHUNT_UNDER_VOLTAGE_MASK, val); 504*4d5c2d98SGuenter Roeck case hwmon_curr_crit_alarm: 505*4d5c2d98SGuenter Roeck return ina226_alert_read(regmap, INA226_SHUNT_OVER_VOLTAGE_MASK, val); 506814db9f1SGuenter Roeck default: 507814db9f1SGuenter Roeck return -EOPNOTSUPP; 508814db9f1SGuenter Roeck } 509814db9f1SGuenter Roeck } 510814db9f1SGuenter Roeck 511814db9f1SGuenter Roeck static int ina2xx_read(struct device *dev, enum hwmon_sensor_types type, 512814db9f1SGuenter Roeck u32 attr, int channel, long *val) 513814db9f1SGuenter Roeck { 514814db9f1SGuenter Roeck switch (type) { 515814db9f1SGuenter Roeck case hwmon_chip: 516814db9f1SGuenter Roeck return ina2xx_chip_read(dev, attr, val); 517814db9f1SGuenter Roeck case hwmon_in: 518814db9f1SGuenter Roeck return ina2xx_in_read(dev, attr, channel, val); 519814db9f1SGuenter Roeck case hwmon_power: 520814db9f1SGuenter Roeck return ina2xx_power_read(dev, attr, val); 521814db9f1SGuenter Roeck case hwmon_curr: 522814db9f1SGuenter Roeck return ina2xx_curr_read(dev, attr, val); 523814db9f1SGuenter Roeck default: 524814db9f1SGuenter Roeck return -EOPNOTSUPP; 525814db9f1SGuenter Roeck } 526814db9f1SGuenter Roeck } 527814db9f1SGuenter Roeck 528814db9f1SGuenter Roeck static int ina2xx_chip_write(struct device *dev, u32 attr, long val) 529814db9f1SGuenter Roeck { 530814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 531814db9f1SGuenter Roeck 532814db9f1SGuenter Roeck switch (attr) { 533814db9f1SGuenter Roeck case hwmon_chip_update_interval: 534814db9f1SGuenter Roeck return regmap_update_bits(data->regmap, INA2XX_CONFIG, 535814db9f1SGuenter Roeck INA226_AVG_RD_MASK, 536814db9f1SGuenter Roeck ina226_interval_to_reg(val)); 537814db9f1SGuenter Roeck default: 538814db9f1SGuenter Roeck return -EOPNOTSUPP; 539814db9f1SGuenter Roeck } 540814db9f1SGuenter Roeck } 541814db9f1SGuenter Roeck 542814db9f1SGuenter Roeck static int ina2xx_in_write(struct device *dev, u32 attr, int channel, long val) 543814db9f1SGuenter Roeck { 544814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 545814db9f1SGuenter Roeck 546814db9f1SGuenter Roeck switch (attr) { 547814db9f1SGuenter Roeck case hwmon_in_lcrit: 548814db9f1SGuenter Roeck return ina226_alert_limit_write(data, 549814db9f1SGuenter Roeck channel ? INA226_BUS_UNDER_VOLTAGE_MASK : INA226_SHUNT_UNDER_VOLTAGE_MASK, 5509965ebd1SGuenter Roeck channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE, 551814db9f1SGuenter Roeck val); 552814db9f1SGuenter Roeck case hwmon_in_crit: 553814db9f1SGuenter Roeck return ina226_alert_limit_write(data, 554814db9f1SGuenter Roeck channel ? INA226_BUS_OVER_VOLTAGE_MASK : INA226_SHUNT_OVER_VOLTAGE_MASK, 5559965ebd1SGuenter Roeck channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE, 556814db9f1SGuenter Roeck val); 557814db9f1SGuenter Roeck default: 558814db9f1SGuenter Roeck return -EOPNOTSUPP; 559814db9f1SGuenter Roeck } 560814db9f1SGuenter Roeck return 0; 561814db9f1SGuenter Roeck } 562814db9f1SGuenter Roeck 563814db9f1SGuenter Roeck static int ina2xx_power_write(struct device *dev, u32 attr, long val) 564814db9f1SGuenter Roeck { 565814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 566814db9f1SGuenter Roeck 567814db9f1SGuenter Roeck switch (attr) { 568814db9f1SGuenter Roeck case hwmon_power_crit: 5699965ebd1SGuenter Roeck return ina226_alert_limit_write(data, INA226_POWER_OVER_LIMIT_MASK, 5709965ebd1SGuenter Roeck INA2XX_POWER, val); 571814db9f1SGuenter Roeck default: 572814db9f1SGuenter Roeck return -EOPNOTSUPP; 573814db9f1SGuenter Roeck } 574814db9f1SGuenter Roeck return 0; 575814db9f1SGuenter Roeck } 576814db9f1SGuenter Roeck 577*4d5c2d98SGuenter Roeck static int ina2xx_curr_write(struct device *dev, u32 attr, long val) 578*4d5c2d98SGuenter Roeck { 579*4d5c2d98SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 580*4d5c2d98SGuenter Roeck 581*4d5c2d98SGuenter Roeck switch (attr) { 582*4d5c2d98SGuenter Roeck case hwmon_curr_lcrit: 583*4d5c2d98SGuenter Roeck return ina226_alert_limit_write(data, INA226_SHUNT_UNDER_VOLTAGE_MASK, 584*4d5c2d98SGuenter Roeck INA2XX_CURRENT, val); 585*4d5c2d98SGuenter Roeck case hwmon_curr_crit: 586*4d5c2d98SGuenter Roeck return ina226_alert_limit_write(data, INA226_SHUNT_OVER_VOLTAGE_MASK, 587*4d5c2d98SGuenter Roeck INA2XX_CURRENT, val); 588*4d5c2d98SGuenter Roeck default: 589*4d5c2d98SGuenter Roeck return -EOPNOTSUPP; 590*4d5c2d98SGuenter Roeck } 591*4d5c2d98SGuenter Roeck return 0; 592*4d5c2d98SGuenter Roeck } 593*4d5c2d98SGuenter Roeck 594814db9f1SGuenter Roeck static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type, 595814db9f1SGuenter Roeck u32 attr, int channel, long val) 596814db9f1SGuenter Roeck { 597814db9f1SGuenter Roeck switch (type) { 598814db9f1SGuenter Roeck case hwmon_chip: 599814db9f1SGuenter Roeck return ina2xx_chip_write(dev, attr, val); 600814db9f1SGuenter Roeck case hwmon_in: 601814db9f1SGuenter Roeck return ina2xx_in_write(dev, attr, channel, val); 602814db9f1SGuenter Roeck case hwmon_power: 603814db9f1SGuenter Roeck return ina2xx_power_write(dev, attr, val); 604*4d5c2d98SGuenter Roeck case hwmon_curr: 605*4d5c2d98SGuenter Roeck return ina2xx_curr_write(dev, attr, val); 606814db9f1SGuenter Roeck default: 607814db9f1SGuenter Roeck return -EOPNOTSUPP; 608814db9f1SGuenter Roeck } 609814db9f1SGuenter Roeck } 610814db9f1SGuenter Roeck 611814db9f1SGuenter Roeck static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type, 612814db9f1SGuenter Roeck u32 attr, int channel) 613814db9f1SGuenter Roeck { 614814db9f1SGuenter Roeck const struct ina2xx_data *data = _data; 615814db9f1SGuenter Roeck enum ina2xx_ids chip = data->chip; 616814db9f1SGuenter Roeck 617814db9f1SGuenter Roeck switch (type) { 618814db9f1SGuenter Roeck case hwmon_in: 619814db9f1SGuenter Roeck switch (attr) { 620814db9f1SGuenter Roeck case hwmon_in_input: 621814db9f1SGuenter Roeck return 0444; 622814db9f1SGuenter Roeck case hwmon_in_lcrit: 623814db9f1SGuenter Roeck case hwmon_in_crit: 624814db9f1SGuenter Roeck if (chip == ina226) 625814db9f1SGuenter Roeck return 0644; 626814db9f1SGuenter Roeck break; 627814db9f1SGuenter Roeck case hwmon_in_lcrit_alarm: 628814db9f1SGuenter Roeck case hwmon_in_crit_alarm: 629814db9f1SGuenter Roeck if (chip == ina226) 630814db9f1SGuenter Roeck return 0444; 631814db9f1SGuenter Roeck break; 632814db9f1SGuenter Roeck default: 633814db9f1SGuenter Roeck break; 634814db9f1SGuenter Roeck } 635814db9f1SGuenter Roeck break; 636814db9f1SGuenter Roeck case hwmon_curr: 637814db9f1SGuenter Roeck switch (attr) { 638814db9f1SGuenter Roeck case hwmon_curr_input: 639814db9f1SGuenter Roeck return 0444; 640*4d5c2d98SGuenter Roeck case hwmon_curr_lcrit: 641*4d5c2d98SGuenter Roeck case hwmon_curr_crit: 642*4d5c2d98SGuenter Roeck if (chip == ina226) 643*4d5c2d98SGuenter Roeck return 0644; 644*4d5c2d98SGuenter Roeck break; 645*4d5c2d98SGuenter Roeck case hwmon_curr_lcrit_alarm: 646*4d5c2d98SGuenter Roeck case hwmon_curr_crit_alarm: 647*4d5c2d98SGuenter Roeck if (chip == ina226) 648*4d5c2d98SGuenter Roeck return 0444; 649*4d5c2d98SGuenter Roeck break; 650814db9f1SGuenter Roeck default: 651814db9f1SGuenter Roeck break; 652814db9f1SGuenter Roeck } 653814db9f1SGuenter Roeck break; 654814db9f1SGuenter Roeck case hwmon_power: 655814db9f1SGuenter Roeck switch (attr) { 656814db9f1SGuenter Roeck case hwmon_power_input: 657814db9f1SGuenter Roeck return 0444; 658814db9f1SGuenter Roeck case hwmon_power_crit: 659814db9f1SGuenter Roeck if (chip == ina226) 660814db9f1SGuenter Roeck return 0644; 661814db9f1SGuenter Roeck break; 662814db9f1SGuenter Roeck case hwmon_power_crit_alarm: 663814db9f1SGuenter Roeck if (chip == ina226) 664814db9f1SGuenter Roeck return 0444; 665814db9f1SGuenter Roeck break; 666814db9f1SGuenter Roeck default: 667814db9f1SGuenter Roeck break; 668814db9f1SGuenter Roeck } 669814db9f1SGuenter Roeck break; 670814db9f1SGuenter Roeck case hwmon_chip: 671814db9f1SGuenter Roeck switch (attr) { 672814db9f1SGuenter Roeck case hwmon_chip_update_interval: 673814db9f1SGuenter Roeck if (chip == ina226) 674814db9f1SGuenter Roeck return 0644; 675814db9f1SGuenter Roeck break; 676814db9f1SGuenter Roeck default: 677814db9f1SGuenter Roeck break; 678814db9f1SGuenter Roeck } 679814db9f1SGuenter Roeck break; 680814db9f1SGuenter Roeck default: 681814db9f1SGuenter Roeck break; 682814db9f1SGuenter Roeck } 683814db9f1SGuenter Roeck return 0; 684814db9f1SGuenter Roeck } 685814db9f1SGuenter Roeck 686814db9f1SGuenter Roeck static const struct hwmon_channel_info * const ina2xx_info[] = { 687814db9f1SGuenter Roeck HWMON_CHANNEL_INFO(chip, 688814db9f1SGuenter Roeck HWMON_C_UPDATE_INTERVAL), 689814db9f1SGuenter Roeck HWMON_CHANNEL_INFO(in, 690814db9f1SGuenter Roeck HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM | 691814db9f1SGuenter Roeck HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM, 692814db9f1SGuenter Roeck HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM | 693814db9f1SGuenter Roeck HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM 694814db9f1SGuenter Roeck ), 695*4d5c2d98SGuenter Roeck HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM | 696*4d5c2d98SGuenter Roeck HWMON_C_LCRIT | HWMON_C_LCRIT_ALARM), 697814db9f1SGuenter Roeck HWMON_CHANNEL_INFO(power, 698814db9f1SGuenter Roeck HWMON_P_INPUT | HWMON_P_CRIT | HWMON_P_CRIT_ALARM), 699814db9f1SGuenter Roeck NULL 700814db9f1SGuenter Roeck }; 701814db9f1SGuenter Roeck 702814db9f1SGuenter Roeck static const struct hwmon_ops ina2xx_hwmon_ops = { 703814db9f1SGuenter Roeck .is_visible = ina2xx_is_visible, 704814db9f1SGuenter Roeck .read = ina2xx_read, 705814db9f1SGuenter Roeck .write = ina2xx_write, 706814db9f1SGuenter Roeck }; 707814db9f1SGuenter Roeck 708814db9f1SGuenter Roeck static const struct hwmon_chip_info ina2xx_chip_info = { 709814db9f1SGuenter Roeck .ops = &ina2xx_hwmon_ops, 710814db9f1SGuenter Roeck .info = ina2xx_info, 711814db9f1SGuenter Roeck }; 712814db9f1SGuenter Roeck 713814db9f1SGuenter Roeck /* shunt resistance */ 7145a56a39bSAlex Qiu 7155d389b12SMaciej Purski /* 7165d389b12SMaciej Purski * In order to keep calibration register value fixed, the product 7175d389b12SMaciej Purski * of current_lsb and shunt_resistor should also be fixed and equal 7185d389b12SMaciej Purski * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order 7195d389b12SMaciej Purski * to keep the scale. 7205d389b12SMaciej Purski */ 721ab7fbee4SGuenter Roeck static int ina2xx_set_shunt(struct ina2xx_data *data, unsigned long val) 7225d389b12SMaciej Purski { 7235d389b12SMaciej Purski unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, 7245d389b12SMaciej Purski data->config->shunt_div); 725ab7fbee4SGuenter Roeck if (!val || val > dividend) 7265d389b12SMaciej Purski return -EINVAL; 7275d389b12SMaciej Purski 7285d389b12SMaciej Purski data->rshunt = val; 7295d389b12SMaciej Purski data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); 7305d389b12SMaciej Purski data->power_lsb_uW = data->config->power_lsb_factor * 7315d389b12SMaciej Purski data->current_lsb_uA; 7325d389b12SMaciej Purski 7335d389b12SMaciej Purski return 0; 7345d389b12SMaciej Purski } 7355d389b12SMaciej Purski 736814db9f1SGuenter Roeck static ssize_t shunt_resistor_show(struct device *dev, 7376a0f234fSGuenter Roeck struct device_attribute *da, char *buf) 7383ad86700SLothar Felten { 7393ad86700SLothar Felten struct ina2xx_data *data = dev_get_drvdata(dev); 7403ad86700SLothar Felten 741af9a9730SZihao Tang return sysfs_emit(buf, "%li\n", data->rshunt); 7423ad86700SLothar Felten } 7433ad86700SLothar Felten 744814db9f1SGuenter Roeck static ssize_t shunt_resistor_store(struct device *dev, 7458a5fc795SBartosz Golaszewski struct device_attribute *da, 7468a5fc795SBartosz Golaszewski const char *buf, size_t count) 7478a5fc795SBartosz Golaszewski { 748814db9f1SGuenter Roeck struct ina2xx_data *data = dev_get_drvdata(dev); 7498a5fc795SBartosz Golaszewski unsigned long val; 7508a5fc795SBartosz Golaszewski int status; 7518a5fc795SBartosz Golaszewski 7528a5fc795SBartosz Golaszewski status = kstrtoul(buf, 10, &val); 7538a5fc795SBartosz Golaszewski if (status < 0) 7548a5fc795SBartosz Golaszewski return status; 7558a5fc795SBartosz Golaszewski 756ab7fbee4SGuenter Roeck mutex_lock(&data->config_lock); 7575d389b12SMaciej Purski status = ina2xx_set_shunt(data, val); 758ab7fbee4SGuenter Roeck mutex_unlock(&data->config_lock); 7598a5fc795SBartosz Golaszewski if (status < 0) 7608a5fc795SBartosz Golaszewski return status; 7618a5fc795SBartosz Golaszewski return count; 7628a5fc795SBartosz Golaszewski } 7638a5fc795SBartosz Golaszewski 764814db9f1SGuenter Roeck static DEVICE_ATTR_RW(shunt_resistor); 76572a87a47SBartosz Golaszewski 766f7c2fe38SFelten, Lothar /* pointers to created device attributes */ 767468bf0e3SGuenter Roeck static struct attribute *ina2xx_attrs[] = { 768814db9f1SGuenter Roeck &dev_attr_shunt_resistor.attr, 769f7c2fe38SFelten, Lothar NULL, 770f7c2fe38SFelten, Lothar }; 771814db9f1SGuenter Roeck ATTRIBUTE_GROUPS(ina2xx); 772f7c2fe38SFelten, Lothar 77351c6fa32SGuenter Roeck /* 77451c6fa32SGuenter Roeck * Initialize chip 77551c6fa32SGuenter Roeck */ 77651c6fa32SGuenter Roeck static int ina2xx_init(struct device *dev, struct ina2xx_data *data) 77751c6fa32SGuenter Roeck { 77851c6fa32SGuenter Roeck struct regmap *regmap = data->regmap; 77951c6fa32SGuenter Roeck u32 shunt; 78051c6fa32SGuenter Roeck int ret; 78151c6fa32SGuenter Roeck 78251c6fa32SGuenter Roeck if (device_property_read_u32(dev, "shunt-resistor", &shunt) < 0) 78351c6fa32SGuenter Roeck shunt = INA2XX_RSHUNT_DEFAULT; 78451c6fa32SGuenter Roeck 78551c6fa32SGuenter Roeck ret = ina2xx_set_shunt(data, shunt); 78651c6fa32SGuenter Roeck if (ret < 0) 78751c6fa32SGuenter Roeck return ret; 78851c6fa32SGuenter Roeck 78951c6fa32SGuenter Roeck ret = regmap_write(regmap, INA2XX_CONFIG, data->config->config_default); 79051c6fa32SGuenter Roeck if (ret < 0) 79151c6fa32SGuenter Roeck return ret; 79251c6fa32SGuenter Roeck 79351c6fa32SGuenter Roeck if (data->chip == ina226) { 79451c6fa32SGuenter Roeck bool active_high = device_property_read_bool(dev, "ti,alert-polarity-active-high"); 79551c6fa32SGuenter Roeck 796aa7d1763SGuenter Roeck regmap_update_bits(regmap, INA226_MASK_ENABLE, 797aa7d1763SGuenter Roeck INA226_ALERT_LATCH_ENABLE | INA226_ALERT_POLARITY, 798aa7d1763SGuenter Roeck INA226_ALERT_LATCH_ENABLE | 79951c6fa32SGuenter Roeck FIELD_PREP(INA226_ALERT_POLARITY, active_high)); 80051c6fa32SGuenter Roeck } 80151c6fa32SGuenter Roeck 80251c6fa32SGuenter Roeck /* 80351c6fa32SGuenter Roeck * Calibration register is set to the best value, which eliminates 80451c6fa32SGuenter Roeck * truncation errors on calculating current register in hardware. 80551c6fa32SGuenter Roeck * According to datasheet (eq. 3) the best values are 2048 for 80651c6fa32SGuenter Roeck * ina226 and 4096 for ina219. They are hardcoded as calibration_value. 80751c6fa32SGuenter Roeck */ 80851c6fa32SGuenter Roeck return regmap_write(regmap, INA2XX_CALIBRATION, 80951c6fa32SGuenter Roeck data->config->calibration_value); 81051c6fa32SGuenter Roeck } 81151c6fa32SGuenter Roeck 81267487038SStephen Kitt static int ina2xx_probe(struct i2c_client *client) 813f7c2fe38SFelten, Lothar { 814468bf0e3SGuenter Roeck struct device *dev = &client->dev; 815468bf0e3SGuenter Roeck struct ina2xx_data *data; 816468bf0e3SGuenter Roeck struct device *hwmon_dev; 817bd0ddd4dSJavier Martinez Canillas enum ina2xx_ids chip; 818814db9f1SGuenter Roeck int ret; 819bd0ddd4dSJavier Martinez Canillas 8208b839699SAndrew Davis chip = (uintptr_t)i2c_get_match_data(client); 821f7c2fe38SFelten, Lothar 822468bf0e3SGuenter Roeck data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 823f7c2fe38SFelten, Lothar if (!data) 824f7c2fe38SFelten, Lothar return -ENOMEM; 825f7c2fe38SFelten, Lothar 826f7c2fe38SFelten, Lothar /* set the device type */ 827bd0ddd4dSJavier Martinez Canillas data->config = &ina2xx_config[chip]; 82851c6fa32SGuenter Roeck data->chip = chip; 8290c4c5860SMarek Szyprowski mutex_init(&data->config_lock); 83072a87a47SBartosz Golaszewski 831a0de56c8SMarc Titinger data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); 832a0de56c8SMarc Titinger if (IS_ERR(data->regmap)) { 833a0de56c8SMarc Titinger dev_err(dev, "failed to allocate register map\n"); 834a0de56c8SMarc Titinger return PTR_ERR(data->regmap); 835a0de56c8SMarc Titinger } 836a0de56c8SMarc Titinger 837ad20248aSSvyatoslav Ryhel ret = devm_regulator_get_enable(dev, "vs"); 838ad20248aSSvyatoslav Ryhel if (ret) 839ad20248aSSvyatoslav Ryhel return dev_err_probe(dev, ret, "failed to enable vs regulator\n"); 840ad20248aSSvyatoslav Ryhel 84151c6fa32SGuenter Roeck ret = ina2xx_init(dev, data); 84251c6fa32SGuenter Roeck if (ret < 0) 84351c6fa32SGuenter Roeck return dev_err_probe(dev, ret, "failed to configure device\n"); 844509416a8SBartosz Golaszewski 845814db9f1SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 846814db9f1SGuenter Roeck data, &ina2xx_chip_info, 847814db9f1SGuenter Roeck ina2xx_groups); 848468bf0e3SGuenter Roeck if (IS_ERR(hwmon_dev)) 849468bf0e3SGuenter Roeck return PTR_ERR(hwmon_dev); 850f7c2fe38SFelten, Lothar 851468bf0e3SGuenter Roeck dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n", 85270df9ebbSNicolin Chen client->name, data->rshunt); 8536106db25SGuenter Roeck 854f7c2fe38SFelten, Lothar return 0; 855f7c2fe38SFelten, Lothar } 856f7c2fe38SFelten, Lothar 857f7c2fe38SFelten, Lothar static const struct i2c_device_id ina2xx_id[] = { 858f7c2fe38SFelten, Lothar { "ina219", ina219 }, 859dc92cd0cSGuenter Roeck { "ina220", ina219 }, 860f7c2fe38SFelten, Lothar { "ina226", ina226 }, 861dc92cd0cSGuenter Roeck { "ina230", ina226 }, 862add513beSKevin Hilman { "ina231", ina226 }, 863f7c2fe38SFelten, Lothar { } 864f7c2fe38SFelten, Lothar }; 865f7c2fe38SFelten, Lothar MODULE_DEVICE_TABLE(i2c, ina2xx_id); 866f7c2fe38SFelten, Lothar 867df6b8c70SGuenter Roeck static const struct of_device_id __maybe_unused ina2xx_of_match[] = { 868bd0ddd4dSJavier Martinez Canillas { 869bd0ddd4dSJavier Martinez Canillas .compatible = "ti,ina219", 870bd0ddd4dSJavier Martinez Canillas .data = (void *)ina219 871bd0ddd4dSJavier Martinez Canillas }, 872bd0ddd4dSJavier Martinez Canillas { 873bd0ddd4dSJavier Martinez Canillas .compatible = "ti,ina220", 874bd0ddd4dSJavier Martinez Canillas .data = (void *)ina219 875bd0ddd4dSJavier Martinez Canillas }, 876bd0ddd4dSJavier Martinez Canillas { 877bd0ddd4dSJavier Martinez Canillas .compatible = "ti,ina226", 878bd0ddd4dSJavier Martinez Canillas .data = (void *)ina226 879bd0ddd4dSJavier Martinez Canillas }, 880bd0ddd4dSJavier Martinez Canillas { 881bd0ddd4dSJavier Martinez Canillas .compatible = "ti,ina230", 882bd0ddd4dSJavier Martinez Canillas .data = (void *)ina226 883bd0ddd4dSJavier Martinez Canillas }, 884bd0ddd4dSJavier Martinez Canillas { 885bd0ddd4dSJavier Martinez Canillas .compatible = "ti,ina231", 886bd0ddd4dSJavier Martinez Canillas .data = (void *)ina226 887bd0ddd4dSJavier Martinez Canillas }, 888bd0ddd4dSJavier Martinez Canillas { }, 889bd0ddd4dSJavier Martinez Canillas }; 890bd0ddd4dSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, ina2xx_of_match); 891bd0ddd4dSJavier Martinez Canillas 892f7c2fe38SFelten, Lothar static struct i2c_driver ina2xx_driver = { 893f7c2fe38SFelten, Lothar .driver = { 894f7c2fe38SFelten, Lothar .name = "ina2xx", 895bd0ddd4dSJavier Martinez Canillas .of_match_table = of_match_ptr(ina2xx_of_match), 896f7c2fe38SFelten, Lothar }, 8971975d167SUwe Kleine-König .probe = ina2xx_probe, 898f7c2fe38SFelten, Lothar .id_table = ina2xx_id, 899f7c2fe38SFelten, Lothar }; 900f7c2fe38SFelten, Lothar 901d835ca0fSWei Yongjun module_i2c_driver(ina2xx_driver); 902f7c2fe38SFelten, Lothar 903f7c2fe38SFelten, Lothar MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>"); 904f7c2fe38SFelten, Lothar MODULE_DESCRIPTION("ina2xx driver"); 905f7c2fe38SFelten, Lothar MODULE_LICENSE("GPL"); 906