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