staging:iio:ad7192: Report offset and scale for temperature channel
authorLars-Peter Clausen <lars@metafoo.de>
Fri, 10 Aug 2012 16:36:00 +0000 (17:36 +0100)
committerJonathan Cameron <jic23@kernel.org>
Thu, 16 Aug 2012 19:24:37 +0000 (20:24 +0100)
The temperature channel reports values in degree Kelvin with sensitivity of 5630
codes per degree. If the chip is configured in bipolar mode there is an
additional binary offset of 0x800000 and the sensitivity is divided by two.

Currently the driver does the mapping from the raw value to degree Celsius when
doing a manual conversion. This has several disadvantages, the major one being
that it does not work for buffered mode, also by doing the division by the
sensitivity in the driver the precession of the reported value is needlessly
reduced.

Furthermore the current calculation only works in bipolar mode and the current
scale is of by a factor of 1000.

This patch modifies the driver to report correct offset and scale values in
both unipolar and bipolar mode and to report the raw temperature value
for manual conversions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/staging/iio/adc/ad7192.c

index 73483d26a034808f7fdd5f752c58e6d9de99bfb4..095837285f4fb25732b8986f3d6d25458a9a11a2 100644 (file)
@@ -798,6 +798,11 @@ static const struct attribute_group ad7195_attribute_group = {
        .attrs = ad7195_attributes,
 };
 
+static unsigned int ad7192_get_temp_scale(bool unipolar)
+{
+       return unipolar ? 2815 * 2 : 2815;
+}
+
 static int ad7192_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan,
                           int *val,
@@ -824,17 +829,6 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
                *val = (smpl >> chan->scan_type.shift) &
                        ((1 << (chan->scan_type.realbits)) - 1);
 
-               switch (chan->type) {
-               case IIO_VOLTAGE:
-                       break;
-               case IIO_TEMP:
-                       *val -= 0x800000;
-                       *val /= 2815; /* temp Kelvin */
-                       *val -= 273; /* temp Celsius */
-                       break;
-               default:
-                       return -EINVAL;
-               }
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
@@ -846,16 +840,20 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
                        mutex_unlock(&indio_dev->mlock);
                        return IIO_VAL_INT_PLUS_NANO;
                case IIO_TEMP:
-                       *val =  1000;
-                       return IIO_VAL_INT;
+                       *val = 0;
+                       *val2 = 1000000000 / ad7192_get_temp_scale(unipolar);
+                       return IIO_VAL_INT_PLUS_NANO;
                default:
                        return -EINVAL;
                }
        case IIO_CHAN_INFO_OFFSET:
                if (!unipolar)
-                       *val -= (1 << (chan->scan_type.realbits - 1));
+                       *val = -(1 << (chan->scan_type.realbits - 1));
                else
                        *val = 0;
+               /* Kelvin to Celsius */
+               if (chan->type == IIO_TEMP)
+                       *val -= 273 * ad7192_get_temp_scale(unipolar);
                return IIO_VAL_INT;
        }