[PATCH 3/3] iio: ina2xx: add support for CHAN_INFO_SCALE

From: Marc Titinger
Date: Fri Dec 11 2015 - 11:49:38 EST


Provide client apps with the scales to apply to the register values
read from the software buffer.

Follow the ABI documentation so that values are in milli-unit after scales
are applied.

Signed-off-by: Marc Titinger <mtitinger@xxxxxxxxxxxx>
---
drivers/iio/adc/ina2xx-adc.c | 85 +++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 99afa6e..98939ba 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -82,6 +82,11 @@ static bool ina2xx_is_volatile_reg(struct device *dev, unsigned int reg)
return (reg != INA2XX_CONFIG);
}

+static inline bool is_signed_reg(unsigned int reg)
+{
+ return (reg == INA2XX_SHUNT_VOLTAGE) || (reg == INA2XX_CURRENT);
+}
+
static const struct regmap_config ina2xx_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
@@ -133,43 +138,6 @@ static const struct ina2xx_config ina2xx_config[] = {
},
};

-static int ina2xx_get_value(struct ina2xx_chip_info *chip, u8 reg,
- unsigned int regval, int *val, int *uval)
-{
- *val = 0;
-
- switch (reg) {
- case INA2XX_SHUNT_VOLTAGE:
- /* signed register */
- *uval = DIV_ROUND_CLOSEST((s16) regval,
- chip->config->shunt_div);
- return IIO_VAL_INT_PLUS_MICRO;
-
- case INA2XX_BUS_VOLTAGE:
- *uval = (regval >> chip->config->bus_voltage_shift)
- * chip->config->bus_voltage_lsb;
- *val = *uval / 1000000;
- *uval = *uval % 1000000;
- return IIO_VAL_INT_PLUS_MICRO;
-
- case INA2XX_POWER:
- *uval = regval * chip->config->power_lsb;
- *val = *uval / 1000000;
- *uval = *uval % 1000000;
- return IIO_VAL_INT_PLUS_MICRO;
-
- case INA2XX_CURRENT:
- /* signed register, LSB=1mA (selected), in mA */
- *uval = (s16) regval * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
-
- default:
- /* programmer goofed */
- WARN_ON_ONCE(1);
- }
- return -EINVAL;
-}
-
static int ina2xx_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -184,7 +152,12 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;

- return ina2xx_get_value(chip, chan->address, regval, val, val2);
+ if (is_signed_reg(chan->address))
+ *val = (s16) regval;
+ else
+ *val = regval;
+
+ return IIO_VAL_INT;

case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*val = chip->avg;
@@ -208,11 +181,34 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev,

return IIO_VAL_INT;

- default:
- return -EINVAL;
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->address) {
+ case INA2XX_SHUNT_VOLTAGE:
+ /* processed (mV) = raw*1000/shunt_div */
+ *val2 = chip->config->shunt_div;
+ *val = 1000;
+ return IIO_VAL_FRACTIONAL;
+
+ case INA2XX_BUS_VOLTAGE:
+ /* processed (mV) = raw*lsb (uV) / (1000 << shift) */
+ *val = chip->config->bus_voltage_lsb;
+ *val2 = 1000 << chip->config->bus_voltage_shift;
+ return IIO_VAL_FRACTIONAL;
+
+ case INA2XX_POWER:
+ /* processed (mW) = raw*lsb (uW) / 1000 */
+ *val = chip->config->power_lsb;
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
+
+ case INA2XX_CURRENT:
+ /* processed (mA) = raw (mA) */
+ *val = 1;
+ return IIO_VAL_INT;
+ }
}

- return 0;
+ return -EINVAL;
}

/*
@@ -395,7 +391,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.address = (_address), \
.indexed = 1, \
.channel = (_index), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)|BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.scan_index = (_index), \
@@ -403,7 +399,7 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.sign = 'u', \
.realbits = 16, \
.storagebits = 16, \
- .endianness = IIO_BE, \
+ .endianness = IIO_LE, \
} \
}

@@ -417,13 +413,14 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.indexed = 1, \
.channel = (_index), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_INT_TIME), \
.scan_index = (_index), \
.scan_type = { \
.sign = 'u', \
.realbits = 16, \
.storagebits = 16, \
- .endianness = IIO_BE, \
+ .endianness = IIO_LE, \
} \
}

--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/