xref: /openbmc/linux/drivers/hwmon/ina2xx.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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 
25f7c2fe38SFelten, Lothar #include <linux/kernel.h>
26f7c2fe38SFelten, Lothar #include <linux/module.h>
27f7c2fe38SFelten, Lothar #include <linux/init.h>
28f7c2fe38SFelten, Lothar #include <linux/err.h>
29f7c2fe38SFelten, Lothar #include <linux/slab.h>
30f7c2fe38SFelten, Lothar #include <linux/i2c.h>
31f7c2fe38SFelten, Lothar #include <linux/hwmon.h>
32f7c2fe38SFelten, Lothar #include <linux/hwmon-sysfs.h>
33dcd8f392SJean Delvare #include <linux/jiffies.h>
3431e7ad74STang Yuantian #include <linux/of.h>
35509416a8SBartosz Golaszewski #include <linux/delay.h>
36d38df34eSBartosz Golaszewski #include <linux/util_macros.h>
37a0de56c8SMarc Titinger #include <linux/regmap.h>
38f7c2fe38SFelten, Lothar 
39f7c2fe38SFelten, Lothar #include <linux/platform_data/ina2xx.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 /* register count */
55f7c2fe38SFelten, Lothar #define INA219_REGISTERS		6
56f7c2fe38SFelten, Lothar #define INA226_REGISTERS		8
57f7c2fe38SFelten, Lothar 
58f7c2fe38SFelten, Lothar #define INA2XX_MAX_REGISTERS		8
59f7c2fe38SFelten, Lothar 
60f7c2fe38SFelten, Lothar /* settings - depend on use case */
61f7c2fe38SFelten, Lothar #define INA219_CONFIG_DEFAULT		0x399F	/* PGA=8 */
62f7c2fe38SFelten, Lothar #define INA226_CONFIG_DEFAULT		0x4527	/* averages=16 */
63f7c2fe38SFelten, Lothar 
64f7c2fe38SFelten, Lothar /* worst case is 68.10 ms (~14.6Hz, ina219) */
65f7c2fe38SFelten, Lothar #define INA2XX_CONVERSION_RATE		15
66509416a8SBartosz Golaszewski #define INA2XX_MAX_DELAY		69 /* worst case delay in ms */
67509416a8SBartosz Golaszewski 
68509416a8SBartosz Golaszewski #define INA2XX_RSHUNT_DEFAULT		10000
69f7c2fe38SFelten, Lothar 
7072a87a47SBartosz Golaszewski /* bit mask for reading the averaging setting in the configuration register */
7172a87a47SBartosz Golaszewski #define INA226_AVG_RD_MASK		0x0E00
7272a87a47SBartosz Golaszewski 
7372a87a47SBartosz Golaszewski #define INA226_READ_AVG(reg)		(((reg) & INA226_AVG_RD_MASK) >> 9)
7472a87a47SBartosz Golaszewski #define INA226_SHIFT_AVG(val)		((val) << 9)
7572a87a47SBartosz Golaszewski 
765a56a39bSAlex Qiu /* bit number of alert functions in Mask/Enable Register */
775a56a39bSAlex Qiu #define INA226_SHUNT_OVER_VOLTAGE_BIT	15
785a56a39bSAlex Qiu #define INA226_SHUNT_UNDER_VOLTAGE_BIT	14
795a56a39bSAlex Qiu #define INA226_BUS_OVER_VOLTAGE_BIT	13
805a56a39bSAlex Qiu #define INA226_BUS_UNDER_VOLTAGE_BIT	12
815a56a39bSAlex Qiu #define INA226_POWER_OVER_LIMIT_BIT	11
825a56a39bSAlex Qiu 
835a56a39bSAlex Qiu /* bit mask for alert config bits of Mask/Enable Register */
845a56a39bSAlex Qiu #define INA226_ALERT_CONFIG_MASK	0xFC00
855a56a39bSAlex Qiu #define INA226_ALERT_FUNCTION_FLAG	BIT(4)
865a56a39bSAlex Qiu 
8772a87a47SBartosz Golaszewski /* common attrs, ina226 attrs and NULL */
8872a87a47SBartosz Golaszewski #define INA2XX_MAX_ATTRIBUTE_GROUPS	3
8972a87a47SBartosz Golaszewski 
9072a87a47SBartosz Golaszewski /*
9172a87a47SBartosz Golaszewski  * Both bus voltage and shunt voltage conversion times for ina226 are set
9272a87a47SBartosz Golaszewski  * to 0b0100 on POR, which translates to 2200 microseconds in total.
9372a87a47SBartosz Golaszewski  */
9472a87a47SBartosz Golaszewski #define INA226_TOTAL_CONV_TIME_DEFAULT	2200
9572a87a47SBartosz Golaszewski 
96a0de56c8SMarc Titinger static struct regmap_config ina2xx_regmap_config = {
97a0de56c8SMarc Titinger 	.reg_bits = 8,
98a0de56c8SMarc Titinger 	.val_bits = 16,
99a0de56c8SMarc Titinger };
100a0de56c8SMarc Titinger 
101f7c2fe38SFelten, Lothar enum ina2xx_ids { ina219, ina226 };
102f7c2fe38SFelten, Lothar 
1036106db25SGuenter Roeck struct ina2xx_config {
1046106db25SGuenter Roeck 	u16 config_default;
1055d389b12SMaciej Purski 	int calibration_value;
1066106db25SGuenter Roeck 	int registers;
1076106db25SGuenter Roeck 	int shunt_div;
1086106db25SGuenter Roeck 	int bus_voltage_shift;
1096106db25SGuenter Roeck 	int bus_voltage_lsb;	/* uV */
1105d389b12SMaciej Purski 	int power_lsb_factor;
1116106db25SGuenter Roeck };
1126106db25SGuenter Roeck 
113f7c2fe38SFelten, Lothar struct ina2xx_data {
1146106db25SGuenter Roeck 	const struct ina2xx_config *config;
115f7c2fe38SFelten, Lothar 
116509416a8SBartosz Golaszewski 	long rshunt;
1175d389b12SMaciej Purski 	long current_lsb_uA;
1185d389b12SMaciej Purski 	long power_lsb_uW;
119a0de56c8SMarc Titinger 	struct mutex config_lock;
120a0de56c8SMarc Titinger 	struct regmap *regmap;
121f7c2fe38SFelten, Lothar 
12272a87a47SBartosz Golaszewski 	const struct attribute_group *groups[INA2XX_MAX_ATTRIBUTE_GROUPS];
123f7c2fe38SFelten, Lothar };
124f7c2fe38SFelten, Lothar 
1256106db25SGuenter Roeck static const struct ina2xx_config ina2xx_config[] = {
1266106db25SGuenter Roeck 	[ina219] = {
1276106db25SGuenter Roeck 		.config_default = INA219_CONFIG_DEFAULT,
1285d389b12SMaciej Purski 		.calibration_value = 4096,
1296106db25SGuenter Roeck 		.registers = INA219_REGISTERS,
1306106db25SGuenter Roeck 		.shunt_div = 100,
1316106db25SGuenter Roeck 		.bus_voltage_shift = 3,
1326106db25SGuenter Roeck 		.bus_voltage_lsb = 4000,
1335d389b12SMaciej Purski 		.power_lsb_factor = 20,
1346106db25SGuenter Roeck 	},
1356106db25SGuenter Roeck 	[ina226] = {
1366106db25SGuenter Roeck 		.config_default = INA226_CONFIG_DEFAULT,
1375d389b12SMaciej Purski 		.calibration_value = 2048,
1386106db25SGuenter Roeck 		.registers = INA226_REGISTERS,
1396106db25SGuenter Roeck 		.shunt_div = 400,
1406106db25SGuenter Roeck 		.bus_voltage_shift = 0,
1416106db25SGuenter Roeck 		.bus_voltage_lsb = 1250,
1425d389b12SMaciej Purski 		.power_lsb_factor = 25,
1436106db25SGuenter Roeck 	},
1446106db25SGuenter Roeck };
1456106db25SGuenter Roeck 
14672a87a47SBartosz Golaszewski /*
14772a87a47SBartosz Golaszewski  * Available averaging rates for ina226. The indices correspond with
14872a87a47SBartosz Golaszewski  * the bit values expected by the chip (according to the ina226 datasheet,
14972a87a47SBartosz Golaszewski  * table 3 AVG bit settings, found at
15049dc2fb0SAlexander A. Klimov  * https://www.ti.com/lit/ds/symlink/ina226.pdf.
15172a87a47SBartosz Golaszewski  */
15272a87a47SBartosz Golaszewski static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
15372a87a47SBartosz Golaszewski 
ina226_reg_to_interval(u16 config)15472a87a47SBartosz Golaszewski static int ina226_reg_to_interval(u16 config)
15572a87a47SBartosz Golaszewski {
15672a87a47SBartosz Golaszewski 	int avg = ina226_avg_tab[INA226_READ_AVG(config)];
15772a87a47SBartosz Golaszewski 
15872a87a47SBartosz Golaszewski 	/*
15972a87a47SBartosz Golaszewski 	 * Multiply the total conversion time by the number of averages.
16072a87a47SBartosz Golaszewski 	 * Return the result in milliseconds.
16172a87a47SBartosz Golaszewski 	 */
16272a87a47SBartosz Golaszewski 	return DIV_ROUND_CLOSEST(avg * INA226_TOTAL_CONV_TIME_DEFAULT, 1000);
16372a87a47SBartosz Golaszewski }
16472a87a47SBartosz Golaszewski 
165a0de56c8SMarc Titinger /*
166a0de56c8SMarc Titinger  * Return the new, shifted AVG field value of CONFIG register,
167a0de56c8SMarc Titinger  * to use with regmap_update_bits
168a0de56c8SMarc Titinger  */
ina226_interval_to_reg(int interval)169a0de56c8SMarc Titinger static u16 ina226_interval_to_reg(int interval)
17072a87a47SBartosz Golaszewski {
17172a87a47SBartosz Golaszewski 	int avg, avg_bits;
17272a87a47SBartosz Golaszewski 
17372a87a47SBartosz Golaszewski 	avg = DIV_ROUND_CLOSEST(interval * 1000,
17472a87a47SBartosz Golaszewski 				INA226_TOTAL_CONV_TIME_DEFAULT);
175d38df34eSBartosz Golaszewski 	avg_bits = find_closest(avg, ina226_avg_tab,
176d38df34eSBartosz Golaszewski 				ARRAY_SIZE(ina226_avg_tab));
17772a87a47SBartosz Golaszewski 
178a0de56c8SMarc Titinger 	return INA226_SHIFT_AVG(avg_bits);
17972a87a47SBartosz Golaszewski }
18072a87a47SBartosz Golaszewski 
1815d389b12SMaciej Purski /*
1825d389b12SMaciej Purski  * Calibration register is set to the best value, which eliminates
1835d389b12SMaciej Purski  * truncation errors on calculating current register in hardware.
1845d389b12SMaciej Purski  * According to datasheet (eq. 3) the best values are 2048 for
1855d389b12SMaciej Purski  * ina226 and 4096 for ina219. They are hardcoded as calibration_value.
1865d389b12SMaciej Purski  */
ina2xx_calibrate(struct ina2xx_data * data)1878a5fc795SBartosz Golaszewski static int ina2xx_calibrate(struct ina2xx_data *data)
1888a5fc795SBartosz Golaszewski {
1895d389b12SMaciej Purski 	return regmap_write(data->regmap, INA2XX_CALIBRATION,
1905d389b12SMaciej Purski 			    data->config->calibration_value);
1918a5fc795SBartosz Golaszewski }
1928a5fc795SBartosz Golaszewski 
193509416a8SBartosz Golaszewski /*
194509416a8SBartosz Golaszewski  * Initialize the configuration and calibration registers.
195509416a8SBartosz Golaszewski  */
ina2xx_init(struct ina2xx_data * data)196509416a8SBartosz Golaszewski static int ina2xx_init(struct ina2xx_data *data)
197509416a8SBartosz Golaszewski {
198a0de56c8SMarc Titinger 	int ret = regmap_write(data->regmap, INA2XX_CONFIG,
199a0de56c8SMarc Titinger 			       data->config->config_default);
200509416a8SBartosz Golaszewski 	if (ret < 0)
201509416a8SBartosz Golaszewski 		return ret;
202509416a8SBartosz Golaszewski 
2038a5fc795SBartosz Golaszewski 	return ina2xx_calibrate(data);
204509416a8SBartosz Golaszewski }
205509416a8SBartosz Golaszewski 
ina2xx_read_reg(struct device * dev,int reg,unsigned int * regval)206a0de56c8SMarc Titinger static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval)
207f7c2fe38SFelten, Lothar {
208468bf0e3SGuenter Roeck 	struct ina2xx_data *data = dev_get_drvdata(dev);
209a0de56c8SMarc Titinger 	int ret, retry;
210509416a8SBartosz Golaszewski 
211a0de56c8SMarc Titinger 	dev_dbg(dev, "Starting register %d read\n", reg);
212509416a8SBartosz Golaszewski 
213509416a8SBartosz Golaszewski 	for (retry = 5; retry; retry--) {
214a0de56c8SMarc Titinger 
215a0de56c8SMarc Titinger 		ret = regmap_read(data->regmap, reg, regval);
216a0de56c8SMarc Titinger 		if (ret < 0)
217a0de56c8SMarc Titinger 			return ret;
218a0de56c8SMarc Titinger 
219a0de56c8SMarc Titinger 		dev_dbg(dev, "read %d, val = 0x%04x\n", reg, *regval);
220509416a8SBartosz Golaszewski 
221509416a8SBartosz Golaszewski 		/*
222509416a8SBartosz Golaszewski 		 * If the current value in the calibration register is 0, the
223509416a8SBartosz Golaszewski 		 * power and current registers will also remain at 0. In case
224509416a8SBartosz Golaszewski 		 * the chip has been reset let's check the calibration
225509416a8SBartosz Golaszewski 		 * register and reinitialize if needed.
226a0de56c8SMarc Titinger 		 * We do that extra read of the calibration register if there
227a0de56c8SMarc Titinger 		 * is some hint of a chip reset.
228509416a8SBartosz Golaszewski 		 */
229a0de56c8SMarc Titinger 		if (*regval == 0) {
230a0de56c8SMarc Titinger 			unsigned int cal;
231a0de56c8SMarc Titinger 
232a0de56c8SMarc Titinger 			ret = regmap_read(data->regmap, INA2XX_CALIBRATION,
233a0de56c8SMarc Titinger 					  &cal);
234a0de56c8SMarc Titinger 			if (ret < 0)
235a0de56c8SMarc Titinger 				return ret;
236a0de56c8SMarc Titinger 
237a0de56c8SMarc Titinger 			if (cal == 0) {
238509416a8SBartosz Golaszewski 				dev_warn(dev, "chip not calibrated, reinitializing\n");
239509416a8SBartosz Golaszewski 
240a0de56c8SMarc Titinger 				ret = ina2xx_init(data);
241a0de56c8SMarc Titinger 				if (ret < 0)
242a0de56c8SMarc Titinger 					return ret;
243509416a8SBartosz Golaszewski 				/*
244a0de56c8SMarc Titinger 				 * Let's make sure the power and current
245a0de56c8SMarc Titinger 				 * registers have been updated before trying
246a0de56c8SMarc Titinger 				 * again.
247509416a8SBartosz Golaszewski 				 */
248509416a8SBartosz Golaszewski 				msleep(INA2XX_MAX_DELAY);
249509416a8SBartosz Golaszewski 				continue;
250509416a8SBartosz Golaszewski 			}
251a0de56c8SMarc Titinger 		}
252509416a8SBartosz Golaszewski 		return 0;
253509416a8SBartosz Golaszewski 	}
254509416a8SBartosz Golaszewski 
255509416a8SBartosz Golaszewski 	/*
256509416a8SBartosz Golaszewski 	 * If we're here then although all write operations succeeded, the
257509416a8SBartosz Golaszewski 	 * chip still returns 0 in the calibration register. Nothing more we
258509416a8SBartosz Golaszewski 	 * can do here.
259509416a8SBartosz Golaszewski 	 */
260509416a8SBartosz Golaszewski 	dev_err(dev, "unable to reinitialize the chip\n");
261509416a8SBartosz Golaszewski 	return -ENODEV;
262509416a8SBartosz Golaszewski }
263509416a8SBartosz Golaszewski 
ina2xx_get_value(struct ina2xx_data * data,u8 reg,unsigned int regval)264a0de56c8SMarc Titinger static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
265a0de56c8SMarc Titinger 			    unsigned int regval)
266f7c2fe38SFelten, Lothar {
2676106db25SGuenter Roeck 	int val;
268f7c2fe38SFelten, Lothar 
269f7c2fe38SFelten, Lothar 	switch (reg) {
270f7c2fe38SFelten, Lothar 	case INA2XX_SHUNT_VOLTAGE:
271c0214f98SFabio Baltieri 		/* signed register */
272a0de56c8SMarc Titinger 		val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div);
273f7c2fe38SFelten, Lothar 		break;
274f7c2fe38SFelten, Lothar 	case INA2XX_BUS_VOLTAGE:
275a0de56c8SMarc Titinger 		val = (regval >> data->config->bus_voltage_shift)
2766106db25SGuenter Roeck 		  * data->config->bus_voltage_lsb;
2776106db25SGuenter Roeck 		val = DIV_ROUND_CLOSEST(val, 1000);
278f7c2fe38SFelten, Lothar 		break;
279f7c2fe38SFelten, Lothar 	case INA2XX_POWER:
2805d389b12SMaciej Purski 		val = regval * data->power_lsb_uW;
281f7c2fe38SFelten, Lothar 		break;
282f7c2fe38SFelten, Lothar 	case INA2XX_CURRENT:
2835d389b12SMaciej Purski 		/* signed register, result in mA */
28438cd989eSNicolin Chen 		val = (s16)regval * data->current_lsb_uA;
2855d389b12SMaciej Purski 		val = DIV_ROUND_CLOSEST(val, 1000);
286f7c2fe38SFelten, Lothar 		break;
2878a5fc795SBartosz Golaszewski 	case INA2XX_CALIBRATION:
2885d389b12SMaciej Purski 		val = regval;
2898a5fc795SBartosz Golaszewski 		break;
290f7c2fe38SFelten, Lothar 	default:
291f7c2fe38SFelten, Lothar 		/* programmer goofed */
292f7c2fe38SFelten, Lothar 		WARN_ON_ONCE(1);
293f7c2fe38SFelten, Lothar 		val = 0;
294f7c2fe38SFelten, Lothar 		break;
295f7c2fe38SFelten, Lothar 	}
296f7c2fe38SFelten, Lothar 
297f7c2fe38SFelten, Lothar 	return val;
298f7c2fe38SFelten, Lothar }
299f7c2fe38SFelten, Lothar 
ina2xx_value_show(struct device * dev,struct device_attribute * da,char * buf)3006a0f234fSGuenter Roeck static ssize_t ina2xx_value_show(struct device *dev,
301f7c2fe38SFelten, Lothar 				 struct device_attribute *da, char *buf)
302f7c2fe38SFelten, Lothar {
303f7c2fe38SFelten, Lothar 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
304a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
305a0de56c8SMarc Titinger 	unsigned int regval;
306f7c2fe38SFelten, Lothar 
307a0de56c8SMarc Titinger 	int err = ina2xx_read_reg(dev, attr->index, &regval);
308a0de56c8SMarc Titinger 
309a0de56c8SMarc Titinger 	if (err < 0)
310a0de56c8SMarc Titinger 		return err;
311f7c2fe38SFelten, Lothar 
312af9a9730SZihao Tang 	return sysfs_emit(buf, "%d\n", ina2xx_get_value(data, attr->index, regval));
313f7c2fe38SFelten, Lothar }
314f7c2fe38SFelten, Lothar 
ina226_reg_to_alert(struct ina2xx_data * data,u8 bit,u16 regval)3155a56a39bSAlex Qiu static int ina226_reg_to_alert(struct ina2xx_data *data, u8 bit, u16 regval)
3165a56a39bSAlex Qiu {
3175a56a39bSAlex Qiu 	int reg;
3185a56a39bSAlex Qiu 
3195a56a39bSAlex Qiu 	switch (bit) {
3205a56a39bSAlex Qiu 	case INA226_SHUNT_OVER_VOLTAGE_BIT:
3215a56a39bSAlex Qiu 	case INA226_SHUNT_UNDER_VOLTAGE_BIT:
3225a56a39bSAlex Qiu 		reg = INA2XX_SHUNT_VOLTAGE;
3235a56a39bSAlex Qiu 		break;
3245a56a39bSAlex Qiu 	case INA226_BUS_OVER_VOLTAGE_BIT:
3255a56a39bSAlex Qiu 	case INA226_BUS_UNDER_VOLTAGE_BIT:
3265a56a39bSAlex Qiu 		reg = INA2XX_BUS_VOLTAGE;
3275a56a39bSAlex Qiu 		break;
3285a56a39bSAlex Qiu 	case INA226_POWER_OVER_LIMIT_BIT:
3295a56a39bSAlex Qiu 		reg = INA2XX_POWER;
3305a56a39bSAlex Qiu 		break;
3315a56a39bSAlex Qiu 	default:
3325a56a39bSAlex Qiu 		/* programmer goofed */
3335a56a39bSAlex Qiu 		WARN_ON_ONCE(1);
3345a56a39bSAlex Qiu 		return 0;
3355a56a39bSAlex Qiu 	}
3365a56a39bSAlex Qiu 
3375a56a39bSAlex Qiu 	return ina2xx_get_value(data, reg, regval);
3385a56a39bSAlex Qiu }
3395a56a39bSAlex Qiu 
3405a56a39bSAlex Qiu /*
3415a56a39bSAlex Qiu  * Turns alert limit values into register values.
3425a56a39bSAlex Qiu  * Opposite of the formula in ina2xx_get_value().
3435a56a39bSAlex Qiu  */
ina226_alert_to_reg(struct ina2xx_data * data,u8 bit,int val)3445a56a39bSAlex Qiu static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val)
3455a56a39bSAlex Qiu {
3465a56a39bSAlex Qiu 	switch (bit) {
3475a56a39bSAlex Qiu 	case INA226_SHUNT_OVER_VOLTAGE_BIT:
3485a56a39bSAlex Qiu 	case INA226_SHUNT_UNDER_VOLTAGE_BIT:
3495a56a39bSAlex Qiu 		val *= data->config->shunt_div;
3505a56a39bSAlex Qiu 		return clamp_val(val, SHRT_MIN, SHRT_MAX);
3515a56a39bSAlex Qiu 	case INA226_BUS_OVER_VOLTAGE_BIT:
3525a56a39bSAlex Qiu 	case INA226_BUS_UNDER_VOLTAGE_BIT:
3535a56a39bSAlex Qiu 		val = (val * 1000) << data->config->bus_voltage_shift;
3545a56a39bSAlex Qiu 		val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
3555a56a39bSAlex Qiu 		return clamp_val(val, 0, SHRT_MAX);
3565a56a39bSAlex Qiu 	case INA226_POWER_OVER_LIMIT_BIT:
3575a56a39bSAlex Qiu 		val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
3585a56a39bSAlex Qiu 		return clamp_val(val, 0, USHRT_MAX);
3595a56a39bSAlex Qiu 	default:
3605a56a39bSAlex Qiu 		/* programmer goofed */
3615a56a39bSAlex Qiu 		WARN_ON_ONCE(1);
3625a56a39bSAlex Qiu 		return 0;
3635a56a39bSAlex Qiu 	}
3645a56a39bSAlex Qiu }
3655a56a39bSAlex Qiu 
ina226_alert_show(struct device * dev,struct device_attribute * da,char * buf)3665a56a39bSAlex Qiu static ssize_t ina226_alert_show(struct device *dev,
3675a56a39bSAlex Qiu 				 struct device_attribute *da, char *buf)
3685a56a39bSAlex Qiu {
3695a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
3705a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
3715a56a39bSAlex Qiu 	int regval;
3725a56a39bSAlex Qiu 	int val = 0;
3735a56a39bSAlex Qiu 	int ret;
3745a56a39bSAlex Qiu 
3755a56a39bSAlex Qiu 	mutex_lock(&data->config_lock);
3765a56a39bSAlex Qiu 	ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
3775a56a39bSAlex Qiu 	if (ret)
3785a56a39bSAlex Qiu 		goto abort;
3795a56a39bSAlex Qiu 
3805a56a39bSAlex Qiu 	if (regval & BIT(attr->index)) {
3815a56a39bSAlex Qiu 		ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, &regval);
3825a56a39bSAlex Qiu 		if (ret)
3835a56a39bSAlex Qiu 			goto abort;
3845a56a39bSAlex Qiu 		val = ina226_reg_to_alert(data, attr->index, regval);
3855a56a39bSAlex Qiu 	}
3865a56a39bSAlex Qiu 
3871f4d4af4SGuenter Roeck 	ret = sysfs_emit(buf, "%d\n", val);
3885a56a39bSAlex Qiu abort:
3895a56a39bSAlex Qiu 	mutex_unlock(&data->config_lock);
3905a56a39bSAlex Qiu 	return ret;
3915a56a39bSAlex Qiu }
3925a56a39bSAlex Qiu 
ina226_alert_store(struct device * dev,struct device_attribute * da,const char * buf,size_t count)3935a56a39bSAlex Qiu static ssize_t ina226_alert_store(struct device *dev,
3945a56a39bSAlex Qiu 				  struct device_attribute *da,
3955a56a39bSAlex Qiu 				  const char *buf, size_t count)
3965a56a39bSAlex Qiu {
3975a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
3985a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
3995a56a39bSAlex Qiu 	unsigned long val;
4005a56a39bSAlex Qiu 	int ret;
4015a56a39bSAlex Qiu 
4025a56a39bSAlex Qiu 	ret = kstrtoul(buf, 10, &val);
4035a56a39bSAlex Qiu 	if (ret < 0)
4045a56a39bSAlex Qiu 		return ret;
4055a56a39bSAlex Qiu 
4065a56a39bSAlex Qiu 	/*
4075a56a39bSAlex Qiu 	 * Clear all alerts first to avoid accidentally triggering ALERT pin
4085a56a39bSAlex Qiu 	 * due to register write sequence. Then, only enable the alert
4095a56a39bSAlex Qiu 	 * if the value is non-zero.
4105a56a39bSAlex Qiu 	 */
4115a56a39bSAlex Qiu 	mutex_lock(&data->config_lock);
4125a56a39bSAlex Qiu 	ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
4135a56a39bSAlex Qiu 				 INA226_ALERT_CONFIG_MASK, 0);
4145a56a39bSAlex Qiu 	if (ret < 0)
4155a56a39bSAlex Qiu 		goto abort;
4165a56a39bSAlex Qiu 
4175a56a39bSAlex Qiu 	ret = regmap_write(data->regmap, INA226_ALERT_LIMIT,
4185a56a39bSAlex Qiu 			   ina226_alert_to_reg(data, attr->index, val));
4195a56a39bSAlex Qiu 	if (ret < 0)
4205a56a39bSAlex Qiu 		goto abort;
4215a56a39bSAlex Qiu 
4225a56a39bSAlex Qiu 	if (val != 0) {
4235a56a39bSAlex Qiu 		ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
4245a56a39bSAlex Qiu 					 INA226_ALERT_CONFIG_MASK,
4255a56a39bSAlex Qiu 					 BIT(attr->index));
4265a56a39bSAlex Qiu 		if (ret < 0)
4275a56a39bSAlex Qiu 			goto abort;
4285a56a39bSAlex Qiu 	}
4295a56a39bSAlex Qiu 
4305a56a39bSAlex Qiu 	ret = count;
4315a56a39bSAlex Qiu abort:
4325a56a39bSAlex Qiu 	mutex_unlock(&data->config_lock);
4335a56a39bSAlex Qiu 	return ret;
4345a56a39bSAlex Qiu }
4355a56a39bSAlex Qiu 
ina226_alarm_show(struct device * dev,struct device_attribute * da,char * buf)4365a56a39bSAlex Qiu static ssize_t ina226_alarm_show(struct device *dev,
4375a56a39bSAlex Qiu 				 struct device_attribute *da, char *buf)
4385a56a39bSAlex Qiu {
4395a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
4405a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
4415a56a39bSAlex Qiu 	int regval;
4425a56a39bSAlex Qiu 	int alarm = 0;
4435a56a39bSAlex Qiu 	int ret;
4445a56a39bSAlex Qiu 
4455a56a39bSAlex Qiu 	ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
4465a56a39bSAlex Qiu 	if (ret)
4475a56a39bSAlex Qiu 		return ret;
4485a56a39bSAlex Qiu 
4495a56a39bSAlex Qiu 	alarm = (regval & BIT(attr->index)) &&
4505a56a39bSAlex Qiu 		(regval & INA226_ALERT_FUNCTION_FLAG);
451af9a9730SZihao Tang 	return sysfs_emit(buf, "%d\n", alarm);
4525a56a39bSAlex Qiu }
4535a56a39bSAlex Qiu 
4545d389b12SMaciej Purski /*
4555d389b12SMaciej Purski  * In order to keep calibration register value fixed, the product
4565d389b12SMaciej Purski  * of current_lsb and shunt_resistor should also be fixed and equal
4575d389b12SMaciej Purski  * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
4585d389b12SMaciej Purski  * to keep the scale.
4595d389b12SMaciej Purski  */
ina2xx_set_shunt(struct ina2xx_data * data,long val)4605d389b12SMaciej Purski static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
4615d389b12SMaciej Purski {
4625d389b12SMaciej Purski 	unsigned int dividend = DIV_ROUND_CLOSEST(1000000000,
4635d389b12SMaciej Purski 						  data->config->shunt_div);
4645d389b12SMaciej Purski 	if (val <= 0 || val > dividend)
4655d389b12SMaciej Purski 		return -EINVAL;
4665d389b12SMaciej Purski 
4675d389b12SMaciej Purski 	mutex_lock(&data->config_lock);
4685d389b12SMaciej Purski 	data->rshunt = val;
4695d389b12SMaciej Purski 	data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val);
4705d389b12SMaciej Purski 	data->power_lsb_uW = data->config->power_lsb_factor *
4715d389b12SMaciej Purski 			     data->current_lsb_uA;
4725d389b12SMaciej Purski 	mutex_unlock(&data->config_lock);
4735d389b12SMaciej Purski 
4745d389b12SMaciej Purski 	return 0;
4755d389b12SMaciej Purski }
4765d389b12SMaciej Purski 
ina2xx_shunt_show(struct device * dev,struct device_attribute * da,char * buf)4776a0f234fSGuenter Roeck static ssize_t ina2xx_shunt_show(struct device *dev,
4786a0f234fSGuenter Roeck 				 struct device_attribute *da, char *buf)
4793ad86700SLothar Felten {
4803ad86700SLothar Felten 	struct ina2xx_data *data = dev_get_drvdata(dev);
4813ad86700SLothar Felten 
482af9a9730SZihao Tang 	return sysfs_emit(buf, "%li\n", data->rshunt);
4833ad86700SLothar Felten }
4843ad86700SLothar Felten 
ina2xx_shunt_store(struct device * dev,struct device_attribute * da,const char * buf,size_t count)4856a0f234fSGuenter Roeck static ssize_t ina2xx_shunt_store(struct device *dev,
4868a5fc795SBartosz Golaszewski 				  struct device_attribute *da,
4878a5fc795SBartosz Golaszewski 				  const char *buf, size_t count)
4888a5fc795SBartosz Golaszewski {
4898a5fc795SBartosz Golaszewski 	unsigned long val;
4908a5fc795SBartosz Golaszewski 	int status;
491a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
4928a5fc795SBartosz Golaszewski 
4938a5fc795SBartosz Golaszewski 	status = kstrtoul(buf, 10, &val);
4948a5fc795SBartosz Golaszewski 	if (status < 0)
4958a5fc795SBartosz Golaszewski 		return status;
4968a5fc795SBartosz Golaszewski 
4975d389b12SMaciej Purski 	status = ina2xx_set_shunt(data, val);
4988a5fc795SBartosz Golaszewski 	if (status < 0)
4998a5fc795SBartosz Golaszewski 		return status;
5008a5fc795SBartosz Golaszewski 	return count;
5018a5fc795SBartosz Golaszewski }
5028a5fc795SBartosz Golaszewski 
ina226_interval_store(struct device * dev,struct device_attribute * da,const char * buf,size_t count)5036a0f234fSGuenter Roeck static ssize_t ina226_interval_store(struct device *dev,
50472a87a47SBartosz Golaszewski 				     struct device_attribute *da,
50572a87a47SBartosz Golaszewski 				     const char *buf, size_t count)
50672a87a47SBartosz Golaszewski {
50772a87a47SBartosz Golaszewski 	struct ina2xx_data *data = dev_get_drvdata(dev);
50872a87a47SBartosz Golaszewski 	unsigned long val;
50972a87a47SBartosz Golaszewski 	int status;
51072a87a47SBartosz Golaszewski 
51172a87a47SBartosz Golaszewski 	status = kstrtoul(buf, 10, &val);
51272a87a47SBartosz Golaszewski 	if (status < 0)
51372a87a47SBartosz Golaszewski 		return status;
51472a87a47SBartosz Golaszewski 
51572a87a47SBartosz Golaszewski 	if (val > INT_MAX || val == 0)
51672a87a47SBartosz Golaszewski 		return -EINVAL;
51772a87a47SBartosz Golaszewski 
518a0de56c8SMarc Titinger 	status = regmap_update_bits(data->regmap, INA2XX_CONFIG,
519a0de56c8SMarc Titinger 				    INA226_AVG_RD_MASK,
520a0de56c8SMarc Titinger 				    ina226_interval_to_reg(val));
52172a87a47SBartosz Golaszewski 	if (status < 0)
52272a87a47SBartosz Golaszewski 		return status;
52372a87a47SBartosz Golaszewski 
52472a87a47SBartosz Golaszewski 	return count;
52572a87a47SBartosz Golaszewski }
52672a87a47SBartosz Golaszewski 
ina226_interval_show(struct device * dev,struct device_attribute * da,char * buf)5276a0f234fSGuenter Roeck static ssize_t ina226_interval_show(struct device *dev,
52872a87a47SBartosz Golaszewski 				    struct device_attribute *da, char *buf)
52972a87a47SBartosz Golaszewski {
530a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
531a0de56c8SMarc Titinger 	int status;
532a0de56c8SMarc Titinger 	unsigned int regval;
53372a87a47SBartosz Golaszewski 
534a0de56c8SMarc Titinger 	status = regmap_read(data->regmap, INA2XX_CONFIG, &regval);
535a0de56c8SMarc Titinger 	if (status)
536a0de56c8SMarc Titinger 		return status;
53772a87a47SBartosz Golaszewski 
538af9a9730SZihao Tang 	return sysfs_emit(buf, "%d\n", ina226_reg_to_interval(regval));
53972a87a47SBartosz Golaszewski }
54072a87a47SBartosz Golaszewski 
541f7c2fe38SFelten, Lothar /* shunt voltage */
5426a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);
5435a56a39bSAlex Qiu /* shunt voltage over/under voltage alert setting and alarm */
5445a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in0_crit, ina226_alert,
5455a56a39bSAlex Qiu 			     INA226_SHUNT_OVER_VOLTAGE_BIT);
5465a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in0_lcrit, ina226_alert,
5475a56a39bSAlex Qiu 			     INA226_SHUNT_UNDER_VOLTAGE_BIT);
5485a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in0_crit_alarm, ina226_alarm,
5495a56a39bSAlex Qiu 			     INA226_SHUNT_OVER_VOLTAGE_BIT);
5505a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in0_lcrit_alarm, ina226_alarm,
5515a56a39bSAlex Qiu 			     INA226_SHUNT_UNDER_VOLTAGE_BIT);
552f7c2fe38SFelten, Lothar 
553f7c2fe38SFelten, Lothar /* bus voltage */
5546a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
5555a56a39bSAlex Qiu /* bus voltage over/under voltage alert setting and alarm */
5565a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in1_crit, ina226_alert,
5575a56a39bSAlex Qiu 			     INA226_BUS_OVER_VOLTAGE_BIT);
5585a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in1_lcrit, ina226_alert,
5595a56a39bSAlex Qiu 			     INA226_BUS_UNDER_VOLTAGE_BIT);
5605a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in1_crit_alarm, ina226_alarm,
5615a56a39bSAlex Qiu 			     INA226_BUS_OVER_VOLTAGE_BIT);
5625a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in1_lcrit_alarm, ina226_alarm,
5635a56a39bSAlex Qiu 			     INA226_BUS_UNDER_VOLTAGE_BIT);
564f7c2fe38SFelten, Lothar 
565f7c2fe38SFelten, Lothar /* calculated current */
5666a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT);
567f7c2fe38SFelten, Lothar 
568f7c2fe38SFelten, Lothar /* calculated power */
5696a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER);
5705a56a39bSAlex Qiu /* over-limit power alert setting and alarm */
5715a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(power1_crit, ina226_alert,
5725a56a39bSAlex Qiu 			     INA226_POWER_OVER_LIMIT_BIT);
5735a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina226_alarm,
5745a56a39bSAlex Qiu 			     INA226_POWER_OVER_LIMIT_BIT);
575f7c2fe38SFelten, Lothar 
5768a5fc795SBartosz Golaszewski /* shunt resistance */
5776a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION);
5788a5fc795SBartosz Golaszewski 
57972a87a47SBartosz Golaszewski /* update interval (ina226 only) */
5806a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0);
58172a87a47SBartosz Golaszewski 
582f7c2fe38SFelten, Lothar /* pointers to created device attributes */
583468bf0e3SGuenter Roeck static struct attribute *ina2xx_attrs[] = {
584f7c2fe38SFelten, Lothar 	&sensor_dev_attr_in0_input.dev_attr.attr,
585f7c2fe38SFelten, Lothar 	&sensor_dev_attr_in1_input.dev_attr.attr,
586f7c2fe38SFelten, Lothar 	&sensor_dev_attr_curr1_input.dev_attr.attr,
587f7c2fe38SFelten, Lothar 	&sensor_dev_attr_power1_input.dev_attr.attr,
5888a5fc795SBartosz Golaszewski 	&sensor_dev_attr_shunt_resistor.dev_attr.attr,
589f7c2fe38SFelten, Lothar 	NULL,
590f7c2fe38SFelten, Lothar };
59172a87a47SBartosz Golaszewski 
59272a87a47SBartosz Golaszewski static const struct attribute_group ina2xx_group = {
59372a87a47SBartosz Golaszewski 	.attrs = ina2xx_attrs,
59472a87a47SBartosz Golaszewski };
59572a87a47SBartosz Golaszewski 
59672a87a47SBartosz Golaszewski static struct attribute *ina226_attrs[] = {
5975a56a39bSAlex Qiu 	&sensor_dev_attr_in0_crit.dev_attr.attr,
5985a56a39bSAlex Qiu 	&sensor_dev_attr_in0_lcrit.dev_attr.attr,
5995a56a39bSAlex Qiu 	&sensor_dev_attr_in0_crit_alarm.dev_attr.attr,
6005a56a39bSAlex Qiu 	&sensor_dev_attr_in0_lcrit_alarm.dev_attr.attr,
6015a56a39bSAlex Qiu 	&sensor_dev_attr_in1_crit.dev_attr.attr,
6025a56a39bSAlex Qiu 	&sensor_dev_attr_in1_lcrit.dev_attr.attr,
6035a56a39bSAlex Qiu 	&sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
6045a56a39bSAlex Qiu 	&sensor_dev_attr_in1_lcrit_alarm.dev_attr.attr,
6055a56a39bSAlex Qiu 	&sensor_dev_attr_power1_crit.dev_attr.attr,
6065a56a39bSAlex Qiu 	&sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
60772a87a47SBartosz Golaszewski 	&sensor_dev_attr_update_interval.dev_attr.attr,
60872a87a47SBartosz Golaszewski 	NULL,
60972a87a47SBartosz Golaszewski };
61072a87a47SBartosz Golaszewski 
61172a87a47SBartosz Golaszewski static const struct attribute_group ina226_group = {
61272a87a47SBartosz Golaszewski 	.attrs = ina226_attrs,
61372a87a47SBartosz Golaszewski };
614f7c2fe38SFelten, Lothar 
61567487038SStephen Kitt static const struct i2c_device_id ina2xx_id[];
61667487038SStephen Kitt 
ina2xx_probe(struct i2c_client * client)61767487038SStephen Kitt static int ina2xx_probe(struct i2c_client *client)
618f7c2fe38SFelten, Lothar {
619468bf0e3SGuenter Roeck 	struct device *dev = &client->dev;
620468bf0e3SGuenter Roeck 	struct ina2xx_data *data;
621468bf0e3SGuenter Roeck 	struct device *hwmon_dev;
622468bf0e3SGuenter Roeck 	u32 val;
62372a87a47SBartosz Golaszewski 	int ret, group = 0;
624bd0ddd4dSJavier Martinez Canillas 	enum ina2xx_ids chip;
625bd0ddd4dSJavier Martinez Canillas 
626bd0ddd4dSJavier Martinez Canillas 	if (client->dev.of_node)
627*4a2a41dfSKrzysztof Kozlowski 		chip = (uintptr_t)of_device_get_match_data(&client->dev);
628bd0ddd4dSJavier Martinez Canillas 	else
62967487038SStephen Kitt 		chip = i2c_match_id(ina2xx_id, client)->driver_data;
630f7c2fe38SFelten, Lothar 
631468bf0e3SGuenter Roeck 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
632f7c2fe38SFelten, Lothar 	if (!data)
633f7c2fe38SFelten, Lothar 		return -ENOMEM;
634f7c2fe38SFelten, Lothar 
635f7c2fe38SFelten, Lothar 	/* set the device type */
636bd0ddd4dSJavier Martinez Canillas 	data->config = &ina2xx_config[chip];
6370c4c5860SMarek Szyprowski 	mutex_init(&data->config_lock);
63872a87a47SBartosz Golaszewski 
639001e2e73SMarc Titinger 	if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) {
640001e2e73SMarc Titinger 		struct ina2xx_platform_data *pdata = dev_get_platdata(dev);
641001e2e73SMarc Titinger 
642001e2e73SMarc Titinger 		if (pdata)
643001e2e73SMarc Titinger 			val = pdata->shunt_uohms;
644001e2e73SMarc Titinger 		else
645001e2e73SMarc Titinger 			val = INA2XX_RSHUNT_DEFAULT;
646001e2e73SMarc Titinger 	}
647001e2e73SMarc Titinger 
6485d389b12SMaciej Purski 	ina2xx_set_shunt(data, val);
649001e2e73SMarc Titinger 
650a0de56c8SMarc Titinger 	ina2xx_regmap_config.max_register = data->config->registers;
651a0de56c8SMarc Titinger 
652a0de56c8SMarc Titinger 	data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config);
653a0de56c8SMarc Titinger 	if (IS_ERR(data->regmap)) {
654a0de56c8SMarc Titinger 		dev_err(dev, "failed to allocate register map\n");
655a0de56c8SMarc Titinger 		return PTR_ERR(data->regmap);
656a0de56c8SMarc Titinger 	}
657a0de56c8SMarc Titinger 
658ad20248aSSvyatoslav Ryhel 	ret = devm_regulator_get_enable(dev, "vs");
659ad20248aSSvyatoslav Ryhel 	if (ret)
660ad20248aSSvyatoslav Ryhel 		return dev_err_probe(dev, ret, "failed to enable vs regulator\n");
661ad20248aSSvyatoslav Ryhel 
662509416a8SBartosz Golaszewski 	ret = ina2xx_init(data);
663509416a8SBartosz Golaszewski 	if (ret < 0) {
664509416a8SBartosz Golaszewski 		dev_err(dev, "error configuring the device: %d\n", ret);
665509416a8SBartosz Golaszewski 		return -ENODEV;
666509416a8SBartosz Golaszewski 	}
667509416a8SBartosz Golaszewski 
66872a87a47SBartosz Golaszewski 	data->groups[group++] = &ina2xx_group;
66970df9ebbSNicolin Chen 	if (chip == ina226)
67072a87a47SBartosz Golaszewski 		data->groups[group++] = &ina226_group;
67172a87a47SBartosz Golaszewski 
672468bf0e3SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
67372a87a47SBartosz Golaszewski 							   data, data->groups);
674468bf0e3SGuenter Roeck 	if (IS_ERR(hwmon_dev))
675468bf0e3SGuenter Roeck 		return PTR_ERR(hwmon_dev);
676f7c2fe38SFelten, Lothar 
677468bf0e3SGuenter Roeck 	dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",
67870df9ebbSNicolin Chen 		 client->name, data->rshunt);
6796106db25SGuenter Roeck 
680f7c2fe38SFelten, Lothar 	return 0;
681f7c2fe38SFelten, Lothar }
682f7c2fe38SFelten, Lothar 
683f7c2fe38SFelten, Lothar static const struct i2c_device_id ina2xx_id[] = {
684f7c2fe38SFelten, Lothar 	{ "ina219", ina219 },
685dc92cd0cSGuenter Roeck 	{ "ina220", ina219 },
686f7c2fe38SFelten, Lothar 	{ "ina226", ina226 },
687dc92cd0cSGuenter Roeck 	{ "ina230", ina226 },
688add513beSKevin Hilman 	{ "ina231", ina226 },
689f7c2fe38SFelten, Lothar 	{ }
690f7c2fe38SFelten, Lothar };
691f7c2fe38SFelten, Lothar MODULE_DEVICE_TABLE(i2c, ina2xx_id);
692f7c2fe38SFelten, Lothar 
693df6b8c70SGuenter Roeck static const struct of_device_id __maybe_unused ina2xx_of_match[] = {
694bd0ddd4dSJavier Martinez Canillas 	{
695bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina219",
696bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina219
697bd0ddd4dSJavier Martinez Canillas 	},
698bd0ddd4dSJavier Martinez Canillas 	{
699bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina220",
700bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina219
701bd0ddd4dSJavier Martinez Canillas 	},
702bd0ddd4dSJavier Martinez Canillas 	{
703bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina226",
704bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
705bd0ddd4dSJavier Martinez Canillas 	},
706bd0ddd4dSJavier Martinez Canillas 	{
707bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina230",
708bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
709bd0ddd4dSJavier Martinez Canillas 	},
710bd0ddd4dSJavier Martinez Canillas 	{
711bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina231",
712bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
713bd0ddd4dSJavier Martinez Canillas 	},
714bd0ddd4dSJavier Martinez Canillas 	{ },
715bd0ddd4dSJavier Martinez Canillas };
716bd0ddd4dSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, ina2xx_of_match);
717bd0ddd4dSJavier Martinez Canillas 
718f7c2fe38SFelten, Lothar static struct i2c_driver ina2xx_driver = {
719f7c2fe38SFelten, Lothar 	.driver = {
720f7c2fe38SFelten, Lothar 		.name	= "ina2xx",
721bd0ddd4dSJavier Martinez Canillas 		.of_match_table = of_match_ptr(ina2xx_of_match),
722f7c2fe38SFelten, Lothar 	},
7231975d167SUwe Kleine-König 	.probe		= ina2xx_probe,
724f7c2fe38SFelten, Lothar 	.id_table	= ina2xx_id,
725f7c2fe38SFelten, Lothar };
726f7c2fe38SFelten, Lothar 
727d835ca0fSWei Yongjun module_i2c_driver(ina2xx_driver);
728f7c2fe38SFelten, Lothar 
729f7c2fe38SFelten, Lothar MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");
730f7c2fe38SFelten, Lothar MODULE_DESCRIPTION("ina2xx driver");
731f7c2fe38SFelten, Lothar MODULE_LICENSE("GPL");
732