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