iio: industrialio-core: iio_write_channel_info accept IIO_VAL_INT_PLUS_NANO
authorMichael Hennerich <michael.hennerich@analog.com>
Mon, 27 Jun 2011 12:07:10 +0000 (13:07 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 28 Jun 2011 21:39:34 +0000 (14:39 -0700)
Allow iio_write_channel_info() to accept IIO_VAL_INT_PLUS_NANO

Changes since V1:
use callback to query expected format/precision

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/iio/iio.h
drivers/staging/iio/industrialio-core.c

index 6e51baaaa7544762bb409c71c58b0dfce150d216..9ca89c7d56930522b871d2b34bd00dc12013f7aa 100644 (file)
@@ -220,6 +220,9 @@ struct iio_trigger; /* forward declaration */
  *                     contain the elements making up the returned value.
  * @write_raw:         function to write a value to the device.
  *                     Parameters are the same as for read_raw.
+ * @write_raw_get_fmt: callback function to query the expected
+ *                     format/precision. If not set by the driver, write_raw
+ *                     returns IIO_VAL_INT_PLUS_MICRO.
  * @read_event_config: find out if the event is enabled.
  * @write_event_config:        set if the event is enabled.
  * @read_event_value:  read a value associated with the event. Meaning
@@ -247,6 +250,10 @@ struct iio_info {
                         int val2,
                         long mask);
 
+       int (*write_raw_get_fmt)(struct iio_dev *indio_dev,
+                        struct iio_chan_spec const *chan,
+                        long mask);
+
        int (*read_event_config)(struct iio_dev *indio_dev,
                                 int event_code);
 
index e5a7663613a7a66460a62470d694f5abc728780a..744153ee2edbe7d8c3852254ff5fb9446355bdd1 100644 (file)
@@ -412,25 +412,40 @@ static ssize_t iio_write_channel_info(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       int ret, integer = 0, micro = 0, micro_mult = 100000;
+       int ret, integer = 0, fract = 0, fract_mult = 100000;
        bool integer_part = true, negative = false;
 
        /* Assumes decimal - precision based on number of digits */
        if (!indio_dev->info->write_raw)
                return -EINVAL;
+
+       if (indio_dev->info->write_raw_get_fmt)
+               switch (indio_dev->info->write_raw_get_fmt(indio_dev,
+                       this_attr->c, this_attr->address)) {
+               case IIO_VAL_INT_PLUS_MICRO:
+                       fract_mult = 100000;
+                       break;
+               case IIO_VAL_INT_PLUS_NANO:
+                       fract_mult = 100000000;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
        if (buf[0] == '-') {
                negative = true;
                buf++;
        }
+
        while (*buf) {
                if ('0' <= *buf && *buf <= '9') {
                        if (integer_part)
                                integer = integer*10 + *buf - '0';
                        else {
-                               micro += micro_mult*(*buf - '0');
-                               if (micro_mult == 1)
+                               fract += fract_mult*(*buf - '0');
+                               if (fract_mult == 1)
                                        break;
-                               micro_mult /= 10;
+                               fract_mult /= 10;
                        }
                } else if (*buf == '\n') {
                        if (*(buf + 1) == '\0')
@@ -448,11 +463,11 @@ static ssize_t iio_write_channel_info(struct device *dev,
                if (integer)
                        integer = -integer;
                else
-                       micro = -micro;
+                       fract = -fract;
        }
 
        ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
-                                        integer, micro, this_attr->address);
+                                        integer, fract, this_attr->address);
        if (ret)
                return ret;