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