* [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register [not found] <20171001194818.26017-1-stefan.bruens@rwth-aachen.de> @ 2017-10-01 19:48 ` Stefan Brüns 2017-10-08 9:57 ` Jonathan Cameron 2017-10-01 19:48 ` [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm Stefan Brüns 2017-10-01 19:48 ` [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range Stefan Brüns 2 siblings, 1 reply; 13+ messages in thread From: Stefan Brüns @ 2017-10-01 19:48 UTC (permalink / raw) To: linux-iio Cc: Peter Meerwald-Stadler, Stefan Brüns, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack Lower bits of the INA219/220 bus voltage register are conversion status flags, properly mask the value. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> --- drivers/iio/adc/ina2xx-adc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index f387b972e4f4..361fb4e459d5 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -44,7 +44,6 @@ #define INA226_MASK_ENABLE 0x06 #define INA226_CVRF BIT(3) -#define INA219_CNVR BIT(1) #define INA2XX_MAX_REGISTERS 8 @@ -79,6 +78,11 @@ #define INA226_ITS_MASK GENMASK(5, 3) #define INA226_SHIFT_ITS(val) ((val) << 3) +/* INA219 Bus voltage register, low bits are flags */ +#define INA219_OVF BIT(0) +#define INA219_CNVR BIT(1) +#define INA219_BUS_VOLTAGE_MASK GENMASK(16, 3) + /* Cosmetic macro giving the sampling period for a full P=UxI cycle */ #define SAMPLING_PERIOD(c) ((c->int_time_vbus + c->int_time_vshunt) \ * c->avg) @@ -170,6 +174,10 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, else *val = regval; + if ((chip->config->chip_id == ina219) && + (chan->address == INA2XX_SHUNT_VOLTAGE)) + *val &= INA219_BUS_VOLTAGE_MASK; + return IIO_VAL_INT; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: @@ -639,6 +647,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) if (ret < 0) return ret; + if ((chip->config->chip_id == ina219) && + (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_BUS_VOLTAGE)) + val &= INA219_BUS_VOLTAGE_MASK; + data[i++] = val; if (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_POWER) -- 2.14.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register 2017-10-01 19:48 ` [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register Stefan Brüns @ 2017-10-08 9:57 ` Jonathan Cameron 0 siblings, 0 replies; 13+ messages in thread From: Jonathan Cameron @ 2017-10-08 9:57 UTC (permalink / raw) To: Stefan Brüns Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Hartmut Knaack On Sun, 1 Oct 2017 21:48:16 +0200 Stefan Brüns <stefan.bruens@rwth-aachen.de> wrote: > Lower bits of the INA219/220 bus voltage register are conversion > status flags, properly mask the value. > > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Hi, good to find this issue, but the 'right' fix is perhaps a little more complex than present here. Jonathan > --- > > drivers/iio/adc/ina2xx-adc.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c > index f387b972e4f4..361fb4e459d5 100644 > --- a/drivers/iio/adc/ina2xx-adc.c > +++ b/drivers/iio/adc/ina2xx-adc.c > @@ -44,7 +44,6 @@ > > #define INA226_MASK_ENABLE 0x06 > #define INA226_CVRF BIT(3) > -#define INA219_CNVR BIT(1) > > #define INA2XX_MAX_REGISTERS 8 > > @@ -79,6 +78,11 @@ > #define INA226_ITS_MASK GENMASK(5, 3) > #define INA226_SHIFT_ITS(val) ((val) << 3) > > +/* INA219 Bus voltage register, low bits are flags */ > +#define INA219_OVF BIT(0) > +#define INA219_CNVR BIT(1) > +#define INA219_BUS_VOLTAGE_MASK GENMASK(16, 3) > + > /* Cosmetic macro giving the sampling period for a full P=UxI cycle */ > #define SAMPLING_PERIOD(c) ((c->int_time_vbus + c->int_time_vshunt) \ > * c->avg) > @@ -170,6 +174,10 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, > else > *val = regval; > > + if ((chip->config->chip_id == ina219) && > + (chan->address == INA2XX_SHUNT_VOLTAGE)) > + *val &= INA219_BUS_VOLTAGE_MASK; > + This first case is fine - up to the fact that it should really be shifting it appropriately to not give a false impression of precision. Also correctly unwinding the case below may require some changes here as well as the scale will change. > return IIO_VAL_INT; > > case IIO_CHAN_INFO_OVERSAMPLING_RATIO: > @@ -639,6 +647,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) > if (ret < 0) > return ret; > > + if ((chip->config->chip_id == ina219) && > + (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_BUS_VOLTAGE)) > + val &= INA219_BUS_VOLTAGE_MASK; > + For this I'm not sure this is the correct fix. The driver should not be lying about the available data when describing the channel. Right now the channel description is: #define INA219_CHAN_VOLTAGE(_index, _address) { \ .type = IIO_VOLTAGE, \ .address = (_address), \ .indexed = 1, \ .channel = (_index), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_INT_TIME), \ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (_index), \ .scan_type = { \ .sign = 'u', \ .realbits = 16, \ .storagebits = 16, \ .endianness = IIO_LE, \ } \ } Reading the datasheet this should be .realbits = 13, .shift = 3, I think Userspace is then responsible for masking and shifting the data to not give a false impression of it's precision. Clearly this with probably have some knock on effects that will also need fixing. > data[i++] = val; > > if (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_POWER) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm [not found] <20171001194818.26017-1-stefan.bruens@rwth-aachen.de> 2017-10-01 19:48 ` [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register Stefan Brüns @ 2017-10-01 19:48 ` Stefan Brüns 2017-10-08 10:03 ` Jonathan Cameron [not found] ` <CGME20171009092944eucas1p18b2e66a4a07db309551a7e945c2611ec@eucas1p1.samsung.com> 2017-10-01 19:48 ` [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range Stefan Brüns 2 siblings, 2 replies; 13+ messages in thread From: Stefan Brüns @ 2017-10-01 19:48 UTC (permalink / raw) To: linux-iio Cc: Peter Meerwald-Stadler, Stefan Brüns, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack According to the ABI documentation, the shunt resistor value should be specificied in Ohm. As this is also used/documented for the MAX9611, use the same for the INA2xx driver. This poses an ABI break for anyone actually altering the shunt value through the sysfs interface, it does not alter the default value nor a value set from the devicetree. Minor change: Fix comment, 1mA is 10^-3A. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> --- drivers/iio/adc/ina2xx-adc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 361fb4e459d5..1930f853e8c5 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -127,7 +127,7 @@ struct ina2xx_chip_info { struct task_struct *task; const struct ina2xx_config *config; struct mutex state_lock; - unsigned int shunt_resistor; + unsigned int shunt_resistor_uohm; int avg; int int_time_vbus; /* Bus voltage integration time uS */ int int_time_vshunt; /* Shunt voltage integration time uS */ @@ -444,7 +444,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, /* * Set current LSB to 1mA, shunt is in uOhms * (equation 13 in datasheet). We hardcode a Current_LSB - * of 1.0 x10-6. The only remaining parameter is RShunt. + * of 1.0 x10-3. The only remaining parameter is RShunt. * There is no need to expose the CALIBRATION register * to the user for now. But we need to reset this register * if the user updates RShunt after driver init, e.g upon @@ -453,7 +453,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) { u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->shunt_resistor); + chip->shunt_resistor_uohm); return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); } @@ -463,7 +463,7 @@ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) if (val <= 0 || val > chip->config->calibration_factor) return -EINVAL; - chip->shunt_resistor = val; + chip->shunt_resistor_uohm = val; return 0; } @@ -473,8 +473,9 @@ static ssize_t ina2xx_shunt_resistor_show(struct device *dev, char *buf) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + int vals[2] = { chip->shunt_resistor_uohm, 1000000 }; - return sprintf(buf, "%d\n", chip->shunt_resistor); + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); } static ssize_t ina2xx_shunt_resistor_store(struct device *dev, @@ -482,14 +483,13 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, const char *buf, size_t len) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); - unsigned long val; - int ret; + int val, val_fract, ret; - ret = kstrtoul((const char *) buf, 10, &val); + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); if (ret) return ret; - ret = set_shunt_resistor(chip, val); + ret = set_shunt_resistor(chip, val * 1000000 + val_fract); if (ret) return ret; -- 2.14.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-10-01 19:48 ` [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm Stefan Brüns @ 2017-10-08 10:03 ` Jonathan Cameron [not found] ` <CGME20171009092944eucas1p18b2e66a4a07db309551a7e945c2611ec@eucas1p1.samsung.com> 1 sibling, 0 replies; 13+ messages in thread From: Jonathan Cameron @ 2017-10-08 10:03 UTC (permalink / raw) To: Stefan Brüns Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Hartmut Knaack On Sun, 1 Oct 2017 21:48:17 +0200 Stefan Brüns <stefan.bruens@rwth-aachen.de> wrote: > According to the ABI documentation, the shunt resistor value should be > specificied in Ohm. As this is also used/documented for the MAX9611, > use the same for the INA2xx driver. > > This poses an ABI break for anyone actually altering the shunt value > through the sysfs interface, it does not alter the default value nor > a value set from the devicetree. Yeah, I messed up on this an missed that we had a number of different drivers with different scaling on this.. Sorry about that. So I think we need to apply this to get consistency - changing shunt resistance from userspace does seem fairly unusual though so fingers crossed that no one is doing it. I'm going to do this the slow way though so hopefully we get shouts before breaking too many people. Hence I'm routing this through the next merge window. After it's been in mainline all the way to release, if no-one complains we can request it is added to stable. Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > > Minor change: Fix comment, 1mA is 10^-3A. > > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> > --- > > drivers/iio/adc/ina2xx-adc.c | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c > index 361fb4e459d5..1930f853e8c5 100644 > --- a/drivers/iio/adc/ina2xx-adc.c > +++ b/drivers/iio/adc/ina2xx-adc.c > @@ -127,7 +127,7 @@ struct ina2xx_chip_info { > struct task_struct *task; > const struct ina2xx_config *config; > struct mutex state_lock; > - unsigned int shunt_resistor; > + unsigned int shunt_resistor_uohm; > int avg; > int int_time_vbus; /* Bus voltage integration time uS */ > int int_time_vshunt; /* Shunt voltage integration time uS */ > @@ -444,7 +444,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, > /* > * Set current LSB to 1mA, shunt is in uOhms > * (equation 13 in datasheet). We hardcode a Current_LSB > - * of 1.0 x10-6. The only remaining parameter is RShunt. > + * of 1.0 x10-3. The only remaining parameter is RShunt. > * There is no need to expose the CALIBRATION register > * to the user for now. But we need to reset this register > * if the user updates RShunt after driver init, e.g upon > @@ -453,7 +453,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, > static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) > { > u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, > - chip->shunt_resistor); > + chip->shunt_resistor_uohm); > > return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); > } > @@ -463,7 +463,7 @@ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) > if (val <= 0 || val > chip->config->calibration_factor) > return -EINVAL; > > - chip->shunt_resistor = val; > + chip->shunt_resistor_uohm = val; > > return 0; > } > @@ -473,8 +473,9 @@ static ssize_t ina2xx_shunt_resistor_show(struct device *dev, > char *buf) > { > struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); > + int vals[2] = { chip->shunt_resistor_uohm, 1000000 }; > > - return sprintf(buf, "%d\n", chip->shunt_resistor); > + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); > } > > static ssize_t ina2xx_shunt_resistor_store(struct device *dev, > @@ -482,14 +483,13 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, > const char *buf, size_t len) > { > struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); > - unsigned long val; > - int ret; > + int val, val_fract, ret; > > - ret = kstrtoul((const char *) buf, 10, &val); > + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); > if (ret) > return ret; > > - ret = set_shunt_resistor(chip, val); > + ret = set_shunt_resistor(chip, val * 1000000 + val_fract); > if (ret) > return ret; > ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <CGME20171009092944eucas1p18b2e66a4a07db309551a7e945c2611ec@eucas1p1.samsung.com>]
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm [not found] ` <CGME20171009092944eucas1p18b2e66a4a07db309551a7e945c2611ec@eucas1p1.samsung.com> @ 2017-10-09 9:29 ` Maciej Purski 2017-10-14 18:27 ` Stefan Bruens 0 siblings, 1 reply; 13+ messages in thread From: Maciej Purski @ 2017-10-09 9:29 UTC (permalink / raw) To: Stefan Brüns, linux-iio Cc: Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack On 10/01/2017 09:48 PM, Stefan Brüns wrote: > According to the ABI documentation, the shunt resistor value should be > specificied in Ohm. As this is also used/documented for the MAX9611, > use the same for the INA2xx driver. > > This poses an ABI break for anyone actually altering the shunt value > through the sysfs interface, it does not alter the default value nor > a value set from the devicetree. > > Minor change: Fix comment, 1mA is 10^-3A. > I have just a minor issue. There could be an inconsistency with units as in my patch I make current_lsb adjustable and I need it to be in uA (it used to be hardcoded as 1 mA so to achieve better precision we need smaller units). So in order to keep calibration register properly scaled, I convert uOhms to mOhms on each set_calibration(). So if both my changes and your changes were applied, on each shunt_resistore_store we would be performing multiplication by 10^6 and then in set_calibration() division by 10^3 which seems odd to me. I guess we could keep it as shunt_resistor_ohms instead of shunt_resistor_uohm. We could avoid performing division on each shunt_resistor_show() and perform multiplication by 10^3 only once in set_calibration() on each shunt_resistore_store(). We could then change the default value and perform division only on probing, when reading the shunt_resistance from device tree. There are many other options. It's not a major issue so maybe we could leave it as it is or you could suggest some changes in my patch. > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> > --- > > drivers/iio/adc/ina2xx-adc.c | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c > index 361fb4e459d5..1930f853e8c5 100644 > --- a/drivers/iio/adc/ina2xx-adc.c > +++ b/drivers/iio/adc/ina2xx-adc.c > @@ -127,7 +127,7 @@ struct ina2xx_chip_info { > struct task_struct *task; > const struct ina2xx_config *config; > struct mutex state_lock; > - unsigned int shunt_resistor; > + unsigned int shunt_resistor_uohm; > int avg; > int int_time_vbus; /* Bus voltage integration time uS */ > int int_time_vshunt; /* Shunt voltage integration time uS */ > @@ -444,7 +444,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, > /* > * Set current LSB to 1mA, shunt is in uOhms > * (equation 13 in datasheet). We hardcode a Current_LSB > - * of 1.0 x10-6. The only remaining parameter is RShunt. > + * of 1.0 x10-3. The only remaining parameter is RShunt. > * There is no need to expose the CALIBRATION register > * to the user for now. But we need to reset this register > * if the user updates RShunt after driver init, e.g upon > @@ -453,7 +453,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, > static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) > { > u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, > - chip->shunt_resistor); > + chip->shunt_resistor_uohm); > > return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); > } > @@ -463,7 +463,7 @@ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) > if (val <= 0 || val > chip->config->calibration_factor) > return -EINVAL; > > - chip->shunt_resistor = val; > + chip->shunt_resistor_uohm = val; > > return 0; > } > @@ -473,8 +473,9 @@ static ssize_t ina2xx_shunt_resistor_show(struct device *dev, > char *buf) > { > struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); > + int vals[2] = { chip->shunt_resistor_uohm, 1000000 }; > > - return sprintf(buf, "%d\n", chip->shunt_resistor); > + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); > } > > static ssize_t ina2xx_shunt_resistor_store(struct device *dev, > @@ -482,14 +483,13 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, > const char *buf, size_t len) > { > struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); > - unsigned long val; > - int ret; > + int val, val_fract, ret; > > - ret = kstrtoul((const char *) buf, 10, &val); > + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); > if (ret) > return ret; > > - ret = set_shunt_resistor(chip, val); > + ret = set_shunt_resistor(chip, val * 1000000 + val_fract); > if (ret) > return ret; > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-10-09 9:29 ` [2/3] " Maciej Purski @ 2017-10-14 18:27 ` Stefan Bruens 2017-11-02 9:04 ` Maciej Purski 0 siblings, 1 reply; 13+ messages in thread From: Stefan Bruens @ 2017-10-14 18:27 UTC (permalink / raw) To: Maciej Purski Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack On Montag, 9. Oktober 2017 11:29:43 CEST Maciej Purski wrote: > On 10/01/2017 09:48 PM, Stefan Brüns wrote: > > According to the ABI documentation, the shunt resistor value should be > > specificied in Ohm. As this is also used/documented for the MAX9611, > > use the same for the INA2xx driver. > > > > This poses an ABI break for anyone actually altering the shunt value > > through the sysfs interface, it does not alter the default value nor > > a value set from the devicetree. > > > > Minor change: Fix comment, 1mA is 10^-3A. > > I have just a minor issue. There could be an inconsistency with units as in > my patch I make current_lsb adjustable and I need it to be in uA (it used > to be hardcoded as 1 mA so to achieve better precision we need smaller > units). So in order to keep calibration register properly scaled, I convert > uOhms to mOhms on each set_calibration(). So if both my changes and your > changes were applied, on each shunt_resistore_store we would be performing > multiplication by 10^6 and then in set_calibration() division by 10^3 which > seems odd to me. > > I guess we could keep it as shunt_resistor_ohms instead of > shunt_resistor_uohm. We could avoid performing division on each > shunt_resistor_show() and perform multiplication by 10^3 only once in > set_calibration() on each > shunt_resistore_store(). We could then change the default value and perform > division only on probing, when reading the shunt_resistance from device > tree. > > There are many other options. It's not a major issue so maybe we could leave > it as it is or you could suggest some changes in my patch. Sorry it took me so long to answer ... The current fixed current_lsb of 1mA is indeed a bad choice for everything but a shunt resistor value of 10mOhm, as it truncates the current value. So what is a *good* choice? One important point is the current register is merely more than a convenience register. At least for the INA219/220, it provides nothing not achievable in software, and for the INA226 family it only has added value if the current is varying faster than the readout frequency and the averaging is used. The precision of the current register is limited by the precision of the shunt voltage register, and may be reduced by the applied scaling/calibration factor. The precision of the shunt voltage register is fixed at 10uV (INA219) resp. 2.5uV (INA226). Changing conversion time (both) and PGA (219) affects the noise and offset, but the lsb value is still fixed. If one wants to carry over the shunt voltage register precision into the current register, its important no (or hardly any) truncation happens. The terms therefor are given in the manual, formulas 8.5.1 (4) resp 7.5.1 (3): INA219: current = shunt_voltage * cal_register / 4096 INA226: current = shunt_voltage * cal_register / 2048 So any cal value smaller than 4096 (2048) will introduce truncation errors, larger values may introduce overflows, if the full input range is used. Now, would it not be wise to always use 4096 (2048) for the calibration value? The raw values from the IIO subsystem are meaningless without their accompanying scale factor. Instead of changing the calibration value, why not just change the reported scale factor? More opinions are very welcome. Kind regards, Stefan -- Stefan Brüns / Bergstraße 21 / 52062 Aachen home: +49 241 53809034 mobile: +49 151 50412019 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-10-14 18:27 ` Stefan Bruens @ 2017-11-02 9:04 ` Maciej Purski 2017-11-06 10:21 ` Stefan Brüns 0 siblings, 1 reply; 13+ messages in thread From: Maciej Purski @ 2017-11-02 9:04 UTC (permalink / raw) To: Stefan Bruens Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack On 10/14/2017 08:27 PM, Stefan Bruens wrote: > On Montag, 9. Oktober 2017 11:29:43 CEST Maciej Purski wrote: >> On 10/01/2017 09:48 PM, Stefan Brüns wrote: >>> According to the ABI documentation, the shunt resistor value should be >>> specificied in Ohm. As this is also used/documented for the MAX9611, >>> use the same for the INA2xx driver. >>> >>> This poses an ABI break for anyone actually altering the shunt value >>> through the sysfs interface, it does not alter the default value nor >>> a value set from the devicetree. >>> >>> Minor change: Fix comment, 1mA is 10^-3A. >> >> I have just a minor issue. There could be an inconsistency with units as in >> my patch I make current_lsb adjustable and I need it to be in uA (it used >> to be hardcoded as 1 mA so to achieve better precision we need smaller >> units). So in order to keep calibration register properly scaled, I convert >> uOhms to mOhms on each set_calibration(). So if both my changes and your >> changes were applied, on each shunt_resistore_store we would be performing >> multiplication by 10^6 and then in set_calibration() division by 10^3 which >> seems odd to me. >> >> I guess we could keep it as shunt_resistor_ohms instead of >> shunt_resistor_uohm. We could avoid performing division on each >> shunt_resistor_show() and perform multiplication by 10^3 only once in >> set_calibration() on each >> shunt_resistore_store(). We could then change the default value and perform >> division only on probing, when reading the shunt_resistance from device >> tree. >> >> There are many other options. It's not a major issue so maybe we could leave >> it as it is or you could suggest some changes in my patch. > > Sorry it took me so long to answer ... > > The current fixed current_lsb of 1mA is indeed a bad choice for everything but > a shunt resistor value of 10mOhm, as it truncates the current value. So what > is a *good* choice? > > One important point is the current register is merely more than a convenience > register. At least for the INA219/220, it provides nothing not achievable in > software, and for the INA226 family it only has added value if the current is > varying faster than the readout frequency and the averaging is used. > > The precision of the current register is limited by the precision of the shunt > voltage register, and may be reduced by the applied scaling/calibration > factor. > > The precision of the shunt voltage register is fixed at 10uV (INA219) resp. > 2.5uV (INA226). Changing conversion time (both) and PGA (219) affects the > noise and offset, but the lsb value is still fixed. > > If one wants to carry over the shunt voltage register precision into the > current register, its important no (or hardly any) truncation happens. The > terms therefor are given in the manual, formulas 8.5.1 (4) resp 7.5.1 (3): > > INA219: current = shunt_voltage * cal_register / 4096 > INA226: current = shunt_voltage * cal_register / 2048 > > So any cal value smaller than 4096 (2048) will introduce truncation errors, > larger values may introduce overflows, if the full input range is used. Now, > would it not be wise to always use 4096 (2048) for the calibration value? > > The raw values from the IIO subsystem are meaningless without their > accompanying scale factor. Instead of changing the calibration value, why not > just change the reported scale factor? > > More opinions are very welcome. > > Kind regards, > > Stefan > Thanks for the reply. I agree that cal_register set to 4096 (2048) allows us to eliminate truncaction error. However according to your suggestion, if we made cal_reg a fixed value, then current_lsb and r_shunt should be also a fixed value, as they are related according to formula 8.5 (1) cal_register = 0.00512 / (current_lsb * r_shunt) Therefore, changing the scale value wouldn't affect the calib_reg value, so it wouldn't give the user any information on the actual current_lsb of the device. The real value is calculated like this by the user: processed_value = raw_value * scale I think that even after changing the scale value processed_value is expected to be approximately the same. Maybe I'm wrong or I didn't precisely understand what you have suggested. I hope that someone will also comment on that. Best regards, Maciej ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-11-02 9:04 ` Maciej Purski @ 2017-11-06 10:21 ` Stefan Brüns 2017-11-08 13:22 ` Maciej Purski 0 siblings, 1 reply; 13+ messages in thread From: Stefan Brüns @ 2017-11-06 10:21 UTC (permalink / raw) To: Maciej Purski Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack [-- Attachment #1: Type: text/plain, Size: 5248 bytes --] On Thursday, November 2, 2017 10:04:01 AM CET Maciej Purski wrote: > On 10/14/2017 08:27 PM, Stefan Bruens wrote: > > On Montag, 9. Oktober 2017 11:29:43 CEST Maciej Purski wrote: > >> On 10/01/2017 09:48 PM, Stefan Brüns wrote: > >>> According to the ABI documentation, the shunt resistor value should be > >>> specificied in Ohm. As this is also used/documented for the MAX9611, > >>> use the same for the INA2xx driver. > >>> > >>> This poses an ABI break for anyone actually altering the shunt value > >>> through the sysfs interface, it does not alter the default value nor > >>> a value set from the devicetree. > >>> > >>> Minor change: Fix comment, 1mA is 10^-3A. > >> > >> I have just a minor issue. There could be an inconsistency with units as > >> in > >> my patch I make current_lsb adjustable and I need it to be in uA (it used > >> to be hardcoded as 1 mA so to achieve better precision we need smaller > >> units). So in order to keep calibration register properly scaled, I > >> convert > >> uOhms to mOhms on each set_calibration(). So if both my changes and your > >> changes were applied, on each shunt_resistore_store we would be > >> performing > >> multiplication by 10^6 and then in set_calibration() division by 10^3 > >> which > >> seems odd to me. > >> > >> I guess we could keep it as shunt_resistor_ohms instead of > >> shunt_resistor_uohm. We could avoid performing division on each > >> shunt_resistor_show() and perform multiplication by 10^3 only once in > >> set_calibration() on each > >> shunt_resistore_store(). We could then change the default value and > >> perform > >> division only on probing, when reading the shunt_resistance from device > >> tree. > >> > >> There are many other options. It's not a major issue so maybe we could > >> leave it as it is or you could suggest some changes in my patch. > > > > Sorry it took me so long to answer ... > > > > The current fixed current_lsb of 1mA is indeed a bad choice for everything > > but a shunt resistor value of 10mOhm, as it truncates the current value. > > So what is a *good* choice? > > > > One important point is the current register is merely more than a > > convenience register. At least for the INA219/220, it provides nothing > > not achievable in software, and for the INA226 family it only has added > > value if the current is varying faster than the readout frequency and the > > averaging is used. > > > > The precision of the current register is limited by the precision of the > > shunt voltage register, and may be reduced by the applied > > scaling/calibration factor. > > > > The precision of the shunt voltage register is fixed at 10uV (INA219) > > resp. > > 2.5uV (INA226). Changing conversion time (both) and PGA (219) affects the > > noise and offset, but the lsb value is still fixed. > > > > If one wants to carry over the shunt voltage register precision into the > > current register, its important no (or hardly any) truncation happens. The > > terms therefor are given in the manual, formulas 8.5.1 (4) resp 7.5.1 (3): > > > > INA219: current = shunt_voltage * cal_register / 4096 > > INA226: current = shunt_voltage * cal_register / 2048 > > > > So any cal value smaller than 4096 (2048) will introduce truncation > > errors, > > larger values may introduce overflows, if the full input range is used. > > Now, would it not be wise to always use 4096 (2048) for the calibration > > value? > > > > The raw values from the IIO subsystem are meaningless without their > > accompanying scale factor. Instead of changing the calibration value, why > > not just change the reported scale factor? > > > > More opinions are very welcome. > > > > Kind regards, > > > > Stefan > > Thanks for the reply. > > I agree that cal_register set to 4096 (2048) allows us to eliminate > truncaction error. However according to your suggestion, if we made cal_reg > a fixed value, then current_lsb and r_shunt should be also a fixed value, > as they are related according to formula 8.5 (1) > > cal_register = 0.00512 / (current_lsb * r_shunt) A fixed cal_register only means the current_lsb is implied by the selected shunt resistor value. If you insert 2048 into the equation above, you get: current_lsb = 2.5 * 1e-6 * r_shunt, and using Ohms law to replace r_shunt, thats exactly the resolution of the shunt_voltage register as specified in the datasheet. The higher the shunt resistor value, the smaller the current_lsb. > Therefore, changing the scale value wouldn't affect the calib_reg value, so > it wouldn't give the user any information on the actual current_lsb of the > device. The real value is calculated like this by the user: > > processed_value = raw_value * scale > > I think that even after changing the scale value processed_value is expected > to be approximately the same. A fixed cal_register means you change the current_lsb by changing the shunt resistor. This exposes the full ADC resolution. The current_lsb *is* the scale value. Kind regards, Stefan -- Stefan Brüns / Bergstraße 21 / 52062 Aachen home: +49 241 53809034 mobile: +49 151 50412019 [-- Attachment #2: This is a digitally signed message part. --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-11-06 10:21 ` Stefan Brüns @ 2017-11-08 13:22 ` Maciej Purski 2017-11-19 16:57 ` Jonathan Cameron 0 siblings, 1 reply; 13+ messages in thread From: Maciej Purski @ 2017-11-08 13:22 UTC (permalink / raw) To: Stefan Brüns Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack On 11/06/2017 11:21 AM, Stefan Brüns wrote: > On Thursday, November 2, 2017 10:04:01 AM CET Maciej Purski wrote: >> On 10/14/2017 08:27 PM, Stefan Bruens wrote: >>> On Montag, 9. Oktober 2017 11:29:43 CEST Maciej Purski wrote: >>>> On 10/01/2017 09:48 PM, Stefan Brüns wrote: >>>>> According to the ABI documentation, the shunt resistor value should be >>>>> specificied in Ohm. As this is also used/documented for the MAX9611, >>>>> use the same for the INA2xx driver. >>>>> >>>>> This poses an ABI break for anyone actually altering the shunt value >>>>> through the sysfs interface, it does not alter the default value nor >>>>> a value set from the devicetree. >>>>> >>>>> Minor change: Fix comment, 1mA is 10^-3A. >>>> >>>> I have just a minor issue. There could be an inconsistency with units as >>>> in >>>> my patch I make current_lsb adjustable and I need it to be in uA (it used >>>> to be hardcoded as 1 mA so to achieve better precision we need smaller >>>> units). So in order to keep calibration register properly scaled, I >>>> convert >>>> uOhms to mOhms on each set_calibration(). So if both my changes and your >>>> changes were applied, on each shunt_resistore_store we would be >>>> performing >>>> multiplication by 10^6 and then in set_calibration() division by 10^3 >>>> which >>>> seems odd to me. >>>> >>>> I guess we could keep it as shunt_resistor_ohms instead of >>>> shunt_resistor_uohm. We could avoid performing division on each >>>> shunt_resistor_show() and perform multiplication by 10^3 only once in >>>> set_calibration() on each >>>> shunt_resistore_store(). We could then change the default value and >>>> perform >>>> division only on probing, when reading the shunt_resistance from device >>>> tree. >>>> >>>> There are many other options. It's not a major issue so maybe we could >>>> leave it as it is or you could suggest some changes in my patch. >>> >>> Sorry it took me so long to answer ... >>> >>> The current fixed current_lsb of 1mA is indeed a bad choice for everything >>> but a shunt resistor value of 10mOhm, as it truncates the current value. >>> So what is a *good* choice? >>> >>> One important point is the current register is merely more than a >>> convenience register. At least for the INA219/220, it provides nothing >>> not achievable in software, and for the INA226 family it only has added >>> value if the current is varying faster than the readout frequency and the >>> averaging is used. >>> >>> The precision of the current register is limited by the precision of the >>> shunt voltage register, and may be reduced by the applied >>> scaling/calibration factor. >>> >>> The precision of the shunt voltage register is fixed at 10uV (INA219) >>> resp. >>> 2.5uV (INA226). Changing conversion time (both) and PGA (219) affects the >>> noise and offset, but the lsb value is still fixed. >>> >>> If one wants to carry over the shunt voltage register precision into the >>> current register, its important no (or hardly any) truncation happens. The >>> terms therefor are given in the manual, formulas 8.5.1 (4) resp 7.5.1 (3): >>> >>> INA219: current = shunt_voltage * cal_register / 4096 >>> INA226: current = shunt_voltage * cal_register / 2048 >>> >>> So any cal value smaller than 4096 (2048) will introduce truncation >>> errors, >>> larger values may introduce overflows, if the full input range is used. >>> Now, would it not be wise to always use 4096 (2048) for the calibration >>> value? >>> >>> The raw values from the IIO subsystem are meaningless without their >>> accompanying scale factor. Instead of changing the calibration value, why >>> not just change the reported scale factor? >>> >>> More opinions are very welcome. >>> >>> Kind regards, >>> >>> Stefan >> >> Thanks for the reply. >> >> I agree that cal_register set to 4096 (2048) allows us to eliminate >> truncaction error. However according to your suggestion, if we made cal_reg >> a fixed value, then current_lsb and r_shunt should be also a fixed value, >> as they are related according to formula 8.5 (1) >> >> cal_register = 0.00512 / (current_lsb * r_shunt) > > A fixed cal_register only means the current_lsb is implied by the selected > shunt resistor value. > > If you insert 2048 into the equation above, you get: > > current_lsb = 2.5 * 1e-6 * r_shunt, > > and using Ohms law to replace r_shunt, thats exactly the resolution of the > shunt_voltage register as specified in the datasheet. The higher the shunt > resistor value, the smaller the current_lsb. > >> Therefore, changing the scale value wouldn't affect the calib_reg value, so >> it wouldn't give the user any information on the actual current_lsb of the >> device. The real value is calculated like this by the user: >> >> processed_value = raw_value * scale >> >> I think that even after changing the scale value processed_value is expected >> to be approximately the same. > > A fixed cal_register means you change the current_lsb by changing the shunt > resistor. This exposes the full ADC resolution. > > The current_lsb *is* the scale value. > > Kind regards, > > Stefan > Thanks for your explanation. I can do this the way you suggest, so the only change with the original driver would be to make current_lsb (which is a scale value) follow changes of shunt_resistance value from userspace. But before I'd like to ask Jonathan for opinion on that. Kind regards, Maciej ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm 2017-11-08 13:22 ` Maciej Purski @ 2017-11-19 16:57 ` Jonathan Cameron 0 siblings, 0 replies; 13+ messages in thread From: Jonathan Cameron @ 2017-11-19 16:57 UTC (permalink / raw) To: Maciej Purski Cc: Stefan Brüns, linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Hartmut Knaack On Wed, 08 Nov 2017 14:22:08 +0100 Maciej Purski <m.purski@samsung.com> wrote: > On 11/06/2017 11:21 AM, Stefan Brüns wrote: > > On Thursday, November 2, 2017 10:04:01 AM CET Maciej Purski wrote: > >> On 10/14/2017 08:27 PM, Stefan Bruens wrote: > >>> On Montag, 9. Oktober 2017 11:29:43 CEST Maciej Purski wrote: > >>>> On 10/01/2017 09:48 PM, Stefan Brüns wrote: > >>>>> According to the ABI documentation, the shunt resistor value should be > >>>>> specificied in Ohm. As this is also used/documented for the MAX9611, > >>>>> use the same for the INA2xx driver. > >>>>> > >>>>> This poses an ABI break for anyone actually altering the shunt value > >>>>> through the sysfs interface, it does not alter the default value nor > >>>>> a value set from the devicetree. > >>>>> > >>>>> Minor change: Fix comment, 1mA is 10^-3A. > >>>> > >>>> I have just a minor issue. There could be an inconsistency with units as > >>>> in > >>>> my patch I make current_lsb adjustable and I need it to be in uA (it used > >>>> to be hardcoded as 1 mA so to achieve better precision we need smaller > >>>> units). So in order to keep calibration register properly scaled, I > >>>> convert > >>>> uOhms to mOhms on each set_calibration(). So if both my changes and your > >>>> changes were applied, on each shunt_resistore_store we would be > >>>> performing > >>>> multiplication by 10^6 and then in set_calibration() division by 10^3 > >>>> which > >>>> seems odd to me. > >>>> > >>>> I guess we could keep it as shunt_resistor_ohms instead of > >>>> shunt_resistor_uohm. We could avoid performing division on each > >>>> shunt_resistor_show() and perform multiplication by 10^3 only once in > >>>> set_calibration() on each > >>>> shunt_resistore_store(). We could then change the default value and > >>>> perform > >>>> division only on probing, when reading the shunt_resistance from device > >>>> tree. > >>>> > >>>> There are many other options. It's not a major issue so maybe we could > >>>> leave it as it is or you could suggest some changes in my patch. > >>> > >>> Sorry it took me so long to answer ... > >>> > >>> The current fixed current_lsb of 1mA is indeed a bad choice for everything > >>> but a shunt resistor value of 10mOhm, as it truncates the current value. > >>> So what is a *good* choice? > >>> > >>> One important point is the current register is merely more than a > >>> convenience register. At least for the INA219/220, it provides nothing > >>> not achievable in software, and for the INA226 family it only has added > >>> value if the current is varying faster than the readout frequency and the > >>> averaging is used. > >>> > >>> The precision of the current register is limited by the precision of the > >>> shunt voltage register, and may be reduced by the applied > >>> scaling/calibration factor. > >>> > >>> The precision of the shunt voltage register is fixed at 10uV (INA219) > >>> resp. > >>> 2.5uV (INA226). Changing conversion time (both) and PGA (219) affects the > >>> noise and offset, but the lsb value is still fixed. > >>> > >>> If one wants to carry over the shunt voltage register precision into the > >>> current register, its important no (or hardly any) truncation happens. The > >>> terms therefor are given in the manual, formulas 8.5.1 (4) resp 7.5.1 (3): > >>> > >>> INA219: current = shunt_voltage * cal_register / 4096 > >>> INA226: current = shunt_voltage * cal_register / 2048 > >>> > >>> So any cal value smaller than 4096 (2048) will introduce truncation > >>> errors, > >>> larger values may introduce overflows, if the full input range is used. > >>> Now, would it not be wise to always use 4096 (2048) for the calibration > >>> value? > >>> > >>> The raw values from the IIO subsystem are meaningless without their > >>> accompanying scale factor. Instead of changing the calibration value, why > >>> not just change the reported scale factor? > >>> > >>> More opinions are very welcome. > >>> > >>> Kind regards, > >>> > >>> Stefan > >> > >> Thanks for the reply. > >> > >> I agree that cal_register set to 4096 (2048) allows us to eliminate > >> truncaction error. However according to your suggestion, if we made cal_reg > >> a fixed value, then current_lsb and r_shunt should be also a fixed value, > >> as they are related according to formula 8.5 (1) > >> > >> cal_register = 0.00512 / (current_lsb * r_shunt) > > > > A fixed cal_register only means the current_lsb is implied by the selected > > shunt resistor value. > > > > If you insert 2048 into the equation above, you get: > > > > current_lsb = 2.5 * 1e-6 * r_shunt, > > > > and using Ohms law to replace r_shunt, thats exactly the resolution of the > > shunt_voltage register as specified in the datasheet. The higher the shunt > > resistor value, the smaller the current_lsb. > > > >> Therefore, changing the scale value wouldn't affect the calib_reg value, so > >> it wouldn't give the user any information on the actual current_lsb of the > >> device. The real value is calculated like this by the user: > >> > >> processed_value = raw_value * scale > >> > >> I think that even after changing the scale value processed_value is expected > >> to be approximately the same. > > > > A fixed cal_register means you change the current_lsb by changing the shunt > > resistor. This exposes the full ADC resolution. > > > > The current_lsb *is* the scale value. > > > > Kind regards, > > > > Stefan > > > > Thanks for your explanation. I can do this the way you suggest, so the only > change with the original driver would be to make current_lsb (which is a scale > value) follow changes of shunt_resistance value from userspace. > > But before I'd like to ask Jonathan for opinion on that. This is what I was thinking as well. We basically ensure the scale is right for the shunt_resistance with the ADC operating at it's best possible accuracy and let userspace sort out the mess (as we provide it with the data to do so). > > Kind regards, > > Maciej > -- > To unsubscribe from this list: send the line "unsubscribe linux-iio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range [not found] <20171001194818.26017-1-stefan.bruens@rwth-aachen.de> 2017-10-01 19:48 ` [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register Stefan Brüns 2017-10-01 19:48 ` [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm Stefan Brüns @ 2017-10-01 19:48 ` Stefan Brüns 2017-10-08 10:07 ` Jonathan Cameron 2 siblings, 1 reply; 13+ messages in thread From: Stefan Brüns @ 2017-10-01 19:48 UTC (permalink / raw) To: linux-iio Cc: Peter Meerwald-Stadler, Stefan Brüns, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Jonathan Cameron, Hartmut Knaack Reducing shunt and bus voltage range improves the accuracy, so allow altering the default settings. Both settings are exposed as gain values. While for the shunt voltage this is straightforward, the bus range settings of 32V (default) and 16V are mapped to gain values of 1 resp. 2, to provide a uniform API to userspace. As the gain settings are incorporated into the raw values by the sensor itself, adjusting of the scale attributes is not necessary. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> --- drivers/iio/adc/ina2xx-adc.c | 111 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 1930f853e8c5..7e9ce43ad15d 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -48,8 +48,10 @@ #define INA2XX_MAX_REGISTERS 8 /* settings - depend on use case */ -#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ +#define INA219_CONFIG_DEFAULT 0x399F /* PGA=1/8, BRNG=32V */ #define INA219_DEFAULT_IT 532 +#define INA219_DEFAULT_BRNG 1 /* 32V */ +#define INA219_DEFAULT_PGA 125 /* 1000/8 */ #define INA226_CONFIG_DEFAULT 0x4327 #define INA226_DEFAULT_AVG 4 #define INA226_DEFAULT_IT 1110 @@ -62,6 +64,14 @@ */ #define INA2XX_MODE_MASK GENMASK(3, 0) +/* Gain for VShunt: 1/8 (default), 1/4, 1/2, 1 */ +#define INA219_PGA_MASK GENMASK(12, 11) +#define INA219_SHIFT_PGA(val) ((val) << 11) + +/* VBus range: 32V (default), 16V */ +#define INA219_BRNG_MASK BIT(13) +#define INA219_SHIFT_BRNG(val) ((val) << 13) + /* Averaging for VBus/VShunt/Power */ #define INA226_AVG_MASK GENMASK(11, 9) #define INA226_SHIFT_AVG(val) ((val) << 9) @@ -131,6 +141,8 @@ struct ina2xx_chip_info { int avg; int int_time_vbus; /* Bus voltage integration time uS */ int int_time_vshunt; /* Shunt voltage integration time uS */ + int range_vbus; /* Bus voltage maximum in V */ + int pga_gain_vshunt; /* Shunt voltage PGA gain */ bool allow_async_readout; }; @@ -227,6 +239,18 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, *val = 1; return IIO_VAL_INT; } + + case IIO_CHAN_INFO_HARDWAREGAIN: + switch (chan->address) { + case INA2XX_SHUNT_VOLTAGE: + *val = chip->pga_gain_vshunt; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + + case INA2XX_BUS_VOLTAGE: + *val = chip->range_vbus == 32 ? 1 : 2; + return IIO_VAL_INT; + } } return -EINVAL; @@ -361,6 +385,74 @@ static int ina219_set_int_time_vshunt(struct ina2xx_chip_info *chip, return 0; } +static const int ina219_vbus_range_tab[] = { 1, 2 }; +static int ina219_set_vbus_range_denom(struct ina2xx_chip_info *chip, + unsigned int range, + unsigned int *config) +{ + if (range == 1) + chip->range_vbus = 32; + else if (range == 2) + chip->range_vbus = 16; + else + return -EINVAL; + + *config &= ~INA219_BRNG_MASK; + *config |= INA219_SHIFT_BRNG(range == 1 ? 1 : 0) & INA219_BRNG_MASK; + + return 0; +} + +static const int ina219_vshunt_gain_tab[] = { 125, 250, 500, 1000 }; +static const int ina219_vshunt_gain_frac[] = { + 125, 1000, 250, 1000, 500, 1000, 1000, 1000 }; + +static int ina219_set_vshunt_pga_gain(struct ina2xx_chip_info *chip, + unsigned int gain, + unsigned int *config) +{ + int bits; + + if (gain < 125 || gain > 1000) + return -EINVAL; + + bits = find_closest(gain, ina219_vshunt_gain_tab, + ARRAY_SIZE(ina219_vshunt_gain_tab)); + + chip->pga_gain_vshunt = ina219_vshunt_gain_tab[bits]; + bits = 3 - bits; + + *config &= ~INA219_PGA_MASK; + *config |= INA219_SHIFT_PGA(bits) & INA219_PGA_MASK; + + return 0; +} + +static int ina2xx_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + switch (chan->address) { + case INA2XX_SHUNT_VOLTAGE: + *type = IIO_VAL_FRACTIONAL; + *length = sizeof(ina219_vshunt_gain_frac) / sizeof(int); + *vals = ina219_vshunt_gain_frac; + return IIO_AVAIL_LIST; + + case INA2XX_BUS_VOLTAGE: + *type = IIO_VAL_INT; + *length = sizeof(ina219_vbus_range_tab) / sizeof(int); + *vals = ina219_vbus_range_tab; + return IIO_AVAIL_LIST; + } + } + + return -EINVAL; +} + static int ina2xx_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) @@ -403,6 +495,14 @@ static int ina2xx_write_raw(struct iio_dev *indio_dev, } break; + case IIO_CHAN_INFO_HARDWAREGAIN: + if (chan->address == INA2XX_SHUNT_VOLTAGE) + ret = ina219_set_vshunt_pga_gain(chip, val * 1000000 + + val2, &tmp); + else + ret = ina219_set_vbus_range_denom(chip, val, &tmp); + break; + default: ret = -EINVAL; } @@ -547,7 +647,10 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, .channel = (_index), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_INT_TIME), \ + BIT(IIO_CHAN_INFO_INT_TIME) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (_index), \ .scan_type = { \ @@ -758,7 +861,6 @@ static IIO_CONST_ATTR_NAMED(ina226_integration_time_available, integration_time_available, "0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); - static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR, ina2xx_allow_async_readout_show, ina2xx_allow_async_readout_store, 0); @@ -793,6 +895,7 @@ static const struct iio_info ina219_info = { .driver_module = THIS_MODULE, .attrs = &ina219_attribute_group, .read_raw = ina2xx_read_raw, + .read_avail = ina2xx_read_avail, .write_raw = ina2xx_write_raw, .debugfs_reg_access = ina2xx_debug_reg, }; @@ -874,6 +977,8 @@ static int ina2xx_probe(struct i2c_client *client, chip->avg = 1; ina219_set_int_time_vbus(chip, INA219_DEFAULT_IT, &val); ina219_set_int_time_vshunt(chip, INA219_DEFAULT_IT, &val); + ina219_set_vbus_range_denom(chip, INA219_DEFAULT_BRNG, &val); + ina219_set_vshunt_pga_gain(chip, INA219_DEFAULT_PGA, &val); } ret = ina2xx_init(chip, val); -- 2.14.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range 2017-10-01 19:48 ` [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range Stefan Brüns @ 2017-10-08 10:07 ` Jonathan Cameron 2017-10-09 8:36 ` Maciej Purski 0 siblings, 1 reply; 13+ messages in thread From: Jonathan Cameron @ 2017-10-08 10:07 UTC (permalink / raw) To: Stefan Brüns Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Hartmut Knaack, Maciej Purski On Sun, 1 Oct 2017 21:48:18 +0200 Stefan Brüns <stefan.bruens@rwth-aachen.de> wrote: > Reducing shunt and bus voltage range improves the accuracy, so allow > altering the default settings. > > Both settings are exposed as gain values. While for the shunt voltage > this is straightforward, the bus range settings of 32V (default) and 16V > are mapped to gain values of 1 resp. 2, to provide a uniform API to > userspace. > > As the gain settings are incorporated into the raw values by the sensor > itself, adjusting of the scale attributes is not necessary. > > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> cc'd Maciej Purski who is working to improve the current calibration elements - I'd like you both to review each others patches if possible as the ABI is getting complex in here! I think what you have here won't interfere with Maciej's work, but would like you two to confirm that. Note that patch set probably needs a revision as I've suggested a rather different approach. Thanks, Jonathan > > --- > > drivers/iio/adc/ina2xx-adc.c | 111 +++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 108 insertions(+), 3 deletions(-) > > diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c > index 1930f853e8c5..7e9ce43ad15d 100644 > --- a/drivers/iio/adc/ina2xx-adc.c > +++ b/drivers/iio/adc/ina2xx-adc.c > @@ -48,8 +48,10 @@ > #define INA2XX_MAX_REGISTERS 8 > > /* settings - depend on use case */ > -#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ > +#define INA219_CONFIG_DEFAULT 0x399F /* PGA=1/8, BRNG=32V */ > #define INA219_DEFAULT_IT 532 > +#define INA219_DEFAULT_BRNG 1 /* 32V */ > +#define INA219_DEFAULT_PGA 125 /* 1000/8 */ > #define INA226_CONFIG_DEFAULT 0x4327 > #define INA226_DEFAULT_AVG 4 > #define INA226_DEFAULT_IT 1110 > @@ -62,6 +64,14 @@ > */ > #define INA2XX_MODE_MASK GENMASK(3, 0) > > +/* Gain for VShunt: 1/8 (default), 1/4, 1/2, 1 */ > +#define INA219_PGA_MASK GENMASK(12, 11) > +#define INA219_SHIFT_PGA(val) ((val) << 11) > + > +/* VBus range: 32V (default), 16V */ > +#define INA219_BRNG_MASK BIT(13) > +#define INA219_SHIFT_BRNG(val) ((val) << 13) > + > /* Averaging for VBus/VShunt/Power */ > #define INA226_AVG_MASK GENMASK(11, 9) > #define INA226_SHIFT_AVG(val) ((val) << 9) > @@ -131,6 +141,8 @@ struct ina2xx_chip_info { > int avg; > int int_time_vbus; /* Bus voltage integration time uS */ > int int_time_vshunt; /* Shunt voltage integration time uS */ > + int range_vbus; /* Bus voltage maximum in V */ > + int pga_gain_vshunt; /* Shunt voltage PGA gain */ > bool allow_async_readout; > }; > > @@ -227,6 +239,18 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, > *val = 1; > return IIO_VAL_INT; > } > + > + case IIO_CHAN_INFO_HARDWAREGAIN: > + switch (chan->address) { > + case INA2XX_SHUNT_VOLTAGE: > + *val = chip->pga_gain_vshunt; > + *val2 = 1000; > + return IIO_VAL_FRACTIONAL; > + > + case INA2XX_BUS_VOLTAGE: > + *val = chip->range_vbus == 32 ? 1 : 2; > + return IIO_VAL_INT; > + } > } > > return -EINVAL; > @@ -361,6 +385,74 @@ static int ina219_set_int_time_vshunt(struct ina2xx_chip_info *chip, > return 0; > } > > +static const int ina219_vbus_range_tab[] = { 1, 2 }; > +static int ina219_set_vbus_range_denom(struct ina2xx_chip_info *chip, > + unsigned int range, > + unsigned int *config) > +{ > + if (range == 1) > + chip->range_vbus = 32; > + else if (range == 2) > + chip->range_vbus = 16; > + else > + return -EINVAL; > + > + *config &= ~INA219_BRNG_MASK; > + *config |= INA219_SHIFT_BRNG(range == 1 ? 1 : 0) & INA219_BRNG_MASK; > + > + return 0; > +} > + > +static const int ina219_vshunt_gain_tab[] = { 125, 250, 500, 1000 }; > +static const int ina219_vshunt_gain_frac[] = { > + 125, 1000, 250, 1000, 500, 1000, 1000, 1000 }; > + > +static int ina219_set_vshunt_pga_gain(struct ina2xx_chip_info *chip, > + unsigned int gain, > + unsigned int *config) > +{ > + int bits; > + > + if (gain < 125 || gain > 1000) > + return -EINVAL; > + > + bits = find_closest(gain, ina219_vshunt_gain_tab, > + ARRAY_SIZE(ina219_vshunt_gain_tab)); > + > + chip->pga_gain_vshunt = ina219_vshunt_gain_tab[bits]; > + bits = 3 - bits; > + > + *config &= ~INA219_PGA_MASK; > + *config |= INA219_SHIFT_PGA(bits) & INA219_PGA_MASK; > + > + return 0; > +} > + > +static int ina2xx_read_avail(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + const int **vals, int *type, int *length, > + long mask) > +{ > + switch (mask) { > + case IIO_CHAN_INFO_HARDWAREGAIN: > + switch (chan->address) { > + case INA2XX_SHUNT_VOLTAGE: > + *type = IIO_VAL_FRACTIONAL; > + *length = sizeof(ina219_vshunt_gain_frac) / sizeof(int); > + *vals = ina219_vshunt_gain_frac; > + return IIO_AVAIL_LIST; > + > + case INA2XX_BUS_VOLTAGE: > + *type = IIO_VAL_INT; > + *length = sizeof(ina219_vbus_range_tab) / sizeof(int); > + *vals = ina219_vbus_range_tab; > + return IIO_AVAIL_LIST; > + } > + } > + > + return -EINVAL; > +} > + > static int ina2xx_write_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const *chan, > int val, int val2, long mask) > @@ -403,6 +495,14 @@ static int ina2xx_write_raw(struct iio_dev *indio_dev, > } > break; > > + case IIO_CHAN_INFO_HARDWAREGAIN: > + if (chan->address == INA2XX_SHUNT_VOLTAGE) > + ret = ina219_set_vshunt_pga_gain(chip, val * 1000000 + > + val2, &tmp); > + else > + ret = ina219_set_vbus_range_denom(chip, val, &tmp); > + break; > + > default: > ret = -EINVAL; > } > @@ -547,7 +647,10 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, > .channel = (_index), \ > .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ > BIT(IIO_CHAN_INFO_SCALE) | \ > - BIT(IIO_CHAN_INFO_INT_TIME), \ > + BIT(IIO_CHAN_INFO_INT_TIME) | \ > + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ > + .info_mask_separate_available = \ > + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ > .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ > .scan_index = (_index), \ > .scan_type = { \ > @@ -758,7 +861,6 @@ static IIO_CONST_ATTR_NAMED(ina226_integration_time_available, > integration_time_available, > "0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); > > - > static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR, > ina2xx_allow_async_readout_show, > ina2xx_allow_async_readout_store, 0); > @@ -793,6 +895,7 @@ static const struct iio_info ina219_info = { > .driver_module = THIS_MODULE, > .attrs = &ina219_attribute_group, > .read_raw = ina2xx_read_raw, > + .read_avail = ina2xx_read_avail, > .write_raw = ina2xx_write_raw, > .debugfs_reg_access = ina2xx_debug_reg, > }; > @@ -874,6 +977,8 @@ static int ina2xx_probe(struct i2c_client *client, > chip->avg = 1; > ina219_set_int_time_vbus(chip, INA219_DEFAULT_IT, &val); > ina219_set_int_time_vshunt(chip, INA219_DEFAULT_IT, &val); > + ina219_set_vbus_range_denom(chip, INA219_DEFAULT_BRNG, &val); > + ina219_set_vshunt_pga_gain(chip, INA219_DEFAULT_PGA, &val); > } > > ret = ina2xx_init(chip, val); ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range 2017-10-08 10:07 ` Jonathan Cameron @ 2017-10-09 8:36 ` Maciej Purski 0 siblings, 0 replies; 13+ messages in thread From: Maciej Purski @ 2017-10-09 8:36 UTC (permalink / raw) To: Jonathan Cameron, Stefan Brüns Cc: linux-iio, Peter Meerwald-Stadler, linux-kernel, Andrew F . Davis, Javier Martinez Canillas, Lars-Peter Clausen, Hartmut Knaack On 10/08/2017 12:07 PM, Jonathan Cameron wrote: > On Sun, 1 Oct 2017 21:48:18 +0200 > Stefan Brüns <stefan.bruens@rwth-aachen.de> wrote: > >> Reducing shunt and bus voltage range improves the accuracy, so allow >> altering the default settings. >> >> Both settings are exposed as gain values. While for the shunt voltage >> this is straightforward, the bus range settings of 32V (default) and 16V >> are mapped to gain values of 1 resp. 2, to provide a uniform API to >> userspace. >> >> As the gain settings are incorporated into the raw values by the sensor >> itself, adjusting of the scale attributes is not necessary. >> >> Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> > > cc'd Maciej Purski who is working to improve the current calibration > elements - I'd like you both to review each others patches if possible > as the ABI is getting complex in here! > > I think what you have here won't interfere with Maciej's work, but > would like you two to confirm that. Note that patch set probably > needs a revision as I've suggested a rather different approach. > > Thanks, > > Jonathan > Hi, it looks fine to me. The patches shouldn't interfere with each other. Regards, Maciej >> >> --- >> >> drivers/iio/adc/ina2xx-adc.c | 111 +++++++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 108 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c >> index 1930f853e8c5..7e9ce43ad15d 100644 >> --- a/drivers/iio/adc/ina2xx-adc.c >> +++ b/drivers/iio/adc/ina2xx-adc.c >> @@ -48,8 +48,10 @@ >> #define INA2XX_MAX_REGISTERS 8 >> >> /* settings - depend on use case */ >> -#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ >> +#define INA219_CONFIG_DEFAULT 0x399F /* PGA=1/8, BRNG=32V */ >> #define INA219_DEFAULT_IT 532 >> +#define INA219_DEFAULT_BRNG 1 /* 32V */ >> +#define INA219_DEFAULT_PGA 125 /* 1000/8 */ >> #define INA226_CONFIG_DEFAULT 0x4327 >> #define INA226_DEFAULT_AVG 4 >> #define INA226_DEFAULT_IT 1110 >> @@ -62,6 +64,14 @@ >> */ >> #define INA2XX_MODE_MASK GENMASK(3, 0) >> >> +/* Gain for VShunt: 1/8 (default), 1/4, 1/2, 1 */ >> +#define INA219_PGA_MASK GENMASK(12, 11) >> +#define INA219_SHIFT_PGA(val) ((val) << 11) >> + >> +/* VBus range: 32V (default), 16V */ >> +#define INA219_BRNG_MASK BIT(13) >> +#define INA219_SHIFT_BRNG(val) ((val) << 13) >> + >> /* Averaging for VBus/VShunt/Power */ >> #define INA226_AVG_MASK GENMASK(11, 9) >> #define INA226_SHIFT_AVG(val) ((val) << 9) >> @@ -131,6 +141,8 @@ struct ina2xx_chip_info { >> int avg; >> int int_time_vbus; /* Bus voltage integration time uS */ >> int int_time_vshunt; /* Shunt voltage integration time uS */ >> + int range_vbus; /* Bus voltage maximum in V */ >> + int pga_gain_vshunt; /* Shunt voltage PGA gain */ >> bool allow_async_readout; >> }; >> >> @@ -227,6 +239,18 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, >> *val = 1; >> return IIO_VAL_INT; >> } >> + >> + case IIO_CHAN_INFO_HARDWAREGAIN: >> + switch (chan->address) { >> + case INA2XX_SHUNT_VOLTAGE: >> + *val = chip->pga_gain_vshunt; >> + *val2 = 1000; >> + return IIO_VAL_FRACTIONAL; >> + >> + case INA2XX_BUS_VOLTAGE: >> + *val = chip->range_vbus == 32 ? 1 : 2; >> + return IIO_VAL_INT; >> + } >> } >> >> return -EINVAL; >> @@ -361,6 +385,74 @@ static int ina219_set_int_time_vshunt(struct ina2xx_chip_info *chip, >> return 0; >> } >> >> +static const int ina219_vbus_range_tab[] = { 1, 2 }; >> +static int ina219_set_vbus_range_denom(struct ina2xx_chip_info *chip, >> + unsigned int range, >> + unsigned int *config) >> +{ >> + if (range == 1) >> + chip->range_vbus = 32; >> + else if (range == 2) >> + chip->range_vbus = 16; >> + else >> + return -EINVAL; >> + >> + *config &= ~INA219_BRNG_MASK; >> + *config |= INA219_SHIFT_BRNG(range == 1 ? 1 : 0) & INA219_BRNG_MASK; >> + >> + return 0; >> +} >> + >> +static const int ina219_vshunt_gain_tab[] = { 125, 250, 500, 1000 }; >> +static const int ina219_vshunt_gain_frac[] = { >> + 125, 1000, 250, 1000, 500, 1000, 1000, 1000 }; >> + >> +static int ina219_set_vshunt_pga_gain(struct ina2xx_chip_info *chip, >> + unsigned int gain, >> + unsigned int *config) >> +{ >> + int bits; >> + >> + if (gain < 125 || gain > 1000) >> + return -EINVAL; >> + >> + bits = find_closest(gain, ina219_vshunt_gain_tab, >> + ARRAY_SIZE(ina219_vshunt_gain_tab)); >> + >> + chip->pga_gain_vshunt = ina219_vshunt_gain_tab[bits]; >> + bits = 3 - bits; >> + >> + *config &= ~INA219_PGA_MASK; >> + *config |= INA219_SHIFT_PGA(bits) & INA219_PGA_MASK; >> + >> + return 0; >> +} >> + >> +static int ina2xx_read_avail(struct iio_dev *indio_dev, >> + struct iio_chan_spec const *chan, >> + const int **vals, int *type, int *length, >> + long mask) >> +{ >> + switch (mask) { >> + case IIO_CHAN_INFO_HARDWAREGAIN: >> + switch (chan->address) { >> + case INA2XX_SHUNT_VOLTAGE: >> + *type = IIO_VAL_FRACTIONAL; >> + *length = sizeof(ina219_vshunt_gain_frac) / sizeof(int); >> + *vals = ina219_vshunt_gain_frac; >> + return IIO_AVAIL_LIST; >> + >> + case INA2XX_BUS_VOLTAGE: >> + *type = IIO_VAL_INT; >> + *length = sizeof(ina219_vbus_range_tab) / sizeof(int); >> + *vals = ina219_vbus_range_tab; >> + return IIO_AVAIL_LIST; >> + } >> + } >> + >> + return -EINVAL; >> +} >> + >> static int ina2xx_write_raw(struct iio_dev *indio_dev, >> struct iio_chan_spec const *chan, >> int val, int val2, long mask) >> @@ -403,6 +495,14 @@ static int ina2xx_write_raw(struct iio_dev *indio_dev, >> } >> break; >> >> + case IIO_CHAN_INFO_HARDWAREGAIN: >> + if (chan->address == INA2XX_SHUNT_VOLTAGE) >> + ret = ina219_set_vshunt_pga_gain(chip, val * 1000000 + >> + val2, &tmp); >> + else >> + ret = ina219_set_vbus_range_denom(chip, val, &tmp); >> + break; >> + >> default: >> ret = -EINVAL; >> } >> @@ -547,7 +647,10 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, >> .channel = (_index), \ >> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ >> BIT(IIO_CHAN_INFO_SCALE) | \ >> - BIT(IIO_CHAN_INFO_INT_TIME), \ >> + BIT(IIO_CHAN_INFO_INT_TIME) | \ >> + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ >> + .info_mask_separate_available = \ >> + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ >> .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ >> .scan_index = (_index), \ >> .scan_type = { \ >> @@ -758,7 +861,6 @@ static IIO_CONST_ATTR_NAMED(ina226_integration_time_available, >> integration_time_available, >> "0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); >> >> - >> static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR, >> ina2xx_allow_async_readout_show, >> ina2xx_allow_async_readout_store, 0); >> @@ -793,6 +895,7 @@ static const struct iio_info ina219_info = { >> .driver_module = THIS_MODULE, >> .attrs = &ina219_attribute_group, >> .read_raw = ina2xx_read_raw, >> + .read_avail = ina2xx_read_avail, >> .write_raw = ina2xx_write_raw, >> .debugfs_reg_access = ina2xx_debug_reg, >> }; >> @@ -874,6 +977,8 @@ static int ina2xx_probe(struct i2c_client *client, >> chip->avg = 1; >> ina219_set_int_time_vbus(chip, INA219_DEFAULT_IT, &val); >> ina219_set_int_time_vshunt(chip, INA219_DEFAULT_IT, &val); >> + ina219_set_vbus_range_denom(chip, INA219_DEFAULT_BRNG, &val); >> + ina219_set_vshunt_pga_gain(chip, INA219_DEFAULT_PGA, &val); >> } >> >> ret = ina2xx_init(chip, val); > > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2017-11-19 16:57 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20171001194818.26017-1-stefan.bruens@rwth-aachen.de>
2017-10-01 19:48 ` [PATCH 1/3] iio: adc: ina2xx: Mask flag bits in bus voltage register Stefan Brüns
2017-10-08 9:57 ` Jonathan Cameron
2017-10-01 19:48 ` [PATCH 2/3] iio: adc: ina2xx: Adhere to documented ABI, use Ohm instead of uOhm Stefan Brüns
2017-10-08 10:03 ` Jonathan Cameron
[not found] ` <CGME20171009092944eucas1p18b2e66a4a07db309551a7e945c2611ec@eucas1p1.samsung.com>
2017-10-09 9:29 ` [2/3] " Maciej Purski
2017-10-14 18:27 ` Stefan Bruens
2017-11-02 9:04 ` Maciej Purski
2017-11-06 10:21 ` Stefan Brüns
2017-11-08 13:22 ` Maciej Purski
2017-11-19 16:57 ` Jonathan Cameron
2017-10-01 19:48 ` [PATCH 3/3] iio: adc: ina2xx: Allow setting Shunt Voltage PGA gain and Bus Voltage range Stefan Brüns
2017-10-08 10:07 ` Jonathan Cameron
2017-10-09 8:36 ` Maciej Purski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).