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