1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * INA2XX Current and Power Monitors
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright 2015 Baylibre SAS.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
7*4882a593Smuzhiyun * it under the terms of the GNU General Public License version 2 as
8*4882a593Smuzhiyun * published by the Free Software Foundation.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Based on linux/drivers/iio/adc/ad7291.c
11*4882a593Smuzhiyun * Copyright 2010-2011 Analog Devices Inc.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * Based on linux/drivers/hwmon/ina2xx.c
14*4882a593Smuzhiyun * Copyright 2012 Lothar Felten <l-felten@ti.com>
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * Licensed under the GPL-2 or later.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * IIO driver for INA219-220-226-230-231
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun * Configurable 7-bit I2C slave address from 0x40 to 0x4F
21*4882a593Smuzhiyun */
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #include <linux/delay.h>
24*4882a593Smuzhiyun #include <linux/i2c.h>
25*4882a593Smuzhiyun #include <linux/iio/iio.h>
26*4882a593Smuzhiyun #include <linux/iio/buffer.h>
27*4882a593Smuzhiyun #include <linux/iio/kfifo_buf.h>
28*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
29*4882a593Smuzhiyun #include <linux/kthread.h>
30*4882a593Smuzhiyun #include <linux/module.h>
31*4882a593Smuzhiyun #include <linux/of_device.h>
32*4882a593Smuzhiyun #include <linux/regmap.h>
33*4882a593Smuzhiyun #include <linux/sched/task.h>
34*4882a593Smuzhiyun #include <linux/util_macros.h>
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include <linux/platform_data/ina2xx.h>
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /* INA2XX registers definition */
39*4882a593Smuzhiyun #define INA2XX_CONFIG 0x00
40*4882a593Smuzhiyun #define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */
41*4882a593Smuzhiyun #define INA2XX_BUS_VOLTAGE 0x02 /* readonly */
42*4882a593Smuzhiyun #define INA2XX_POWER 0x03 /* readonly */
43*4882a593Smuzhiyun #define INA2XX_CURRENT 0x04 /* readonly */
44*4882a593Smuzhiyun #define INA2XX_CALIBRATION 0x05
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #define INA226_MASK_ENABLE 0x06
47*4882a593Smuzhiyun #define INA226_CVRF BIT(3)
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define INA2XX_MAX_REGISTERS 8
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* settings - depend on use case */
52*4882a593Smuzhiyun #define INA219_CONFIG_DEFAULT 0x399F /* PGA=1/8, BRNG=32V */
53*4882a593Smuzhiyun #define INA219_DEFAULT_IT 532
54*4882a593Smuzhiyun #define INA219_DEFAULT_BRNG 1 /* 32V */
55*4882a593Smuzhiyun #define INA219_DEFAULT_PGA 125 /* 1000/8 */
56*4882a593Smuzhiyun #define INA226_CONFIG_DEFAULT 0x4327
57*4882a593Smuzhiyun #define INA226_DEFAULT_AVG 4
58*4882a593Smuzhiyun #define INA226_DEFAULT_IT 1110
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #define INA2XX_RSHUNT_DEFAULT 10000
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun * bit masks for reading the settings in the configuration register
64*4882a593Smuzhiyun * FIXME: use regmap_fields.
65*4882a593Smuzhiyun */
66*4882a593Smuzhiyun #define INA2XX_MODE_MASK GENMASK(3, 0)
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* Gain for VShunt: 1/8 (default), 1/4, 1/2, 1 */
69*4882a593Smuzhiyun #define INA219_PGA_MASK GENMASK(12, 11)
70*4882a593Smuzhiyun #define INA219_SHIFT_PGA(val) ((val) << 11)
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* VBus range: 32V (default), 16V */
73*4882a593Smuzhiyun #define INA219_BRNG_MASK BIT(13)
74*4882a593Smuzhiyun #define INA219_SHIFT_BRNG(val) ((val) << 13)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* Averaging for VBus/VShunt/Power */
77*4882a593Smuzhiyun #define INA226_AVG_MASK GENMASK(11, 9)
78*4882a593Smuzhiyun #define INA226_SHIFT_AVG(val) ((val) << 9)
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /* Integration time for VBus */
81*4882a593Smuzhiyun #define INA219_ITB_MASK GENMASK(10, 7)
82*4882a593Smuzhiyun #define INA219_SHIFT_ITB(val) ((val) << 7)
83*4882a593Smuzhiyun #define INA226_ITB_MASK GENMASK(8, 6)
84*4882a593Smuzhiyun #define INA226_SHIFT_ITB(val) ((val) << 6)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* Integration time for VShunt */
87*4882a593Smuzhiyun #define INA219_ITS_MASK GENMASK(6, 3)
88*4882a593Smuzhiyun #define INA219_SHIFT_ITS(val) ((val) << 3)
89*4882a593Smuzhiyun #define INA226_ITS_MASK GENMASK(5, 3)
90*4882a593Smuzhiyun #define INA226_SHIFT_ITS(val) ((val) << 3)
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /* INA219 Bus voltage register, low bits are flags */
93*4882a593Smuzhiyun #define INA219_OVF BIT(0)
94*4882a593Smuzhiyun #define INA219_CNVR BIT(1)
95*4882a593Smuzhiyun #define INA219_BUS_VOLTAGE_SHIFT 3
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun /* Cosmetic macro giving the sampling period for a full P=UxI cycle */
98*4882a593Smuzhiyun #define SAMPLING_PERIOD(c) ((c->int_time_vbus + c->int_time_vshunt) \
99*4882a593Smuzhiyun * c->avg)
100*4882a593Smuzhiyun
ina2xx_is_writeable_reg(struct device * dev,unsigned int reg)101*4882a593Smuzhiyun static bool ina2xx_is_writeable_reg(struct device *dev, unsigned int reg)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun return (reg == INA2XX_CONFIG) || (reg > INA2XX_CURRENT);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
ina2xx_is_volatile_reg(struct device * dev,unsigned int reg)106*4882a593Smuzhiyun static bool ina2xx_is_volatile_reg(struct device *dev, unsigned int reg)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun return (reg != INA2XX_CONFIG);
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
is_signed_reg(unsigned int reg)111*4882a593Smuzhiyun static inline bool is_signed_reg(unsigned int reg)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun return (reg == INA2XX_SHUNT_VOLTAGE) || (reg == INA2XX_CURRENT);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun static const struct regmap_config ina2xx_regmap_config = {
117*4882a593Smuzhiyun .reg_bits = 8,
118*4882a593Smuzhiyun .val_bits = 16,
119*4882a593Smuzhiyun .max_register = INA2XX_MAX_REGISTERS,
120*4882a593Smuzhiyun .writeable_reg = ina2xx_is_writeable_reg,
121*4882a593Smuzhiyun .volatile_reg = ina2xx_is_volatile_reg,
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun enum ina2xx_ids { ina219, ina226 };
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun struct ina2xx_config {
127*4882a593Smuzhiyun u16 config_default;
128*4882a593Smuzhiyun int calibration_value;
129*4882a593Smuzhiyun int shunt_voltage_lsb; /* nV */
130*4882a593Smuzhiyun int bus_voltage_shift; /* position of lsb */
131*4882a593Smuzhiyun int bus_voltage_lsb; /* uV */
132*4882a593Smuzhiyun /* fixed relation between current and power lsb, uW/uA */
133*4882a593Smuzhiyun int power_lsb_factor;
134*4882a593Smuzhiyun enum ina2xx_ids chip_id;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun struct ina2xx_chip_info {
138*4882a593Smuzhiyun struct regmap *regmap;
139*4882a593Smuzhiyun struct task_struct *task;
140*4882a593Smuzhiyun const struct ina2xx_config *config;
141*4882a593Smuzhiyun struct mutex state_lock;
142*4882a593Smuzhiyun unsigned int shunt_resistor_uohm;
143*4882a593Smuzhiyun int avg;
144*4882a593Smuzhiyun int int_time_vbus; /* Bus voltage integration time uS */
145*4882a593Smuzhiyun int int_time_vshunt; /* Shunt voltage integration time uS */
146*4882a593Smuzhiyun int range_vbus; /* Bus voltage maximum in V */
147*4882a593Smuzhiyun int pga_gain_vshunt; /* Shunt voltage PGA gain */
148*4882a593Smuzhiyun bool allow_async_readout;
149*4882a593Smuzhiyun /* data buffer needs space for channel data and timestamp */
150*4882a593Smuzhiyun struct {
151*4882a593Smuzhiyun u16 chan[4];
152*4882a593Smuzhiyun u64 ts __aligned(8);
153*4882a593Smuzhiyun } scan;
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun static const struct ina2xx_config ina2xx_config[] = {
157*4882a593Smuzhiyun [ina219] = {
158*4882a593Smuzhiyun .config_default = INA219_CONFIG_DEFAULT,
159*4882a593Smuzhiyun .calibration_value = 4096,
160*4882a593Smuzhiyun .shunt_voltage_lsb = 10000,
161*4882a593Smuzhiyun .bus_voltage_shift = INA219_BUS_VOLTAGE_SHIFT,
162*4882a593Smuzhiyun .bus_voltage_lsb = 4000,
163*4882a593Smuzhiyun .power_lsb_factor = 20,
164*4882a593Smuzhiyun .chip_id = ina219,
165*4882a593Smuzhiyun },
166*4882a593Smuzhiyun [ina226] = {
167*4882a593Smuzhiyun .config_default = INA226_CONFIG_DEFAULT,
168*4882a593Smuzhiyun .calibration_value = 2048,
169*4882a593Smuzhiyun .shunt_voltage_lsb = 2500,
170*4882a593Smuzhiyun .bus_voltage_shift = 0,
171*4882a593Smuzhiyun .bus_voltage_lsb = 1250,
172*4882a593Smuzhiyun .power_lsb_factor = 25,
173*4882a593Smuzhiyun .chip_id = ina226,
174*4882a593Smuzhiyun },
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun
ina2xx_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)177*4882a593Smuzhiyun static int ina2xx_read_raw(struct iio_dev *indio_dev,
178*4882a593Smuzhiyun struct iio_chan_spec const *chan,
179*4882a593Smuzhiyun int *val, int *val2, long mask)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun int ret;
182*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
183*4882a593Smuzhiyun unsigned int regval;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun switch (mask) {
186*4882a593Smuzhiyun case IIO_CHAN_INFO_RAW:
187*4882a593Smuzhiyun ret = regmap_read(chip->regmap, chan->address, ®val);
188*4882a593Smuzhiyun if (ret)
189*4882a593Smuzhiyun return ret;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (is_signed_reg(chan->address))
192*4882a593Smuzhiyun *val = (s16) regval;
193*4882a593Smuzhiyun else
194*4882a593Smuzhiyun *val = regval;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun if (chan->address == INA2XX_BUS_VOLTAGE)
197*4882a593Smuzhiyun *val >>= chip->config->bus_voltage_shift;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun return IIO_VAL_INT;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
202*4882a593Smuzhiyun *val = chip->avg;
203*4882a593Smuzhiyun return IIO_VAL_INT;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun case IIO_CHAN_INFO_INT_TIME:
206*4882a593Smuzhiyun *val = 0;
207*4882a593Smuzhiyun if (chan->address == INA2XX_SHUNT_VOLTAGE)
208*4882a593Smuzhiyun *val2 = chip->int_time_vshunt;
209*4882a593Smuzhiyun else
210*4882a593Smuzhiyun *val2 = chip->int_time_vbus;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun return IIO_VAL_INT_PLUS_MICRO;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun case IIO_CHAN_INFO_SAMP_FREQ:
215*4882a593Smuzhiyun /*
216*4882a593Smuzhiyun * Sample freq is read only, it is a consequence of
217*4882a593Smuzhiyun * 1/AVG*(CT_bus+CT_shunt).
218*4882a593Smuzhiyun */
219*4882a593Smuzhiyun *val = DIV_ROUND_CLOSEST(1000000, SAMPLING_PERIOD(chip));
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun return IIO_VAL_INT;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun case IIO_CHAN_INFO_SCALE:
224*4882a593Smuzhiyun switch (chan->address) {
225*4882a593Smuzhiyun case INA2XX_SHUNT_VOLTAGE:
226*4882a593Smuzhiyun /* processed (mV) = raw * lsb(nV) / 1000000 */
227*4882a593Smuzhiyun *val = chip->config->shunt_voltage_lsb;
228*4882a593Smuzhiyun *val2 = 1000000;
229*4882a593Smuzhiyun return IIO_VAL_FRACTIONAL;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun case INA2XX_BUS_VOLTAGE:
232*4882a593Smuzhiyun /* processed (mV) = raw * lsb (uV) / 1000 */
233*4882a593Smuzhiyun *val = chip->config->bus_voltage_lsb;
234*4882a593Smuzhiyun *val2 = 1000;
235*4882a593Smuzhiyun return IIO_VAL_FRACTIONAL;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun case INA2XX_CURRENT:
238*4882a593Smuzhiyun /*
239*4882a593Smuzhiyun * processed (mA) = raw * current_lsb (mA)
240*4882a593Smuzhiyun * current_lsb (mA) = shunt_voltage_lsb (nV) /
241*4882a593Smuzhiyun * shunt_resistor (uOhm)
242*4882a593Smuzhiyun */
243*4882a593Smuzhiyun *val = chip->config->shunt_voltage_lsb;
244*4882a593Smuzhiyun *val2 = chip->shunt_resistor_uohm;
245*4882a593Smuzhiyun return IIO_VAL_FRACTIONAL;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun case INA2XX_POWER:
248*4882a593Smuzhiyun /*
249*4882a593Smuzhiyun * processed (mW) = raw * power_lsb (mW)
250*4882a593Smuzhiyun * power_lsb (mW) = power_lsb_factor (mW/mA) *
251*4882a593Smuzhiyun * current_lsb (mA)
252*4882a593Smuzhiyun */
253*4882a593Smuzhiyun *val = chip->config->power_lsb_factor *
254*4882a593Smuzhiyun chip->config->shunt_voltage_lsb;
255*4882a593Smuzhiyun *val2 = chip->shunt_resistor_uohm;
256*4882a593Smuzhiyun return IIO_VAL_FRACTIONAL;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun return -EINVAL;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun case IIO_CHAN_INFO_HARDWAREGAIN:
261*4882a593Smuzhiyun switch (chan->address) {
262*4882a593Smuzhiyun case INA2XX_SHUNT_VOLTAGE:
263*4882a593Smuzhiyun *val = chip->pga_gain_vshunt;
264*4882a593Smuzhiyun *val2 = 1000;
265*4882a593Smuzhiyun return IIO_VAL_FRACTIONAL;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun case INA2XX_BUS_VOLTAGE:
268*4882a593Smuzhiyun *val = chip->range_vbus == 32 ? 1 : 2;
269*4882a593Smuzhiyun return IIO_VAL_INT;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun return -EINVAL;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun return -EINVAL;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /*
278*4882a593Smuzhiyun * Available averaging rates for ina226. The indices correspond with
279*4882a593Smuzhiyun * the bit values expected by the chip (according to the ina226 datasheet,
280*4882a593Smuzhiyun * table 3 AVG bit settings, found at
281*4882a593Smuzhiyun * https://www.ti.com/lit/ds/symlink/ina226.pdf.
282*4882a593Smuzhiyun */
283*4882a593Smuzhiyun static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
284*4882a593Smuzhiyun
ina226_set_average(struct ina2xx_chip_info * chip,unsigned int val,unsigned int * config)285*4882a593Smuzhiyun static int ina226_set_average(struct ina2xx_chip_info *chip, unsigned int val,
286*4882a593Smuzhiyun unsigned int *config)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun int bits;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (val > 1024 || val < 1)
291*4882a593Smuzhiyun return -EINVAL;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun bits = find_closest(val, ina226_avg_tab,
294*4882a593Smuzhiyun ARRAY_SIZE(ina226_avg_tab));
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun chip->avg = ina226_avg_tab[bits];
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun *config &= ~INA226_AVG_MASK;
299*4882a593Smuzhiyun *config |= INA226_SHIFT_AVG(bits) & INA226_AVG_MASK;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun return 0;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /* Conversion times in uS */
305*4882a593Smuzhiyun static const int ina226_conv_time_tab[] = { 140, 204, 332, 588, 1100,
306*4882a593Smuzhiyun 2116, 4156, 8244 };
307*4882a593Smuzhiyun
ina226_set_int_time_vbus(struct ina2xx_chip_info * chip,unsigned int val_us,unsigned int * config)308*4882a593Smuzhiyun static int ina226_set_int_time_vbus(struct ina2xx_chip_info *chip,
309*4882a593Smuzhiyun unsigned int val_us, unsigned int *config)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun int bits;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (val_us > 8244 || val_us < 140)
314*4882a593Smuzhiyun return -EINVAL;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun bits = find_closest(val_us, ina226_conv_time_tab,
317*4882a593Smuzhiyun ARRAY_SIZE(ina226_conv_time_tab));
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun chip->int_time_vbus = ina226_conv_time_tab[bits];
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun *config &= ~INA226_ITB_MASK;
322*4882a593Smuzhiyun *config |= INA226_SHIFT_ITB(bits) & INA226_ITB_MASK;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun return 0;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
ina226_set_int_time_vshunt(struct ina2xx_chip_info * chip,unsigned int val_us,unsigned int * config)327*4882a593Smuzhiyun static int ina226_set_int_time_vshunt(struct ina2xx_chip_info *chip,
328*4882a593Smuzhiyun unsigned int val_us, unsigned int *config)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun int bits;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun if (val_us > 8244 || val_us < 140)
333*4882a593Smuzhiyun return -EINVAL;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun bits = find_closest(val_us, ina226_conv_time_tab,
336*4882a593Smuzhiyun ARRAY_SIZE(ina226_conv_time_tab));
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun chip->int_time_vshunt = ina226_conv_time_tab[bits];
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun *config &= ~INA226_ITS_MASK;
341*4882a593Smuzhiyun *config |= INA226_SHIFT_ITS(bits) & INA226_ITS_MASK;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun return 0;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun /* Conversion times in uS. */
347*4882a593Smuzhiyun static const int ina219_conv_time_tab_subsample[] = { 84, 148, 276, 532 };
348*4882a593Smuzhiyun static const int ina219_conv_time_tab_average[] = { 532, 1060, 2130, 4260,
349*4882a593Smuzhiyun 8510, 17020, 34050, 68100};
350*4882a593Smuzhiyun
ina219_lookup_int_time(unsigned int * val_us,int * bits)351*4882a593Smuzhiyun static int ina219_lookup_int_time(unsigned int *val_us, int *bits)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun if (*val_us > 68100 || *val_us < 84)
354*4882a593Smuzhiyun return -EINVAL;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun if (*val_us <= 532) {
357*4882a593Smuzhiyun *bits = find_closest(*val_us, ina219_conv_time_tab_subsample,
358*4882a593Smuzhiyun ARRAY_SIZE(ina219_conv_time_tab_subsample));
359*4882a593Smuzhiyun *val_us = ina219_conv_time_tab_subsample[*bits];
360*4882a593Smuzhiyun } else {
361*4882a593Smuzhiyun *bits = find_closest(*val_us, ina219_conv_time_tab_average,
362*4882a593Smuzhiyun ARRAY_SIZE(ina219_conv_time_tab_average));
363*4882a593Smuzhiyun *val_us = ina219_conv_time_tab_average[*bits];
364*4882a593Smuzhiyun *bits |= 0x8;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
ina219_set_int_time_vbus(struct ina2xx_chip_info * chip,unsigned int val_us,unsigned int * config)370*4882a593Smuzhiyun static int ina219_set_int_time_vbus(struct ina2xx_chip_info *chip,
371*4882a593Smuzhiyun unsigned int val_us, unsigned int *config)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun int bits, ret;
374*4882a593Smuzhiyun unsigned int val_us_best = val_us;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun ret = ina219_lookup_int_time(&val_us_best, &bits);
377*4882a593Smuzhiyun if (ret)
378*4882a593Smuzhiyun return ret;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun chip->int_time_vbus = val_us_best;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun *config &= ~INA219_ITB_MASK;
383*4882a593Smuzhiyun *config |= INA219_SHIFT_ITB(bits) & INA219_ITB_MASK;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun return 0;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
ina219_set_int_time_vshunt(struct ina2xx_chip_info * chip,unsigned int val_us,unsigned int * config)388*4882a593Smuzhiyun static int ina219_set_int_time_vshunt(struct ina2xx_chip_info *chip,
389*4882a593Smuzhiyun unsigned int val_us, unsigned int *config)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun int bits, ret;
392*4882a593Smuzhiyun unsigned int val_us_best = val_us;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun ret = ina219_lookup_int_time(&val_us_best, &bits);
395*4882a593Smuzhiyun if (ret)
396*4882a593Smuzhiyun return ret;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun chip->int_time_vshunt = val_us_best;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun *config &= ~INA219_ITS_MASK;
401*4882a593Smuzhiyun *config |= INA219_SHIFT_ITS(bits) & INA219_ITS_MASK;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun return 0;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun static const int ina219_vbus_range_tab[] = { 1, 2 };
ina219_set_vbus_range_denom(struct ina2xx_chip_info * chip,unsigned int range,unsigned int * config)407*4882a593Smuzhiyun static int ina219_set_vbus_range_denom(struct ina2xx_chip_info *chip,
408*4882a593Smuzhiyun unsigned int range,
409*4882a593Smuzhiyun unsigned int *config)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun if (range == 1)
412*4882a593Smuzhiyun chip->range_vbus = 32;
413*4882a593Smuzhiyun else if (range == 2)
414*4882a593Smuzhiyun chip->range_vbus = 16;
415*4882a593Smuzhiyun else
416*4882a593Smuzhiyun return -EINVAL;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun *config &= ~INA219_BRNG_MASK;
419*4882a593Smuzhiyun *config |= INA219_SHIFT_BRNG(range == 1 ? 1 : 0) & INA219_BRNG_MASK;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun return 0;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun static const int ina219_vshunt_gain_tab[] = { 125, 250, 500, 1000 };
425*4882a593Smuzhiyun static const int ina219_vshunt_gain_frac[] = {
426*4882a593Smuzhiyun 125, 1000, 250, 1000, 500, 1000, 1000, 1000 };
427*4882a593Smuzhiyun
ina219_set_vshunt_pga_gain(struct ina2xx_chip_info * chip,unsigned int gain,unsigned int * config)428*4882a593Smuzhiyun static int ina219_set_vshunt_pga_gain(struct ina2xx_chip_info *chip,
429*4882a593Smuzhiyun unsigned int gain,
430*4882a593Smuzhiyun unsigned int *config)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun int bits;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (gain < 125 || gain > 1000)
435*4882a593Smuzhiyun return -EINVAL;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun bits = find_closest(gain, ina219_vshunt_gain_tab,
438*4882a593Smuzhiyun ARRAY_SIZE(ina219_vshunt_gain_tab));
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun chip->pga_gain_vshunt = ina219_vshunt_gain_tab[bits];
441*4882a593Smuzhiyun bits = 3 - bits;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun *config &= ~INA219_PGA_MASK;
444*4882a593Smuzhiyun *config |= INA219_SHIFT_PGA(bits) & INA219_PGA_MASK;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
ina2xx_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)449*4882a593Smuzhiyun static int ina2xx_read_avail(struct iio_dev *indio_dev,
450*4882a593Smuzhiyun struct iio_chan_spec const *chan,
451*4882a593Smuzhiyun const int **vals, int *type, int *length,
452*4882a593Smuzhiyun long mask)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun switch (mask) {
455*4882a593Smuzhiyun case IIO_CHAN_INFO_HARDWAREGAIN:
456*4882a593Smuzhiyun switch (chan->address) {
457*4882a593Smuzhiyun case INA2XX_SHUNT_VOLTAGE:
458*4882a593Smuzhiyun *type = IIO_VAL_FRACTIONAL;
459*4882a593Smuzhiyun *length = sizeof(ina219_vshunt_gain_frac) / sizeof(int);
460*4882a593Smuzhiyun *vals = ina219_vshunt_gain_frac;
461*4882a593Smuzhiyun return IIO_AVAIL_LIST;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun case INA2XX_BUS_VOLTAGE:
464*4882a593Smuzhiyun *type = IIO_VAL_INT;
465*4882a593Smuzhiyun *length = sizeof(ina219_vbus_range_tab) / sizeof(int);
466*4882a593Smuzhiyun *vals = ina219_vbus_range_tab;
467*4882a593Smuzhiyun return IIO_AVAIL_LIST;
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun return -EINVAL;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
ina2xx_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)474*4882a593Smuzhiyun static int ina2xx_write_raw(struct iio_dev *indio_dev,
475*4882a593Smuzhiyun struct iio_chan_spec const *chan,
476*4882a593Smuzhiyun int val, int val2, long mask)
477*4882a593Smuzhiyun {
478*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
479*4882a593Smuzhiyun unsigned int config, tmp;
480*4882a593Smuzhiyun int ret;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun if (iio_buffer_enabled(indio_dev))
483*4882a593Smuzhiyun return -EBUSY;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun mutex_lock(&chip->state_lock);
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun ret = regmap_read(chip->regmap, INA2XX_CONFIG, &config);
488*4882a593Smuzhiyun if (ret)
489*4882a593Smuzhiyun goto err;
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun tmp = config;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun switch (mask) {
494*4882a593Smuzhiyun case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
495*4882a593Smuzhiyun ret = ina226_set_average(chip, val, &tmp);
496*4882a593Smuzhiyun break;
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun case IIO_CHAN_INFO_INT_TIME:
499*4882a593Smuzhiyun if (chip->config->chip_id == ina226) {
500*4882a593Smuzhiyun if (chan->address == INA2XX_SHUNT_VOLTAGE)
501*4882a593Smuzhiyun ret = ina226_set_int_time_vshunt(chip, val2,
502*4882a593Smuzhiyun &tmp);
503*4882a593Smuzhiyun else
504*4882a593Smuzhiyun ret = ina226_set_int_time_vbus(chip, val2,
505*4882a593Smuzhiyun &tmp);
506*4882a593Smuzhiyun } else {
507*4882a593Smuzhiyun if (chan->address == INA2XX_SHUNT_VOLTAGE)
508*4882a593Smuzhiyun ret = ina219_set_int_time_vshunt(chip, val2,
509*4882a593Smuzhiyun &tmp);
510*4882a593Smuzhiyun else
511*4882a593Smuzhiyun ret = ina219_set_int_time_vbus(chip, val2,
512*4882a593Smuzhiyun &tmp);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun break;
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun case IIO_CHAN_INFO_HARDWAREGAIN:
517*4882a593Smuzhiyun if (chan->address == INA2XX_SHUNT_VOLTAGE)
518*4882a593Smuzhiyun ret = ina219_set_vshunt_pga_gain(chip, val * 1000 +
519*4882a593Smuzhiyun val2 / 1000, &tmp);
520*4882a593Smuzhiyun else
521*4882a593Smuzhiyun ret = ina219_set_vbus_range_denom(chip, val, &tmp);
522*4882a593Smuzhiyun break;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun default:
525*4882a593Smuzhiyun ret = -EINVAL;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun if (!ret && (tmp != config))
529*4882a593Smuzhiyun ret = regmap_write(chip->regmap, INA2XX_CONFIG, tmp);
530*4882a593Smuzhiyun err:
531*4882a593Smuzhiyun mutex_unlock(&chip->state_lock);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun return ret;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun
ina2xx_allow_async_readout_show(struct device * dev,struct device_attribute * attr,char * buf)536*4882a593Smuzhiyun static ssize_t ina2xx_allow_async_readout_show(struct device *dev,
537*4882a593Smuzhiyun struct device_attribute *attr,
538*4882a593Smuzhiyun char *buf)
539*4882a593Smuzhiyun {
540*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun return sprintf(buf, "%d\n", chip->allow_async_readout);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
ina2xx_allow_async_readout_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)545*4882a593Smuzhiyun static ssize_t ina2xx_allow_async_readout_store(struct device *dev,
546*4882a593Smuzhiyun struct device_attribute *attr,
547*4882a593Smuzhiyun const char *buf, size_t len)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
550*4882a593Smuzhiyun bool val;
551*4882a593Smuzhiyun int ret;
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun ret = strtobool((const char *) buf, &val);
554*4882a593Smuzhiyun if (ret)
555*4882a593Smuzhiyun return ret;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun chip->allow_async_readout = val;
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun return len;
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun /*
563*4882a593Smuzhiyun * Calibration register is set to the best value, which eliminates
564*4882a593Smuzhiyun * truncation errors on calculating current register in hardware.
565*4882a593Smuzhiyun * According to datasheet (INA 226: eq. 3, INA219: eq. 4) the best values
566*4882a593Smuzhiyun * are 2048 for ina226 and 4096 for ina219. They are hardcoded as
567*4882a593Smuzhiyun * calibration_value.
568*4882a593Smuzhiyun */
ina2xx_set_calibration(struct ina2xx_chip_info * chip)569*4882a593Smuzhiyun static int ina2xx_set_calibration(struct ina2xx_chip_info *chip)
570*4882a593Smuzhiyun {
571*4882a593Smuzhiyun return regmap_write(chip->regmap, INA2XX_CALIBRATION,
572*4882a593Smuzhiyun chip->config->calibration_value);
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
set_shunt_resistor(struct ina2xx_chip_info * chip,unsigned int val)575*4882a593Smuzhiyun static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun if (val == 0 || val > INT_MAX)
578*4882a593Smuzhiyun return -EINVAL;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun chip->shunt_resistor_uohm = val;
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun return 0;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
ina2xx_shunt_resistor_show(struct device * dev,struct device_attribute * attr,char * buf)585*4882a593Smuzhiyun static ssize_t ina2xx_shunt_resistor_show(struct device *dev,
586*4882a593Smuzhiyun struct device_attribute *attr,
587*4882a593Smuzhiyun char *buf)
588*4882a593Smuzhiyun {
589*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
590*4882a593Smuzhiyun int vals[2] = { chip->shunt_resistor_uohm, 1000000 };
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun
ina2xx_shunt_resistor_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)595*4882a593Smuzhiyun static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
596*4882a593Smuzhiyun struct device_attribute *attr,
597*4882a593Smuzhiyun const char *buf, size_t len)
598*4882a593Smuzhiyun {
599*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
600*4882a593Smuzhiyun int val, val_fract, ret;
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract);
603*4882a593Smuzhiyun if (ret)
604*4882a593Smuzhiyun return ret;
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun ret = set_shunt_resistor(chip, val * 1000000 + val_fract);
607*4882a593Smuzhiyun if (ret)
608*4882a593Smuzhiyun return ret;
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun return len;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun #define INA219_CHAN(_type, _index, _address) { \
614*4882a593Smuzhiyun .type = (_type), \
615*4882a593Smuzhiyun .address = (_address), \
616*4882a593Smuzhiyun .indexed = 1, \
617*4882a593Smuzhiyun .channel = (_index), \
618*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
619*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_SCALE), \
620*4882a593Smuzhiyun .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
621*4882a593Smuzhiyun .scan_index = (_index), \
622*4882a593Smuzhiyun .scan_type = { \
623*4882a593Smuzhiyun .sign = 'u', \
624*4882a593Smuzhiyun .realbits = 16, \
625*4882a593Smuzhiyun .storagebits = 16, \
626*4882a593Smuzhiyun .endianness = IIO_CPU, \
627*4882a593Smuzhiyun } \
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun #define INA226_CHAN(_type, _index, _address) { \
631*4882a593Smuzhiyun .type = (_type), \
632*4882a593Smuzhiyun .address = (_address), \
633*4882a593Smuzhiyun .indexed = 1, \
634*4882a593Smuzhiyun .channel = (_index), \
635*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
636*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_SCALE), \
637*4882a593Smuzhiyun .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
638*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
639*4882a593Smuzhiyun .scan_index = (_index), \
640*4882a593Smuzhiyun .scan_type = { \
641*4882a593Smuzhiyun .sign = 'u', \
642*4882a593Smuzhiyun .realbits = 16, \
643*4882a593Smuzhiyun .storagebits = 16, \
644*4882a593Smuzhiyun .endianness = IIO_CPU, \
645*4882a593Smuzhiyun } \
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun /*
649*4882a593Smuzhiyun * Sampling Freq is a consequence of the integration times of
650*4882a593Smuzhiyun * the Voltage channels.
651*4882a593Smuzhiyun */
652*4882a593Smuzhiyun #define INA219_CHAN_VOLTAGE(_index, _address, _shift) { \
653*4882a593Smuzhiyun .type = IIO_VOLTAGE, \
654*4882a593Smuzhiyun .address = (_address), \
655*4882a593Smuzhiyun .indexed = 1, \
656*4882a593Smuzhiyun .channel = (_index), \
657*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
658*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_SCALE) | \
659*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_INT_TIME) | \
660*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
661*4882a593Smuzhiyun .info_mask_separate_available = \
662*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
663*4882a593Smuzhiyun .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
664*4882a593Smuzhiyun .scan_index = (_index), \
665*4882a593Smuzhiyun .scan_type = { \
666*4882a593Smuzhiyun .sign = 'u', \
667*4882a593Smuzhiyun .shift = _shift, \
668*4882a593Smuzhiyun .realbits = 16 - _shift, \
669*4882a593Smuzhiyun .storagebits = 16, \
670*4882a593Smuzhiyun .endianness = IIO_LE, \
671*4882a593Smuzhiyun } \
672*4882a593Smuzhiyun }
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun #define INA226_CHAN_VOLTAGE(_index, _address) { \
675*4882a593Smuzhiyun .type = IIO_VOLTAGE, \
676*4882a593Smuzhiyun .address = (_address), \
677*4882a593Smuzhiyun .indexed = 1, \
678*4882a593Smuzhiyun .channel = (_index), \
679*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
680*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_SCALE) | \
681*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_INT_TIME), \
682*4882a593Smuzhiyun .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
683*4882a593Smuzhiyun BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
684*4882a593Smuzhiyun .scan_index = (_index), \
685*4882a593Smuzhiyun .scan_type = { \
686*4882a593Smuzhiyun .sign = 'u', \
687*4882a593Smuzhiyun .realbits = 16, \
688*4882a593Smuzhiyun .storagebits = 16, \
689*4882a593Smuzhiyun .endianness = IIO_LE, \
690*4882a593Smuzhiyun } \
691*4882a593Smuzhiyun }
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun static const struct iio_chan_spec ina226_channels[] = {
695*4882a593Smuzhiyun INA226_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE),
696*4882a593Smuzhiyun INA226_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE),
697*4882a593Smuzhiyun INA226_CHAN(IIO_POWER, 2, INA2XX_POWER),
698*4882a593Smuzhiyun INA226_CHAN(IIO_CURRENT, 3, INA2XX_CURRENT),
699*4882a593Smuzhiyun IIO_CHAN_SOFT_TIMESTAMP(4),
700*4882a593Smuzhiyun };
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun static const struct iio_chan_spec ina219_channels[] = {
703*4882a593Smuzhiyun INA219_CHAN_VOLTAGE(0, INA2XX_SHUNT_VOLTAGE, 0),
704*4882a593Smuzhiyun INA219_CHAN_VOLTAGE(1, INA2XX_BUS_VOLTAGE, INA219_BUS_VOLTAGE_SHIFT),
705*4882a593Smuzhiyun INA219_CHAN(IIO_POWER, 2, INA2XX_POWER),
706*4882a593Smuzhiyun INA219_CHAN(IIO_CURRENT, 3, INA2XX_CURRENT),
707*4882a593Smuzhiyun IIO_CHAN_SOFT_TIMESTAMP(4),
708*4882a593Smuzhiyun };
709*4882a593Smuzhiyun
ina2xx_conversion_ready(struct iio_dev * indio_dev)710*4882a593Smuzhiyun static int ina2xx_conversion_ready(struct iio_dev *indio_dev)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
713*4882a593Smuzhiyun int ret;
714*4882a593Smuzhiyun unsigned int alert;
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun /*
717*4882a593Smuzhiyun * Because the timer thread and the chip conversion clock
718*4882a593Smuzhiyun * are asynchronous, the period difference will eventually
719*4882a593Smuzhiyun * result in reading V[k-1] again, or skip V[k] at time Tk.
720*4882a593Smuzhiyun * In order to resync the timer with the conversion process
721*4882a593Smuzhiyun * we check the ConVersionReadyFlag.
722*4882a593Smuzhiyun * On hardware that supports using the ALERT pin to toggle a
723*4882a593Smuzhiyun * GPIO a triggered buffer could be used instead.
724*4882a593Smuzhiyun * For now, we do an extra read of the MASK_ENABLE register (INA226)
725*4882a593Smuzhiyun * resp. the BUS_VOLTAGE register (INA219).
726*4882a593Smuzhiyun */
727*4882a593Smuzhiyun if (chip->config->chip_id == ina226) {
728*4882a593Smuzhiyun ret = regmap_read(chip->regmap,
729*4882a593Smuzhiyun INA226_MASK_ENABLE, &alert);
730*4882a593Smuzhiyun alert &= INA226_CVRF;
731*4882a593Smuzhiyun } else {
732*4882a593Smuzhiyun ret = regmap_read(chip->regmap,
733*4882a593Smuzhiyun INA2XX_BUS_VOLTAGE, &alert);
734*4882a593Smuzhiyun alert &= INA219_CNVR;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun if (ret < 0)
738*4882a593Smuzhiyun return ret;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun return !!alert;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun
ina2xx_work_buffer(struct iio_dev * indio_dev)743*4882a593Smuzhiyun static int ina2xx_work_buffer(struct iio_dev *indio_dev)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
746*4882a593Smuzhiyun int bit, ret, i = 0;
747*4882a593Smuzhiyun s64 time;
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun time = iio_get_time_ns(indio_dev);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun /*
752*4882a593Smuzhiyun * Single register reads: bulk_read will not work with ina226/219
753*4882a593Smuzhiyun * as there is no auto-increment of the register pointer.
754*4882a593Smuzhiyun */
755*4882a593Smuzhiyun for_each_set_bit(bit, indio_dev->active_scan_mask,
756*4882a593Smuzhiyun indio_dev->masklength) {
757*4882a593Smuzhiyun unsigned int val;
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun ret = regmap_read(chip->regmap,
760*4882a593Smuzhiyun INA2XX_SHUNT_VOLTAGE + bit, &val);
761*4882a593Smuzhiyun if (ret < 0)
762*4882a593Smuzhiyun return ret;
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun chip->scan.chan[i++] = val;
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun iio_push_to_buffers_with_timestamp(indio_dev, &chip->scan, time);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun return 0;
770*4882a593Smuzhiyun };
771*4882a593Smuzhiyun
ina2xx_capture_thread(void * data)772*4882a593Smuzhiyun static int ina2xx_capture_thread(void *data)
773*4882a593Smuzhiyun {
774*4882a593Smuzhiyun struct iio_dev *indio_dev = data;
775*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
776*4882a593Smuzhiyun int sampling_us = SAMPLING_PERIOD(chip);
777*4882a593Smuzhiyun int ret;
778*4882a593Smuzhiyun struct timespec64 next, now, delta;
779*4882a593Smuzhiyun s64 delay_us;
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun /*
782*4882a593Smuzhiyun * Poll a bit faster than the chip internal Fs, in case
783*4882a593Smuzhiyun * we wish to sync with the conversion ready flag.
784*4882a593Smuzhiyun */
785*4882a593Smuzhiyun if (!chip->allow_async_readout)
786*4882a593Smuzhiyun sampling_us -= 200;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun ktime_get_ts64(&next);
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun do {
791*4882a593Smuzhiyun while (!chip->allow_async_readout) {
792*4882a593Smuzhiyun ret = ina2xx_conversion_ready(indio_dev);
793*4882a593Smuzhiyun if (ret < 0)
794*4882a593Smuzhiyun return ret;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun /*
797*4882a593Smuzhiyun * If the conversion was not yet finished,
798*4882a593Smuzhiyun * reset the reference timestamp.
799*4882a593Smuzhiyun */
800*4882a593Smuzhiyun if (ret == 0)
801*4882a593Smuzhiyun ktime_get_ts64(&next);
802*4882a593Smuzhiyun else
803*4882a593Smuzhiyun break;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun ret = ina2xx_work_buffer(indio_dev);
807*4882a593Smuzhiyun if (ret < 0)
808*4882a593Smuzhiyun return ret;
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun ktime_get_ts64(&now);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun /*
813*4882a593Smuzhiyun * Advance the timestamp for the next poll by one sampling
814*4882a593Smuzhiyun * interval, and sleep for the remainder (next - now)
815*4882a593Smuzhiyun * In case "next" has already passed, the interval is added
816*4882a593Smuzhiyun * multiple times, i.e. samples are dropped.
817*4882a593Smuzhiyun */
818*4882a593Smuzhiyun do {
819*4882a593Smuzhiyun timespec64_add_ns(&next, 1000 * sampling_us);
820*4882a593Smuzhiyun delta = timespec64_sub(next, now);
821*4882a593Smuzhiyun delay_us = div_s64(timespec64_to_ns(&delta), 1000);
822*4882a593Smuzhiyun } while (delay_us <= 0);
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun usleep_range(delay_us, (delay_us * 3) >> 1);
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun } while (!kthread_should_stop());
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun return 0;
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun
ina2xx_buffer_enable(struct iio_dev * indio_dev)831*4882a593Smuzhiyun static int ina2xx_buffer_enable(struct iio_dev *indio_dev)
832*4882a593Smuzhiyun {
833*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
834*4882a593Smuzhiyun unsigned int sampling_us = SAMPLING_PERIOD(chip);
835*4882a593Smuzhiyun struct task_struct *task;
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun dev_dbg(&indio_dev->dev, "Enabling buffer w/ scan_mask %02x, freq = %d, avg =%u\n",
838*4882a593Smuzhiyun (unsigned int)(*indio_dev->active_scan_mask),
839*4882a593Smuzhiyun 1000000 / sampling_us, chip->avg);
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun dev_dbg(&indio_dev->dev, "Expected work period: %u us\n", sampling_us);
842*4882a593Smuzhiyun dev_dbg(&indio_dev->dev, "Async readout mode: %d\n",
843*4882a593Smuzhiyun chip->allow_async_readout);
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun task = kthread_create(ina2xx_capture_thread, (void *)indio_dev,
846*4882a593Smuzhiyun "%s:%d-%uus", indio_dev->name, indio_dev->id,
847*4882a593Smuzhiyun sampling_us);
848*4882a593Smuzhiyun if (IS_ERR(task))
849*4882a593Smuzhiyun return PTR_ERR(task);
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun get_task_struct(task);
852*4882a593Smuzhiyun wake_up_process(task);
853*4882a593Smuzhiyun chip->task = task;
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun return 0;
856*4882a593Smuzhiyun }
857*4882a593Smuzhiyun
ina2xx_buffer_disable(struct iio_dev * indio_dev)858*4882a593Smuzhiyun static int ina2xx_buffer_disable(struct iio_dev *indio_dev)
859*4882a593Smuzhiyun {
860*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun if (chip->task) {
863*4882a593Smuzhiyun kthread_stop(chip->task);
864*4882a593Smuzhiyun put_task_struct(chip->task);
865*4882a593Smuzhiyun chip->task = NULL;
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun return 0;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun static const struct iio_buffer_setup_ops ina2xx_setup_ops = {
872*4882a593Smuzhiyun .postenable = &ina2xx_buffer_enable,
873*4882a593Smuzhiyun .predisable = &ina2xx_buffer_disable,
874*4882a593Smuzhiyun };
875*4882a593Smuzhiyun
ina2xx_debug_reg(struct iio_dev * indio_dev,unsigned reg,unsigned writeval,unsigned * readval)876*4882a593Smuzhiyun static int ina2xx_debug_reg(struct iio_dev *indio_dev,
877*4882a593Smuzhiyun unsigned reg, unsigned writeval, unsigned *readval)
878*4882a593Smuzhiyun {
879*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun if (!readval)
882*4882a593Smuzhiyun return regmap_write(chip->regmap, reg, writeval);
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun return regmap_read(chip->regmap, reg, readval);
885*4882a593Smuzhiyun }
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun /* Possible integration times for vshunt and vbus */
888*4882a593Smuzhiyun static IIO_CONST_ATTR_NAMED(ina219_integration_time_available,
889*4882a593Smuzhiyun integration_time_available,
890*4882a593Smuzhiyun "0.000084 0.000148 0.000276 0.000532 0.001060 0.002130 0.004260 0.008510 0.017020 0.034050 0.068100");
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun static IIO_CONST_ATTR_NAMED(ina226_integration_time_available,
893*4882a593Smuzhiyun integration_time_available,
894*4882a593Smuzhiyun "0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244");
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR,
897*4882a593Smuzhiyun ina2xx_allow_async_readout_show,
898*4882a593Smuzhiyun ina2xx_allow_async_readout_store, 0);
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun static IIO_DEVICE_ATTR(in_shunt_resistor, S_IRUGO | S_IWUSR,
901*4882a593Smuzhiyun ina2xx_shunt_resistor_show,
902*4882a593Smuzhiyun ina2xx_shunt_resistor_store, 0);
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun static struct attribute *ina219_attributes[] = {
905*4882a593Smuzhiyun &iio_dev_attr_in_allow_async_readout.dev_attr.attr,
906*4882a593Smuzhiyun &iio_const_attr_ina219_integration_time_available.dev_attr.attr,
907*4882a593Smuzhiyun &iio_dev_attr_in_shunt_resistor.dev_attr.attr,
908*4882a593Smuzhiyun NULL,
909*4882a593Smuzhiyun };
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun static struct attribute *ina226_attributes[] = {
912*4882a593Smuzhiyun &iio_dev_attr_in_allow_async_readout.dev_attr.attr,
913*4882a593Smuzhiyun &iio_const_attr_ina226_integration_time_available.dev_attr.attr,
914*4882a593Smuzhiyun &iio_dev_attr_in_shunt_resistor.dev_attr.attr,
915*4882a593Smuzhiyun NULL,
916*4882a593Smuzhiyun };
917*4882a593Smuzhiyun
918*4882a593Smuzhiyun static const struct attribute_group ina219_attribute_group = {
919*4882a593Smuzhiyun .attrs = ina219_attributes,
920*4882a593Smuzhiyun };
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun static const struct attribute_group ina226_attribute_group = {
923*4882a593Smuzhiyun .attrs = ina226_attributes,
924*4882a593Smuzhiyun };
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun static const struct iio_info ina219_info = {
927*4882a593Smuzhiyun .attrs = &ina219_attribute_group,
928*4882a593Smuzhiyun .read_raw = ina2xx_read_raw,
929*4882a593Smuzhiyun .read_avail = ina2xx_read_avail,
930*4882a593Smuzhiyun .write_raw = ina2xx_write_raw,
931*4882a593Smuzhiyun .debugfs_reg_access = ina2xx_debug_reg,
932*4882a593Smuzhiyun };
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun static const struct iio_info ina226_info = {
935*4882a593Smuzhiyun .attrs = &ina226_attribute_group,
936*4882a593Smuzhiyun .read_raw = ina2xx_read_raw,
937*4882a593Smuzhiyun .write_raw = ina2xx_write_raw,
938*4882a593Smuzhiyun .debugfs_reg_access = ina2xx_debug_reg,
939*4882a593Smuzhiyun };
940*4882a593Smuzhiyun
941*4882a593Smuzhiyun /* Initialize the configuration and calibration registers. */
ina2xx_init(struct ina2xx_chip_info * chip,unsigned int config)942*4882a593Smuzhiyun static int ina2xx_init(struct ina2xx_chip_info *chip, unsigned int config)
943*4882a593Smuzhiyun {
944*4882a593Smuzhiyun int ret = regmap_write(chip->regmap, INA2XX_CONFIG, config);
945*4882a593Smuzhiyun if (ret)
946*4882a593Smuzhiyun return ret;
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun return ina2xx_set_calibration(chip);
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun
ina2xx_probe(struct i2c_client * client,const struct i2c_device_id * id)951*4882a593Smuzhiyun static int ina2xx_probe(struct i2c_client *client,
952*4882a593Smuzhiyun const struct i2c_device_id *id)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun struct ina2xx_chip_info *chip;
955*4882a593Smuzhiyun struct iio_dev *indio_dev;
956*4882a593Smuzhiyun struct iio_buffer *buffer;
957*4882a593Smuzhiyun unsigned int val;
958*4882a593Smuzhiyun enum ina2xx_ids type;
959*4882a593Smuzhiyun int ret;
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
962*4882a593Smuzhiyun if (!indio_dev)
963*4882a593Smuzhiyun return -ENOMEM;
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun chip = iio_priv(indio_dev);
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun /* This is only used for device removal purposes. */
968*4882a593Smuzhiyun i2c_set_clientdata(client, indio_dev);
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun chip->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config);
971*4882a593Smuzhiyun if (IS_ERR(chip->regmap)) {
972*4882a593Smuzhiyun dev_err(&client->dev, "failed to allocate register map\n");
973*4882a593Smuzhiyun return PTR_ERR(chip->regmap);
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun if (client->dev.of_node)
977*4882a593Smuzhiyun type = (enum ina2xx_ids)of_device_get_match_data(&client->dev);
978*4882a593Smuzhiyun else
979*4882a593Smuzhiyun type = id->driver_data;
980*4882a593Smuzhiyun chip->config = &ina2xx_config[type];
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun mutex_init(&chip->state_lock);
983*4882a593Smuzhiyun
984*4882a593Smuzhiyun if (of_property_read_u32(client->dev.of_node,
985*4882a593Smuzhiyun "shunt-resistor", &val) < 0) {
986*4882a593Smuzhiyun struct ina2xx_platform_data *pdata =
987*4882a593Smuzhiyun dev_get_platdata(&client->dev);
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun if (pdata)
990*4882a593Smuzhiyun val = pdata->shunt_uohms;
991*4882a593Smuzhiyun else
992*4882a593Smuzhiyun val = INA2XX_RSHUNT_DEFAULT;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun ret = set_shunt_resistor(chip, val);
996*4882a593Smuzhiyun if (ret)
997*4882a593Smuzhiyun return ret;
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun /* Patch the current config register with default. */
1000*4882a593Smuzhiyun val = chip->config->config_default;
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun if (id->driver_data == ina226) {
1003*4882a593Smuzhiyun ina226_set_average(chip, INA226_DEFAULT_AVG, &val);
1004*4882a593Smuzhiyun ina226_set_int_time_vbus(chip, INA226_DEFAULT_IT, &val);
1005*4882a593Smuzhiyun ina226_set_int_time_vshunt(chip, INA226_DEFAULT_IT, &val);
1006*4882a593Smuzhiyun } else {
1007*4882a593Smuzhiyun chip->avg = 1;
1008*4882a593Smuzhiyun ina219_set_int_time_vbus(chip, INA219_DEFAULT_IT, &val);
1009*4882a593Smuzhiyun ina219_set_int_time_vshunt(chip, INA219_DEFAULT_IT, &val);
1010*4882a593Smuzhiyun ina219_set_vbus_range_denom(chip, INA219_DEFAULT_BRNG, &val);
1011*4882a593Smuzhiyun ina219_set_vshunt_pga_gain(chip, INA219_DEFAULT_PGA, &val);
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun
1014*4882a593Smuzhiyun ret = ina2xx_init(chip, val);
1015*4882a593Smuzhiyun if (ret) {
1016*4882a593Smuzhiyun dev_err(&client->dev, "error configuring the device\n");
1017*4882a593Smuzhiyun return ret;
1018*4882a593Smuzhiyun }
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
1021*4882a593Smuzhiyun if (id->driver_data == ina226) {
1022*4882a593Smuzhiyun indio_dev->channels = ina226_channels;
1023*4882a593Smuzhiyun indio_dev->num_channels = ARRAY_SIZE(ina226_channels);
1024*4882a593Smuzhiyun indio_dev->info = &ina226_info;
1025*4882a593Smuzhiyun } else {
1026*4882a593Smuzhiyun indio_dev->channels = ina219_channels;
1027*4882a593Smuzhiyun indio_dev->num_channels = ARRAY_SIZE(ina219_channels);
1028*4882a593Smuzhiyun indio_dev->info = &ina219_info;
1029*4882a593Smuzhiyun }
1030*4882a593Smuzhiyun indio_dev->name = id->name;
1031*4882a593Smuzhiyun indio_dev->setup_ops = &ina2xx_setup_ops;
1032*4882a593Smuzhiyun
1033*4882a593Smuzhiyun buffer = devm_iio_kfifo_allocate(&indio_dev->dev);
1034*4882a593Smuzhiyun if (!buffer)
1035*4882a593Smuzhiyun return -ENOMEM;
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun iio_device_attach_buffer(indio_dev, buffer);
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun return iio_device_register(indio_dev);
1040*4882a593Smuzhiyun }
1041*4882a593Smuzhiyun
ina2xx_remove(struct i2c_client * client)1042*4882a593Smuzhiyun static int ina2xx_remove(struct i2c_client *client)
1043*4882a593Smuzhiyun {
1044*4882a593Smuzhiyun struct iio_dev *indio_dev = i2c_get_clientdata(client);
1045*4882a593Smuzhiyun struct ina2xx_chip_info *chip = iio_priv(indio_dev);
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun iio_device_unregister(indio_dev);
1048*4882a593Smuzhiyun
1049*4882a593Smuzhiyun /* Powerdown */
1050*4882a593Smuzhiyun return regmap_update_bits(chip->regmap, INA2XX_CONFIG,
1051*4882a593Smuzhiyun INA2XX_MODE_MASK, 0);
1052*4882a593Smuzhiyun }
1053*4882a593Smuzhiyun
1054*4882a593Smuzhiyun static const struct i2c_device_id ina2xx_id[] = {
1055*4882a593Smuzhiyun {"ina219", ina219},
1056*4882a593Smuzhiyun {"ina220", ina219},
1057*4882a593Smuzhiyun {"ina226", ina226},
1058*4882a593Smuzhiyun {"ina230", ina226},
1059*4882a593Smuzhiyun {"ina231", ina226},
1060*4882a593Smuzhiyun {}
1061*4882a593Smuzhiyun };
1062*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, ina2xx_id);
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun static const struct of_device_id ina2xx_of_match[] = {
1065*4882a593Smuzhiyun {
1066*4882a593Smuzhiyun .compatible = "ti,ina219",
1067*4882a593Smuzhiyun .data = (void *)ina219
1068*4882a593Smuzhiyun },
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun .compatible = "ti,ina220",
1071*4882a593Smuzhiyun .data = (void *)ina219
1072*4882a593Smuzhiyun },
1073*4882a593Smuzhiyun {
1074*4882a593Smuzhiyun .compatible = "ti,ina226",
1075*4882a593Smuzhiyun .data = (void *)ina226
1076*4882a593Smuzhiyun },
1077*4882a593Smuzhiyun {
1078*4882a593Smuzhiyun .compatible = "ti,ina230",
1079*4882a593Smuzhiyun .data = (void *)ina226
1080*4882a593Smuzhiyun },
1081*4882a593Smuzhiyun {
1082*4882a593Smuzhiyun .compatible = "ti,ina231",
1083*4882a593Smuzhiyun .data = (void *)ina226
1084*4882a593Smuzhiyun },
1085*4882a593Smuzhiyun {},
1086*4882a593Smuzhiyun };
1087*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, ina2xx_of_match);
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun static struct i2c_driver ina2xx_driver = {
1090*4882a593Smuzhiyun .driver = {
1091*4882a593Smuzhiyun .name = KBUILD_MODNAME,
1092*4882a593Smuzhiyun .of_match_table = ina2xx_of_match,
1093*4882a593Smuzhiyun },
1094*4882a593Smuzhiyun .probe = ina2xx_probe,
1095*4882a593Smuzhiyun .remove = ina2xx_remove,
1096*4882a593Smuzhiyun .id_table = ina2xx_id,
1097*4882a593Smuzhiyun };
1098*4882a593Smuzhiyun module_i2c_driver(ina2xx_driver);
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun MODULE_AUTHOR("Marc Titinger <marc.titinger@baylibre.com>");
1101*4882a593Smuzhiyun MODULE_DESCRIPTION("Texas Instruments INA2XX ADC driver");
1102*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1103