xref: /linux/drivers/hwmon/ina2xx.c (revision 6748703856d461f8cd62b72ebca51040e06cb310)
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>
34bd0ddd4dSJavier Martinez Canillas #include <linux/of_device.h>
3531e7ad74STang Yuantian #include <linux/of.h>
36509416a8SBartosz Golaszewski #include <linux/delay.h>
37d38df34eSBartosz Golaszewski #include <linux/util_macros.h>
38a0de56c8SMarc Titinger #include <linux/regmap.h>
39f7c2fe38SFelten, Lothar 
40f7c2fe38SFelten, Lothar #include <linux/platform_data/ina2xx.h>
41f7c2fe38SFelten, Lothar 
42f7c2fe38SFelten, Lothar /* common register definitions */
43f7c2fe38SFelten, Lothar #define INA2XX_CONFIG			0x00
44f7c2fe38SFelten, Lothar #define INA2XX_SHUNT_VOLTAGE		0x01 /* readonly */
45f7c2fe38SFelten, Lothar #define INA2XX_BUS_VOLTAGE		0x02 /* readonly */
46f7c2fe38SFelten, Lothar #define INA2XX_POWER			0x03 /* readonly */
47f7c2fe38SFelten, Lothar #define INA2XX_CURRENT			0x04 /* readonly */
48f7c2fe38SFelten, Lothar #define INA2XX_CALIBRATION		0x05
49f7c2fe38SFelten, Lothar 
50f7c2fe38SFelten, Lothar /* INA226 register definitions */
51f7c2fe38SFelten, Lothar #define INA226_MASK_ENABLE		0x06
52f7c2fe38SFelten, Lothar #define INA226_ALERT_LIMIT		0x07
53f7c2fe38SFelten, Lothar #define INA226_DIE_ID			0xFF
54f7c2fe38SFelten, Lothar 
55f7c2fe38SFelten, Lothar /* register count */
56f7c2fe38SFelten, Lothar #define INA219_REGISTERS		6
57f7c2fe38SFelten, Lothar #define INA226_REGISTERS		8
58f7c2fe38SFelten, Lothar 
59f7c2fe38SFelten, Lothar #define INA2XX_MAX_REGISTERS		8
60f7c2fe38SFelten, Lothar 
61f7c2fe38SFelten, Lothar /* settings - depend on use case */
62f7c2fe38SFelten, Lothar #define INA219_CONFIG_DEFAULT		0x399F	/* PGA=8 */
63f7c2fe38SFelten, Lothar #define INA226_CONFIG_DEFAULT		0x4527	/* averages=16 */
64f7c2fe38SFelten, Lothar 
65f7c2fe38SFelten, Lothar /* worst case is 68.10 ms (~14.6Hz, ina219) */
66f7c2fe38SFelten, Lothar #define INA2XX_CONVERSION_RATE		15
67509416a8SBartosz Golaszewski #define INA2XX_MAX_DELAY		69 /* worst case delay in ms */
68509416a8SBartosz Golaszewski 
69509416a8SBartosz Golaszewski #define INA2XX_RSHUNT_DEFAULT		10000
70f7c2fe38SFelten, Lothar 
7172a87a47SBartosz Golaszewski /* bit mask for reading the averaging setting in the configuration register */
7272a87a47SBartosz Golaszewski #define INA226_AVG_RD_MASK		0x0E00
7372a87a47SBartosz Golaszewski 
7472a87a47SBartosz Golaszewski #define INA226_READ_AVG(reg)		(((reg) & INA226_AVG_RD_MASK) >> 9)
7572a87a47SBartosz Golaszewski #define INA226_SHIFT_AVG(val)		((val) << 9)
7672a87a47SBartosz Golaszewski 
775a56a39bSAlex Qiu /* bit number of alert functions in Mask/Enable Register */
785a56a39bSAlex Qiu #define INA226_SHUNT_OVER_VOLTAGE_BIT	15
795a56a39bSAlex Qiu #define INA226_SHUNT_UNDER_VOLTAGE_BIT	14
805a56a39bSAlex Qiu #define INA226_BUS_OVER_VOLTAGE_BIT	13
815a56a39bSAlex Qiu #define INA226_BUS_UNDER_VOLTAGE_BIT	12
825a56a39bSAlex Qiu #define INA226_POWER_OVER_LIMIT_BIT	11
835a56a39bSAlex Qiu 
845a56a39bSAlex Qiu /* bit mask for alert config bits of Mask/Enable Register */
855a56a39bSAlex Qiu #define INA226_ALERT_CONFIG_MASK	0xFC00
865a56a39bSAlex Qiu #define INA226_ALERT_FUNCTION_FLAG	BIT(4)
875a56a39bSAlex Qiu 
8872a87a47SBartosz Golaszewski /* common attrs, ina226 attrs and NULL */
8972a87a47SBartosz Golaszewski #define INA2XX_MAX_ATTRIBUTE_GROUPS	3
9072a87a47SBartosz Golaszewski 
9172a87a47SBartosz Golaszewski /*
9272a87a47SBartosz Golaszewski  * Both bus voltage and shunt voltage conversion times for ina226 are set
9372a87a47SBartosz Golaszewski  * to 0b0100 on POR, which translates to 2200 microseconds in total.
9472a87a47SBartosz Golaszewski  */
9572a87a47SBartosz Golaszewski #define INA226_TOTAL_CONV_TIME_DEFAULT	2200
9672a87a47SBartosz Golaszewski 
97a0de56c8SMarc Titinger static struct regmap_config ina2xx_regmap_config = {
98a0de56c8SMarc Titinger 	.reg_bits = 8,
99a0de56c8SMarc Titinger 	.val_bits = 16,
100a0de56c8SMarc Titinger };
101a0de56c8SMarc Titinger 
102f7c2fe38SFelten, Lothar enum ina2xx_ids { ina219, ina226 };
103f7c2fe38SFelten, Lothar 
1046106db25SGuenter Roeck struct ina2xx_config {
1056106db25SGuenter Roeck 	u16 config_default;
1065d389b12SMaciej Purski 	int calibration_value;
1076106db25SGuenter Roeck 	int registers;
1086106db25SGuenter Roeck 	int shunt_div;
1096106db25SGuenter Roeck 	int bus_voltage_shift;
1106106db25SGuenter Roeck 	int bus_voltage_lsb;	/* uV */
1115d389b12SMaciej Purski 	int power_lsb_factor;
1126106db25SGuenter Roeck };
1136106db25SGuenter Roeck 
114f7c2fe38SFelten, Lothar struct ina2xx_data {
1156106db25SGuenter Roeck 	const struct ina2xx_config *config;
116f7c2fe38SFelten, Lothar 
117509416a8SBartosz Golaszewski 	long rshunt;
1185d389b12SMaciej Purski 	long current_lsb_uA;
1195d389b12SMaciej Purski 	long power_lsb_uW;
120a0de56c8SMarc Titinger 	struct mutex config_lock;
121a0de56c8SMarc Titinger 	struct regmap *regmap;
122f7c2fe38SFelten, Lothar 
12372a87a47SBartosz Golaszewski 	const struct attribute_group *groups[INA2XX_MAX_ATTRIBUTE_GROUPS];
124f7c2fe38SFelten, Lothar };
125f7c2fe38SFelten, Lothar 
1266106db25SGuenter Roeck static const struct ina2xx_config ina2xx_config[] = {
1276106db25SGuenter Roeck 	[ina219] = {
1286106db25SGuenter Roeck 		.config_default = INA219_CONFIG_DEFAULT,
1295d389b12SMaciej Purski 		.calibration_value = 4096,
1306106db25SGuenter Roeck 		.registers = INA219_REGISTERS,
1316106db25SGuenter Roeck 		.shunt_div = 100,
1326106db25SGuenter Roeck 		.bus_voltage_shift = 3,
1336106db25SGuenter Roeck 		.bus_voltage_lsb = 4000,
1345d389b12SMaciej Purski 		.power_lsb_factor = 20,
1356106db25SGuenter Roeck 	},
1366106db25SGuenter Roeck 	[ina226] = {
1376106db25SGuenter Roeck 		.config_default = INA226_CONFIG_DEFAULT,
1385d389b12SMaciej Purski 		.calibration_value = 2048,
1396106db25SGuenter Roeck 		.registers = INA226_REGISTERS,
1406106db25SGuenter Roeck 		.shunt_div = 400,
1416106db25SGuenter Roeck 		.bus_voltage_shift = 0,
1426106db25SGuenter Roeck 		.bus_voltage_lsb = 1250,
1435d389b12SMaciej Purski 		.power_lsb_factor = 25,
1446106db25SGuenter Roeck 	},
1456106db25SGuenter Roeck };
1466106db25SGuenter Roeck 
14772a87a47SBartosz Golaszewski /*
14872a87a47SBartosz Golaszewski  * Available averaging rates for ina226. The indices correspond with
14972a87a47SBartosz Golaszewski  * the bit values expected by the chip (according to the ina226 datasheet,
15072a87a47SBartosz Golaszewski  * table 3 AVG bit settings, found at
15149dc2fb0SAlexander A. Klimov  * https://www.ti.com/lit/ds/symlink/ina226.pdf.
15272a87a47SBartosz Golaszewski  */
15372a87a47SBartosz Golaszewski static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
15472a87a47SBartosz Golaszewski 
15572a87a47SBartosz Golaszewski static int ina226_reg_to_interval(u16 config)
15672a87a47SBartosz Golaszewski {
15772a87a47SBartosz Golaszewski 	int avg = ina226_avg_tab[INA226_READ_AVG(config)];
15872a87a47SBartosz Golaszewski 
15972a87a47SBartosz Golaszewski 	/*
16072a87a47SBartosz Golaszewski 	 * Multiply the total conversion time by the number of averages.
16172a87a47SBartosz Golaszewski 	 * Return the result in milliseconds.
16272a87a47SBartosz Golaszewski 	 */
16372a87a47SBartosz Golaszewski 	return DIV_ROUND_CLOSEST(avg * INA226_TOTAL_CONV_TIME_DEFAULT, 1000);
16472a87a47SBartosz Golaszewski }
16572a87a47SBartosz Golaszewski 
166a0de56c8SMarc Titinger /*
167a0de56c8SMarc Titinger  * Return the new, shifted AVG field value of CONFIG register,
168a0de56c8SMarc Titinger  * to use with regmap_update_bits
169a0de56c8SMarc Titinger  */
170a0de56c8SMarc Titinger static u16 ina226_interval_to_reg(int interval)
17172a87a47SBartosz Golaszewski {
17272a87a47SBartosz Golaszewski 	int avg, avg_bits;
17372a87a47SBartosz Golaszewski 
17472a87a47SBartosz Golaszewski 	avg = DIV_ROUND_CLOSEST(interval * 1000,
17572a87a47SBartosz Golaszewski 				INA226_TOTAL_CONV_TIME_DEFAULT);
176d38df34eSBartosz Golaszewski 	avg_bits = find_closest(avg, ina226_avg_tab,
177d38df34eSBartosz Golaszewski 				ARRAY_SIZE(ina226_avg_tab));
17872a87a47SBartosz Golaszewski 
179a0de56c8SMarc Titinger 	return INA226_SHIFT_AVG(avg_bits);
18072a87a47SBartosz Golaszewski }
18172a87a47SBartosz Golaszewski 
1825d389b12SMaciej Purski /*
1835d389b12SMaciej Purski  * Calibration register is set to the best value, which eliminates
1845d389b12SMaciej Purski  * truncation errors on calculating current register in hardware.
1855d389b12SMaciej Purski  * According to datasheet (eq. 3) the best values are 2048 for
1865d389b12SMaciej Purski  * ina226 and 4096 for ina219. They are hardcoded as calibration_value.
1875d389b12SMaciej Purski  */
1888a5fc795SBartosz Golaszewski static int ina2xx_calibrate(struct ina2xx_data *data)
1898a5fc795SBartosz Golaszewski {
1905d389b12SMaciej Purski 	return regmap_write(data->regmap, INA2XX_CALIBRATION,
1915d389b12SMaciej Purski 			    data->config->calibration_value);
1928a5fc795SBartosz Golaszewski }
1938a5fc795SBartosz Golaszewski 
194509416a8SBartosz Golaszewski /*
195509416a8SBartosz Golaszewski  * Initialize the configuration and calibration registers.
196509416a8SBartosz Golaszewski  */
197509416a8SBartosz Golaszewski static int ina2xx_init(struct ina2xx_data *data)
198509416a8SBartosz Golaszewski {
199a0de56c8SMarc Titinger 	int ret = regmap_write(data->regmap, INA2XX_CONFIG,
200a0de56c8SMarc Titinger 			       data->config->config_default);
201509416a8SBartosz Golaszewski 	if (ret < 0)
202509416a8SBartosz Golaszewski 		return ret;
203509416a8SBartosz Golaszewski 
2048a5fc795SBartosz Golaszewski 	return ina2xx_calibrate(data);
205509416a8SBartosz Golaszewski }
206509416a8SBartosz Golaszewski 
207a0de56c8SMarc Titinger static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval)
208f7c2fe38SFelten, Lothar {
209468bf0e3SGuenter Roeck 	struct ina2xx_data *data = dev_get_drvdata(dev);
210a0de56c8SMarc Titinger 	int ret, retry;
211509416a8SBartosz Golaszewski 
212a0de56c8SMarc Titinger 	dev_dbg(dev, "Starting register %d read\n", reg);
213509416a8SBartosz Golaszewski 
214509416a8SBartosz Golaszewski 	for (retry = 5; retry; retry--) {
215a0de56c8SMarc Titinger 
216a0de56c8SMarc Titinger 		ret = regmap_read(data->regmap, reg, regval);
217a0de56c8SMarc Titinger 		if (ret < 0)
218a0de56c8SMarc Titinger 			return ret;
219a0de56c8SMarc Titinger 
220a0de56c8SMarc Titinger 		dev_dbg(dev, "read %d, val = 0x%04x\n", reg, *regval);
221509416a8SBartosz Golaszewski 
222509416a8SBartosz Golaszewski 		/*
223509416a8SBartosz Golaszewski 		 * If the current value in the calibration register is 0, the
224509416a8SBartosz Golaszewski 		 * power and current registers will also remain at 0. In case
225509416a8SBartosz Golaszewski 		 * the chip has been reset let's check the calibration
226509416a8SBartosz Golaszewski 		 * register and reinitialize if needed.
227a0de56c8SMarc Titinger 		 * We do that extra read of the calibration register if there
228a0de56c8SMarc Titinger 		 * is some hint of a chip reset.
229509416a8SBartosz Golaszewski 		 */
230a0de56c8SMarc Titinger 		if (*regval == 0) {
231a0de56c8SMarc Titinger 			unsigned int cal;
232a0de56c8SMarc Titinger 
233a0de56c8SMarc Titinger 			ret = regmap_read(data->regmap, INA2XX_CALIBRATION,
234a0de56c8SMarc Titinger 					  &cal);
235a0de56c8SMarc Titinger 			if (ret < 0)
236a0de56c8SMarc Titinger 				return ret;
237a0de56c8SMarc Titinger 
238a0de56c8SMarc Titinger 			if (cal == 0) {
239509416a8SBartosz Golaszewski 				dev_warn(dev, "chip not calibrated, reinitializing\n");
240509416a8SBartosz Golaszewski 
241a0de56c8SMarc Titinger 				ret = ina2xx_init(data);
242a0de56c8SMarc Titinger 				if (ret < 0)
243a0de56c8SMarc Titinger 					return ret;
244509416a8SBartosz Golaszewski 				/*
245a0de56c8SMarc Titinger 				 * Let's make sure the power and current
246a0de56c8SMarc Titinger 				 * registers have been updated before trying
247a0de56c8SMarc Titinger 				 * again.
248509416a8SBartosz Golaszewski 				 */
249509416a8SBartosz Golaszewski 				msleep(INA2XX_MAX_DELAY);
250509416a8SBartosz Golaszewski 				continue;
251509416a8SBartosz Golaszewski 			}
252a0de56c8SMarc Titinger 		}
253509416a8SBartosz Golaszewski 		return 0;
254509416a8SBartosz Golaszewski 	}
255509416a8SBartosz Golaszewski 
256509416a8SBartosz Golaszewski 	/*
257509416a8SBartosz Golaszewski 	 * If we're here then although all write operations succeeded, the
258509416a8SBartosz Golaszewski 	 * chip still returns 0 in the calibration register. Nothing more we
259509416a8SBartosz Golaszewski 	 * can do here.
260509416a8SBartosz Golaszewski 	 */
261509416a8SBartosz Golaszewski 	dev_err(dev, "unable to reinitialize the chip\n");
262509416a8SBartosz Golaszewski 	return -ENODEV;
263509416a8SBartosz Golaszewski }
264509416a8SBartosz Golaszewski 
265a0de56c8SMarc Titinger static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
266a0de56c8SMarc Titinger 			    unsigned int regval)
267f7c2fe38SFelten, Lothar {
2686106db25SGuenter Roeck 	int val;
269f7c2fe38SFelten, Lothar 
270f7c2fe38SFelten, Lothar 	switch (reg) {
271f7c2fe38SFelten, Lothar 	case INA2XX_SHUNT_VOLTAGE:
272c0214f98SFabio Baltieri 		/* signed register */
273a0de56c8SMarc Titinger 		val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div);
274f7c2fe38SFelten, Lothar 		break;
275f7c2fe38SFelten, Lothar 	case INA2XX_BUS_VOLTAGE:
276a0de56c8SMarc Titinger 		val = (regval >> data->config->bus_voltage_shift)
2776106db25SGuenter Roeck 		  * data->config->bus_voltage_lsb;
2786106db25SGuenter Roeck 		val = DIV_ROUND_CLOSEST(val, 1000);
279f7c2fe38SFelten, Lothar 		break;
280f7c2fe38SFelten, Lothar 	case INA2XX_POWER:
2815d389b12SMaciej Purski 		val = regval * data->power_lsb_uW;
282f7c2fe38SFelten, Lothar 		break;
283f7c2fe38SFelten, Lothar 	case INA2XX_CURRENT:
2845d389b12SMaciej Purski 		/* signed register, result in mA */
28538cd989eSNicolin Chen 		val = (s16)regval * data->current_lsb_uA;
2865d389b12SMaciej Purski 		val = DIV_ROUND_CLOSEST(val, 1000);
287f7c2fe38SFelten, Lothar 		break;
2888a5fc795SBartosz Golaszewski 	case INA2XX_CALIBRATION:
2895d389b12SMaciej Purski 		val = regval;
2908a5fc795SBartosz Golaszewski 		break;
291f7c2fe38SFelten, Lothar 	default:
292f7c2fe38SFelten, Lothar 		/* programmer goofed */
293f7c2fe38SFelten, Lothar 		WARN_ON_ONCE(1);
294f7c2fe38SFelten, Lothar 		val = 0;
295f7c2fe38SFelten, Lothar 		break;
296f7c2fe38SFelten, Lothar 	}
297f7c2fe38SFelten, Lothar 
298f7c2fe38SFelten, Lothar 	return val;
299f7c2fe38SFelten, Lothar }
300f7c2fe38SFelten, Lothar 
3016a0f234fSGuenter Roeck static ssize_t ina2xx_value_show(struct device *dev,
302f7c2fe38SFelten, Lothar 				 struct device_attribute *da, char *buf)
303f7c2fe38SFelten, Lothar {
304f7c2fe38SFelten, Lothar 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
305a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
306a0de56c8SMarc Titinger 	unsigned int regval;
307f7c2fe38SFelten, Lothar 
308a0de56c8SMarc Titinger 	int err = ina2xx_read_reg(dev, attr->index, &regval);
309a0de56c8SMarc Titinger 
310a0de56c8SMarc Titinger 	if (err < 0)
311a0de56c8SMarc Titinger 		return err;
312f7c2fe38SFelten, Lothar 
3136106db25SGuenter Roeck 	return snprintf(buf, PAGE_SIZE, "%d\n",
314a0de56c8SMarc Titinger 			ina2xx_get_value(data, attr->index, regval));
315f7c2fe38SFelten, Lothar }
316f7c2fe38SFelten, Lothar 
3175a56a39bSAlex Qiu static int ina226_reg_to_alert(struct ina2xx_data *data, u8 bit, u16 regval)
3185a56a39bSAlex Qiu {
3195a56a39bSAlex Qiu 	int reg;
3205a56a39bSAlex Qiu 
3215a56a39bSAlex Qiu 	switch (bit) {
3225a56a39bSAlex Qiu 	case INA226_SHUNT_OVER_VOLTAGE_BIT:
3235a56a39bSAlex Qiu 	case INA226_SHUNT_UNDER_VOLTAGE_BIT:
3245a56a39bSAlex Qiu 		reg = INA2XX_SHUNT_VOLTAGE;
3255a56a39bSAlex Qiu 		break;
3265a56a39bSAlex Qiu 	case INA226_BUS_OVER_VOLTAGE_BIT:
3275a56a39bSAlex Qiu 	case INA226_BUS_UNDER_VOLTAGE_BIT:
3285a56a39bSAlex Qiu 		reg = INA2XX_BUS_VOLTAGE;
3295a56a39bSAlex Qiu 		break;
3305a56a39bSAlex Qiu 	case INA226_POWER_OVER_LIMIT_BIT:
3315a56a39bSAlex Qiu 		reg = INA2XX_POWER;
3325a56a39bSAlex Qiu 		break;
3335a56a39bSAlex Qiu 	default:
3345a56a39bSAlex Qiu 		/* programmer goofed */
3355a56a39bSAlex Qiu 		WARN_ON_ONCE(1);
3365a56a39bSAlex Qiu 		return 0;
3375a56a39bSAlex Qiu 	}
3385a56a39bSAlex Qiu 
3395a56a39bSAlex Qiu 	return ina2xx_get_value(data, reg, regval);
3405a56a39bSAlex Qiu }
3415a56a39bSAlex Qiu 
3425a56a39bSAlex Qiu /*
3435a56a39bSAlex Qiu  * Turns alert limit values into register values.
3445a56a39bSAlex Qiu  * Opposite of the formula in ina2xx_get_value().
3455a56a39bSAlex Qiu  */
3465a56a39bSAlex Qiu static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val)
3475a56a39bSAlex Qiu {
3485a56a39bSAlex Qiu 	switch (bit) {
3495a56a39bSAlex Qiu 	case INA226_SHUNT_OVER_VOLTAGE_BIT:
3505a56a39bSAlex Qiu 	case INA226_SHUNT_UNDER_VOLTAGE_BIT:
3515a56a39bSAlex Qiu 		val *= data->config->shunt_div;
3525a56a39bSAlex Qiu 		return clamp_val(val, SHRT_MIN, SHRT_MAX);
3535a56a39bSAlex Qiu 	case INA226_BUS_OVER_VOLTAGE_BIT:
3545a56a39bSAlex Qiu 	case INA226_BUS_UNDER_VOLTAGE_BIT:
3555a56a39bSAlex Qiu 		val = (val * 1000) << data->config->bus_voltage_shift;
3565a56a39bSAlex Qiu 		val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
3575a56a39bSAlex Qiu 		return clamp_val(val, 0, SHRT_MAX);
3585a56a39bSAlex Qiu 	case INA226_POWER_OVER_LIMIT_BIT:
3595a56a39bSAlex Qiu 		val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
3605a56a39bSAlex Qiu 		return clamp_val(val, 0, USHRT_MAX);
3615a56a39bSAlex Qiu 	default:
3625a56a39bSAlex Qiu 		/* programmer goofed */
3635a56a39bSAlex Qiu 		WARN_ON_ONCE(1);
3645a56a39bSAlex Qiu 		return 0;
3655a56a39bSAlex Qiu 	}
3665a56a39bSAlex Qiu }
3675a56a39bSAlex Qiu 
3685a56a39bSAlex Qiu static ssize_t ina226_alert_show(struct device *dev,
3695a56a39bSAlex Qiu 				 struct device_attribute *da, char *buf)
3705a56a39bSAlex Qiu {
3715a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
3725a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
3735a56a39bSAlex Qiu 	int regval;
3745a56a39bSAlex Qiu 	int val = 0;
3755a56a39bSAlex Qiu 	int ret;
3765a56a39bSAlex Qiu 
3775a56a39bSAlex Qiu 	mutex_lock(&data->config_lock);
3785a56a39bSAlex Qiu 	ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
3795a56a39bSAlex Qiu 	if (ret)
3805a56a39bSAlex Qiu 		goto abort;
3815a56a39bSAlex Qiu 
3825a56a39bSAlex Qiu 	if (regval & BIT(attr->index)) {
3835a56a39bSAlex Qiu 		ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, &regval);
3845a56a39bSAlex Qiu 		if (ret)
3855a56a39bSAlex Qiu 			goto abort;
3865a56a39bSAlex Qiu 		val = ina226_reg_to_alert(data, attr->index, regval);
3875a56a39bSAlex Qiu 	}
3885a56a39bSAlex Qiu 
3895a56a39bSAlex Qiu 	ret = snprintf(buf, PAGE_SIZE, "%d\n", val);
3905a56a39bSAlex Qiu abort:
3915a56a39bSAlex Qiu 	mutex_unlock(&data->config_lock);
3925a56a39bSAlex Qiu 	return ret;
3935a56a39bSAlex Qiu }
3945a56a39bSAlex Qiu 
3955a56a39bSAlex Qiu static ssize_t ina226_alert_store(struct device *dev,
3965a56a39bSAlex Qiu 				  struct device_attribute *da,
3975a56a39bSAlex Qiu 				  const char *buf, size_t count)
3985a56a39bSAlex Qiu {
3995a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
4005a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
4015a56a39bSAlex Qiu 	unsigned long val;
4025a56a39bSAlex Qiu 	int ret;
4035a56a39bSAlex Qiu 
4045a56a39bSAlex Qiu 	ret = kstrtoul(buf, 10, &val);
4055a56a39bSAlex Qiu 	if (ret < 0)
4065a56a39bSAlex Qiu 		return ret;
4075a56a39bSAlex Qiu 
4085a56a39bSAlex Qiu 	/*
4095a56a39bSAlex Qiu 	 * Clear all alerts first to avoid accidentally triggering ALERT pin
4105a56a39bSAlex Qiu 	 * due to register write sequence. Then, only enable the alert
4115a56a39bSAlex Qiu 	 * if the value is non-zero.
4125a56a39bSAlex Qiu 	 */
4135a56a39bSAlex Qiu 	mutex_lock(&data->config_lock);
4145a56a39bSAlex Qiu 	ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
4155a56a39bSAlex Qiu 				 INA226_ALERT_CONFIG_MASK, 0);
4165a56a39bSAlex Qiu 	if (ret < 0)
4175a56a39bSAlex Qiu 		goto abort;
4185a56a39bSAlex Qiu 
4195a56a39bSAlex Qiu 	ret = regmap_write(data->regmap, INA226_ALERT_LIMIT,
4205a56a39bSAlex Qiu 			   ina226_alert_to_reg(data, attr->index, val));
4215a56a39bSAlex Qiu 	if (ret < 0)
4225a56a39bSAlex Qiu 		goto abort;
4235a56a39bSAlex Qiu 
4245a56a39bSAlex Qiu 	if (val != 0) {
4255a56a39bSAlex Qiu 		ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
4265a56a39bSAlex Qiu 					 INA226_ALERT_CONFIG_MASK,
4275a56a39bSAlex Qiu 					 BIT(attr->index));
4285a56a39bSAlex Qiu 		if (ret < 0)
4295a56a39bSAlex Qiu 			goto abort;
4305a56a39bSAlex Qiu 	}
4315a56a39bSAlex Qiu 
4325a56a39bSAlex Qiu 	ret = count;
4335a56a39bSAlex Qiu abort:
4345a56a39bSAlex Qiu 	mutex_unlock(&data->config_lock);
4355a56a39bSAlex Qiu 	return ret;
4365a56a39bSAlex Qiu }
4375a56a39bSAlex Qiu 
4385a56a39bSAlex Qiu static ssize_t ina226_alarm_show(struct device *dev,
4395a56a39bSAlex Qiu 				 struct device_attribute *da, char *buf)
4405a56a39bSAlex Qiu {
4415a56a39bSAlex Qiu 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
4425a56a39bSAlex Qiu 	struct ina2xx_data *data = dev_get_drvdata(dev);
4435a56a39bSAlex Qiu 	int regval;
4445a56a39bSAlex Qiu 	int alarm = 0;
4455a56a39bSAlex Qiu 	int ret;
4465a56a39bSAlex Qiu 
4475a56a39bSAlex Qiu 	ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
4485a56a39bSAlex Qiu 	if (ret)
4495a56a39bSAlex Qiu 		return ret;
4505a56a39bSAlex Qiu 
4515a56a39bSAlex Qiu 	alarm = (regval & BIT(attr->index)) &&
4525a56a39bSAlex Qiu 		(regval & INA226_ALERT_FUNCTION_FLAG);
4535a56a39bSAlex Qiu 	return snprintf(buf, PAGE_SIZE, "%d\n", alarm);
4545a56a39bSAlex Qiu }
4555a56a39bSAlex Qiu 
4565d389b12SMaciej Purski /*
4575d389b12SMaciej Purski  * In order to keep calibration register value fixed, the product
4585d389b12SMaciej Purski  * of current_lsb and shunt_resistor should also be fixed and equal
4595d389b12SMaciej Purski  * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
4605d389b12SMaciej Purski  * to keep the scale.
4615d389b12SMaciej Purski  */
4625d389b12SMaciej Purski static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
4635d389b12SMaciej Purski {
4645d389b12SMaciej Purski 	unsigned int dividend = DIV_ROUND_CLOSEST(1000000000,
4655d389b12SMaciej Purski 						  data->config->shunt_div);
4665d389b12SMaciej Purski 	if (val <= 0 || val > dividend)
4675d389b12SMaciej Purski 		return -EINVAL;
4685d389b12SMaciej Purski 
4695d389b12SMaciej Purski 	mutex_lock(&data->config_lock);
4705d389b12SMaciej Purski 	data->rshunt = val;
4715d389b12SMaciej Purski 	data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val);
4725d389b12SMaciej Purski 	data->power_lsb_uW = data->config->power_lsb_factor *
4735d389b12SMaciej Purski 			     data->current_lsb_uA;
4745d389b12SMaciej Purski 	mutex_unlock(&data->config_lock);
4755d389b12SMaciej Purski 
4765d389b12SMaciej Purski 	return 0;
4775d389b12SMaciej Purski }
4785d389b12SMaciej Purski 
4796a0f234fSGuenter Roeck static ssize_t ina2xx_shunt_show(struct device *dev,
4806a0f234fSGuenter Roeck 				 struct device_attribute *da, char *buf)
4813ad86700SLothar Felten {
4823ad86700SLothar Felten 	struct ina2xx_data *data = dev_get_drvdata(dev);
4833ad86700SLothar Felten 
4843ad86700SLothar Felten 	return snprintf(buf, PAGE_SIZE, "%li\n", data->rshunt);
4853ad86700SLothar Felten }
4863ad86700SLothar Felten 
4876a0f234fSGuenter Roeck static ssize_t ina2xx_shunt_store(struct device *dev,
4888a5fc795SBartosz Golaszewski 				  struct device_attribute *da,
4898a5fc795SBartosz Golaszewski 				  const char *buf, size_t count)
4908a5fc795SBartosz Golaszewski {
4918a5fc795SBartosz Golaszewski 	unsigned long val;
4928a5fc795SBartosz Golaszewski 	int status;
493a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
4948a5fc795SBartosz Golaszewski 
4958a5fc795SBartosz Golaszewski 	status = kstrtoul(buf, 10, &val);
4968a5fc795SBartosz Golaszewski 	if (status < 0)
4978a5fc795SBartosz Golaszewski 		return status;
4988a5fc795SBartosz Golaszewski 
4995d389b12SMaciej Purski 	status = ina2xx_set_shunt(data, val);
5008a5fc795SBartosz Golaszewski 	if (status < 0)
5018a5fc795SBartosz Golaszewski 		return status;
5028a5fc795SBartosz Golaszewski 	return count;
5038a5fc795SBartosz Golaszewski }
5048a5fc795SBartosz Golaszewski 
5056a0f234fSGuenter Roeck static ssize_t ina226_interval_store(struct device *dev,
50672a87a47SBartosz Golaszewski 				     struct device_attribute *da,
50772a87a47SBartosz Golaszewski 				     const char *buf, size_t count)
50872a87a47SBartosz Golaszewski {
50972a87a47SBartosz Golaszewski 	struct ina2xx_data *data = dev_get_drvdata(dev);
51072a87a47SBartosz Golaszewski 	unsigned long val;
51172a87a47SBartosz Golaszewski 	int status;
51272a87a47SBartosz Golaszewski 
51372a87a47SBartosz Golaszewski 	status = kstrtoul(buf, 10, &val);
51472a87a47SBartosz Golaszewski 	if (status < 0)
51572a87a47SBartosz Golaszewski 		return status;
51672a87a47SBartosz Golaszewski 
51772a87a47SBartosz Golaszewski 	if (val > INT_MAX || val == 0)
51872a87a47SBartosz Golaszewski 		return -EINVAL;
51972a87a47SBartosz Golaszewski 
520a0de56c8SMarc Titinger 	status = regmap_update_bits(data->regmap, INA2XX_CONFIG,
521a0de56c8SMarc Titinger 				    INA226_AVG_RD_MASK,
522a0de56c8SMarc Titinger 				    ina226_interval_to_reg(val));
52372a87a47SBartosz Golaszewski 	if (status < 0)
52472a87a47SBartosz Golaszewski 		return status;
52572a87a47SBartosz Golaszewski 
52672a87a47SBartosz Golaszewski 	return count;
52772a87a47SBartosz Golaszewski }
52872a87a47SBartosz Golaszewski 
5296a0f234fSGuenter Roeck static ssize_t ina226_interval_show(struct device *dev,
53072a87a47SBartosz Golaszewski 				    struct device_attribute *da, char *buf)
53172a87a47SBartosz Golaszewski {
532a0de56c8SMarc Titinger 	struct ina2xx_data *data = dev_get_drvdata(dev);
533a0de56c8SMarc Titinger 	int status;
534a0de56c8SMarc Titinger 	unsigned int regval;
53572a87a47SBartosz Golaszewski 
536a0de56c8SMarc Titinger 	status = regmap_read(data->regmap, INA2XX_CONFIG, &regval);
537a0de56c8SMarc Titinger 	if (status)
538a0de56c8SMarc Titinger 		return status;
53972a87a47SBartosz Golaszewski 
540a0de56c8SMarc Titinger 	return snprintf(buf, PAGE_SIZE, "%d\n", ina226_reg_to_interval(regval));
54172a87a47SBartosz Golaszewski }
54272a87a47SBartosz Golaszewski 
543f7c2fe38SFelten, Lothar /* shunt voltage */
5446a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);
5455a56a39bSAlex Qiu /* shunt voltage over/under voltage alert setting and alarm */
5465a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in0_crit, ina226_alert,
5475a56a39bSAlex Qiu 			     INA226_SHUNT_OVER_VOLTAGE_BIT);
5485a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in0_lcrit, ina226_alert,
5495a56a39bSAlex Qiu 			     INA226_SHUNT_UNDER_VOLTAGE_BIT);
5505a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in0_crit_alarm, ina226_alarm,
5515a56a39bSAlex Qiu 			     INA226_SHUNT_OVER_VOLTAGE_BIT);
5525a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in0_lcrit_alarm, ina226_alarm,
5535a56a39bSAlex Qiu 			     INA226_SHUNT_UNDER_VOLTAGE_BIT);
554f7c2fe38SFelten, Lothar 
555f7c2fe38SFelten, Lothar /* bus voltage */
5566a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
5575a56a39bSAlex Qiu /* bus voltage over/under voltage alert setting and alarm */
5585a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in1_crit, ina226_alert,
5595a56a39bSAlex Qiu 			     INA226_BUS_OVER_VOLTAGE_BIT);
5605a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(in1_lcrit, ina226_alert,
5615a56a39bSAlex Qiu 			     INA226_BUS_UNDER_VOLTAGE_BIT);
5625a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in1_crit_alarm, ina226_alarm,
5635a56a39bSAlex Qiu 			     INA226_BUS_OVER_VOLTAGE_BIT);
5645a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(in1_lcrit_alarm, ina226_alarm,
5655a56a39bSAlex Qiu 			     INA226_BUS_UNDER_VOLTAGE_BIT);
566f7c2fe38SFelten, Lothar 
567f7c2fe38SFelten, Lothar /* calculated current */
5686a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT);
569f7c2fe38SFelten, Lothar 
570f7c2fe38SFelten, Lothar /* calculated power */
5716a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER);
5725a56a39bSAlex Qiu /* over-limit power alert setting and alarm */
5735a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RW(power1_crit, ina226_alert,
5745a56a39bSAlex Qiu 			     INA226_POWER_OVER_LIMIT_BIT);
5755a56a39bSAlex Qiu static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina226_alarm,
5765a56a39bSAlex Qiu 			     INA226_POWER_OVER_LIMIT_BIT);
577f7c2fe38SFelten, Lothar 
5788a5fc795SBartosz Golaszewski /* shunt resistance */
5796a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION);
5808a5fc795SBartosz Golaszewski 
58172a87a47SBartosz Golaszewski /* update interval (ina226 only) */
5826a0f234fSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0);
58372a87a47SBartosz Golaszewski 
584f7c2fe38SFelten, Lothar /* pointers to created device attributes */
585468bf0e3SGuenter Roeck static struct attribute *ina2xx_attrs[] = {
586f7c2fe38SFelten, Lothar 	&sensor_dev_attr_in0_input.dev_attr.attr,
587f7c2fe38SFelten, Lothar 	&sensor_dev_attr_in1_input.dev_attr.attr,
588f7c2fe38SFelten, Lothar 	&sensor_dev_attr_curr1_input.dev_attr.attr,
589f7c2fe38SFelten, Lothar 	&sensor_dev_attr_power1_input.dev_attr.attr,
5908a5fc795SBartosz Golaszewski 	&sensor_dev_attr_shunt_resistor.dev_attr.attr,
591f7c2fe38SFelten, Lothar 	NULL,
592f7c2fe38SFelten, Lothar };
59372a87a47SBartosz Golaszewski 
59472a87a47SBartosz Golaszewski static const struct attribute_group ina2xx_group = {
59572a87a47SBartosz Golaszewski 	.attrs = ina2xx_attrs,
59672a87a47SBartosz Golaszewski };
59772a87a47SBartosz Golaszewski 
59872a87a47SBartosz Golaszewski static struct attribute *ina226_attrs[] = {
5995a56a39bSAlex Qiu 	&sensor_dev_attr_in0_crit.dev_attr.attr,
6005a56a39bSAlex Qiu 	&sensor_dev_attr_in0_lcrit.dev_attr.attr,
6015a56a39bSAlex Qiu 	&sensor_dev_attr_in0_crit_alarm.dev_attr.attr,
6025a56a39bSAlex Qiu 	&sensor_dev_attr_in0_lcrit_alarm.dev_attr.attr,
6035a56a39bSAlex Qiu 	&sensor_dev_attr_in1_crit.dev_attr.attr,
6045a56a39bSAlex Qiu 	&sensor_dev_attr_in1_lcrit.dev_attr.attr,
6055a56a39bSAlex Qiu 	&sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
6065a56a39bSAlex Qiu 	&sensor_dev_attr_in1_lcrit_alarm.dev_attr.attr,
6075a56a39bSAlex Qiu 	&sensor_dev_attr_power1_crit.dev_attr.attr,
6085a56a39bSAlex Qiu 	&sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
60972a87a47SBartosz Golaszewski 	&sensor_dev_attr_update_interval.dev_attr.attr,
61072a87a47SBartosz Golaszewski 	NULL,
61172a87a47SBartosz Golaszewski };
61272a87a47SBartosz Golaszewski 
61372a87a47SBartosz Golaszewski static const struct attribute_group ina226_group = {
61472a87a47SBartosz Golaszewski 	.attrs = ina226_attrs,
61572a87a47SBartosz Golaszewski };
616f7c2fe38SFelten, Lothar 
617*67487038SStephen Kitt static const struct i2c_device_id ina2xx_id[];
618*67487038SStephen Kitt 
619*67487038SStephen Kitt static int ina2xx_probe(struct i2c_client *client)
620f7c2fe38SFelten, Lothar {
621468bf0e3SGuenter Roeck 	struct device *dev = &client->dev;
622468bf0e3SGuenter Roeck 	struct ina2xx_data *data;
623468bf0e3SGuenter Roeck 	struct device *hwmon_dev;
624468bf0e3SGuenter Roeck 	u32 val;
62572a87a47SBartosz Golaszewski 	int ret, group = 0;
626bd0ddd4dSJavier Martinez Canillas 	enum ina2xx_ids chip;
627bd0ddd4dSJavier Martinez Canillas 
628bd0ddd4dSJavier Martinez Canillas 	if (client->dev.of_node)
629bd0ddd4dSJavier Martinez Canillas 		chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev);
630bd0ddd4dSJavier Martinez Canillas 	else
631*67487038SStephen Kitt 		chip = i2c_match_id(ina2xx_id, client)->driver_data;
632f7c2fe38SFelten, Lothar 
633468bf0e3SGuenter Roeck 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
634f7c2fe38SFelten, Lothar 	if (!data)
635f7c2fe38SFelten, Lothar 		return -ENOMEM;
636f7c2fe38SFelten, Lothar 
637f7c2fe38SFelten, Lothar 	/* set the device type */
638bd0ddd4dSJavier Martinez Canillas 	data->config = &ina2xx_config[chip];
6390c4c5860SMarek Szyprowski 	mutex_init(&data->config_lock);
64072a87a47SBartosz Golaszewski 
641001e2e73SMarc Titinger 	if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) {
642001e2e73SMarc Titinger 		struct ina2xx_platform_data *pdata = dev_get_platdata(dev);
643001e2e73SMarc Titinger 
644001e2e73SMarc Titinger 		if (pdata)
645001e2e73SMarc Titinger 			val = pdata->shunt_uohms;
646001e2e73SMarc Titinger 		else
647001e2e73SMarc Titinger 			val = INA2XX_RSHUNT_DEFAULT;
648001e2e73SMarc Titinger 	}
649001e2e73SMarc Titinger 
6505d389b12SMaciej Purski 	ina2xx_set_shunt(data, val);
651001e2e73SMarc Titinger 
652a0de56c8SMarc Titinger 	ina2xx_regmap_config.max_register = data->config->registers;
653a0de56c8SMarc Titinger 
654a0de56c8SMarc Titinger 	data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config);
655a0de56c8SMarc Titinger 	if (IS_ERR(data->regmap)) {
656a0de56c8SMarc Titinger 		dev_err(dev, "failed to allocate register map\n");
657a0de56c8SMarc Titinger 		return PTR_ERR(data->regmap);
658a0de56c8SMarc Titinger 	}
659a0de56c8SMarc Titinger 
660509416a8SBartosz Golaszewski 	ret = ina2xx_init(data);
661509416a8SBartosz Golaszewski 	if (ret < 0) {
662509416a8SBartosz Golaszewski 		dev_err(dev, "error configuring the device: %d\n", ret);
663509416a8SBartosz Golaszewski 		return -ENODEV;
664509416a8SBartosz Golaszewski 	}
665509416a8SBartosz Golaszewski 
66672a87a47SBartosz Golaszewski 	data->groups[group++] = &ina2xx_group;
66770df9ebbSNicolin Chen 	if (chip == ina226)
66872a87a47SBartosz Golaszewski 		data->groups[group++] = &ina226_group;
66972a87a47SBartosz Golaszewski 
670468bf0e3SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
67172a87a47SBartosz Golaszewski 							   data, data->groups);
672468bf0e3SGuenter Roeck 	if (IS_ERR(hwmon_dev))
673468bf0e3SGuenter Roeck 		return PTR_ERR(hwmon_dev);
674f7c2fe38SFelten, Lothar 
675468bf0e3SGuenter Roeck 	dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",
67670df9ebbSNicolin Chen 		 client->name, data->rshunt);
6776106db25SGuenter Roeck 
678f7c2fe38SFelten, Lothar 	return 0;
679f7c2fe38SFelten, Lothar }
680f7c2fe38SFelten, Lothar 
681f7c2fe38SFelten, Lothar static const struct i2c_device_id ina2xx_id[] = {
682f7c2fe38SFelten, Lothar 	{ "ina219", ina219 },
683dc92cd0cSGuenter Roeck 	{ "ina220", ina219 },
684f7c2fe38SFelten, Lothar 	{ "ina226", ina226 },
685dc92cd0cSGuenter Roeck 	{ "ina230", ina226 },
686add513beSKevin Hilman 	{ "ina231", ina226 },
687f7c2fe38SFelten, Lothar 	{ }
688f7c2fe38SFelten, Lothar };
689f7c2fe38SFelten, Lothar MODULE_DEVICE_TABLE(i2c, ina2xx_id);
690f7c2fe38SFelten, Lothar 
691df6b8c70SGuenter Roeck static const struct of_device_id __maybe_unused ina2xx_of_match[] = {
692bd0ddd4dSJavier Martinez Canillas 	{
693bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina219",
694bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina219
695bd0ddd4dSJavier Martinez Canillas 	},
696bd0ddd4dSJavier Martinez Canillas 	{
697bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina220",
698bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina219
699bd0ddd4dSJavier Martinez Canillas 	},
700bd0ddd4dSJavier Martinez Canillas 	{
701bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina226",
702bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
703bd0ddd4dSJavier Martinez Canillas 	},
704bd0ddd4dSJavier Martinez Canillas 	{
705bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina230",
706bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
707bd0ddd4dSJavier Martinez Canillas 	},
708bd0ddd4dSJavier Martinez Canillas 	{
709bd0ddd4dSJavier Martinez Canillas 		.compatible = "ti,ina231",
710bd0ddd4dSJavier Martinez Canillas 		.data = (void *)ina226
711bd0ddd4dSJavier Martinez Canillas 	},
712bd0ddd4dSJavier Martinez Canillas 	{ },
713bd0ddd4dSJavier Martinez Canillas };
714bd0ddd4dSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, ina2xx_of_match);
715bd0ddd4dSJavier Martinez Canillas 
716f7c2fe38SFelten, Lothar static struct i2c_driver ina2xx_driver = {
717f7c2fe38SFelten, Lothar 	.driver = {
718f7c2fe38SFelten, Lothar 		.name	= "ina2xx",
719bd0ddd4dSJavier Martinez Canillas 		.of_match_table = of_match_ptr(ina2xx_of_match),
720f7c2fe38SFelten, Lothar 	},
721*67487038SStephen Kitt 	.probe_new	= ina2xx_probe,
722f7c2fe38SFelten, Lothar 	.id_table	= ina2xx_id,
723f7c2fe38SFelten, Lothar };
724f7c2fe38SFelten, Lothar 
725d835ca0fSWei Yongjun module_i2c_driver(ina2xx_driver);
726f7c2fe38SFelten, Lothar 
727f7c2fe38SFelten, Lothar MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");
728f7c2fe38SFelten, Lothar MODULE_DESCRIPTION("ina2xx driver");
729f7c2fe38SFelten, Lothar MODULE_LICENSE("GPL");
730