Commit 01a10e04 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

staging:iio:ad7298: Fix temperature scale and offset

The temperature scale and offset depend on the reference voltage, the current
formula used in the driver assumes a 2.5V reference. This patch modifies the
code to report the unprocessed value for the temperature channel "raw" property
and to provide proper "scale" and "offset" properties which depend on the
selected reference voltage.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 2e334600
...@@ -45,7 +45,8 @@ static const struct iio_chan_spec ad7298_channels[] = { ...@@ -45,7 +45,8 @@ static const struct iio_chan_spec ad7298_channels[] = {
.indexed = 1, .indexed = 1,
.channel = 0, .channel = 0,
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
IIO_CHAN_INFO_SCALE_SEPARATE_BIT, IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
.address = AD7298_CH_TEMP, .address = AD7298_CH_TEMP,
.scan_index = -1, .scan_index = -1,
.scan_type = { .scan_type = {
...@@ -80,7 +81,7 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) ...@@ -80,7 +81,7 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
static int ad7298_scan_temp(struct ad7298_state *st, int *val) static int ad7298_scan_temp(struct ad7298_state *st, int *val)
{ {
int tmp, ret; int ret;
__be16 buf; __be16 buf;
buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
...@@ -102,24 +103,24 @@ static int ad7298_scan_temp(struct ad7298_state *st, int *val) ...@@ -102,24 +103,24 @@ static int ad7298_scan_temp(struct ad7298_state *st, int *val)
if (ret) if (ret)
return ret; return ret;
tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS); *val = sign_extend32(be16_to_cpu(buf), 11);
/* return 0;
* One LSB of the ADC corresponds to 0.25 deg C. }
* The temperature reading is in 12-bit twos complement format
*/ static int ad7298_get_ref_voltage(struct ad7298_state *st)
{
int vref;
if (tmp & (1 << (AD7298_BITS - 1))) { if (st->ext_ref) {
tmp = (4096 - tmp) * 250; vref = regulator_get_voltage(st->reg);
tmp -= (2 * tmp); if (vref < 0)
return vref;
return vref / 1000;
} else { } else {
tmp *= 250; /* temperature in milli degrees Celsius */ return AD7298_INTREF_mV;
} }
*val = tmp;
return 0;
} }
static int ad7298_read_raw(struct iio_dev *indio_dev, static int ad7298_read_raw(struct iio_dev *indio_dev,
...@@ -130,7 +131,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, ...@@ -130,7 +131,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
{ {
int ret; int ret;
struct ad7298_state *st = iio_priv(indio_dev); struct ad7298_state *st = iio_priv(indio_dev);
int scale_mv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -155,24 +155,19 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, ...@@ -155,24 +155,19 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
switch (chan->type) { switch (chan->type) {
case IIO_VOLTAGE: case IIO_VOLTAGE:
if (st->ext_ref) { *val = ad7298_get_ref_voltage(st);
scale_mv = regulator_get_voltage(st->reg);
if (scale_mv < 0)
return scale_mv;
scale_mv /= 1000;
} else {
scale_mv = AD7298_INTREF_mV;
}
*val = scale_mv;
*val2 = chan->scan_type.realbits; *val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2; return IIO_VAL_FRACTIONAL_LOG2;
case IIO_TEMP: case IIO_TEMP:
*val = 1; *val = ad7298_get_ref_voltage(st);
*val2 = 0; *val2 = 10;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL;
default: default:
return -EINVAL; return -EINVAL;
} }
case IIO_CHAN_INFO_OFFSET:
*val = 1093 - 2732500 / ad7298_get_ref_voltage(st);
return IIO_VAL_INT;
} }
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment