iio: Factor out fixed point number parsing into its own function
authorLars-Peter Clausen <lars@metafoo.de>
Tue, 20 Nov 2012 13:36:00 +0000 (13:36 +0000)
committerJonathan Cameron <jic23@kernel.org>
Tue, 20 Nov 2012 21:26:39 +0000 (21:26 +0000)
Factor out the code for parsing fixed point numbers into its own function and
make this function globally available. This allows us to reuse the code to parse
fixed point numbers in individual IIO drivers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/industrialio-core.c
include/linux/iio/iio.h

index 3dccd6c..8848f16 100644 (file)
@@ -408,6 +408,64 @@ static ssize_t iio_read_channel_info(struct device *dev,
        }
 }
 
+/**
+ * iio_str_to_fixpoint() - Parse a fixed-point number from a string
+ * @str: The string to parse
+ * @fract_mult: Multiplier for the first decimal place, should be a power of 10
+ * @integer: The integer part of the number
+ * @fract: The fractional part of the number
+ *
+ * Returns 0 on success, or a negative error code if the string could not be
+ * parsed.
+ */
+int iio_str_to_fixpoint(const char *str, int fract_mult,
+       int *integer, int *fract)
+{
+       int i = 0, f = 0;
+       bool integer_part = true, negative = false;
+
+       if (str[0] == '-') {
+               negative = true;
+               str++;
+       } else if (str[0] == '+') {
+               str++;
+       }
+
+       while (*str) {
+               if ('0' <= *str && *str <= '9') {
+                       if (integer_part) {
+                               i = i * 10 + *str - '0';
+                       } else {
+                               f += fract_mult * (*str - '0');
+                               fract_mult /= 10;
+                       }
+               } else if (*str == '\n') {
+                       if (*(str + 1) == '\0')
+                               break;
+                       else
+                               return -EINVAL;
+               } else if (*str == '.' && integer_part) {
+                       integer_part = false;
+               } else {
+                       return -EINVAL;
+               }
+               str++;
+       }
+
+       if (negative) {
+               if (i)
+                       i = -i;
+               else
+                       f = -f;
+       }
+
+       *integer = i;
+       *fract = f;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(iio_str_to_fixpoint);
+
 static ssize_t iio_write_channel_info(struct device *dev,
                                      struct device_attribute *attr,
                                      const char *buf,
@@ -415,8 +473,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       int ret, integer = 0, fract = 0, fract_mult = 100000;
-       bool integer_part = true, negative = false;
+       int ret, fract_mult = 100000;
+       int integer, fract;
 
        /* Assumes decimal - precision based on number of digits */
        if (!indio_dev->info->write_raw)
@@ -435,39 +493,9 @@ static ssize_t iio_write_channel_info(struct device *dev,
                        return -EINVAL;
                }
 
-       if (buf[0] == '-') {
-               negative = true;
-               buf++;
-       } else if (buf[0] == '+') {
-               buf++;
-       }
-
-       while (*buf) {
-               if ('0' <= *buf && *buf <= '9') {
-                       if (integer_part)
-                               integer = integer*10 + *buf - '0';
-                       else {
-                               fract += fract_mult*(*buf - '0');
-                               fract_mult /= 10;
-                       }
-               } else if (*buf == '\n') {
-                       if (*(buf + 1) == '\0')
-                               break;
-                       else
-                               return -EINVAL;
-               } else if (*buf == '.' && integer_part) {
-                       integer_part = false;
-               } else {
-                       return -EINVAL;
-               }
-               buf++;
-       }
-       if (negative) {
-               if (integer)
-                       integer = -integer;
-               else
-                       fract = -fract;
-       }
+       ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+       if (ret)
+               return ret;
 
        ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
                                         integer, fract, this_attr->address);
index adca93a..da8c776 100644 (file)
@@ -620,6 +620,9 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
 };
 #endif
 
+int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
+       int *fract);
+
 /**
  * IIO_DEGREE_TO_RAD() - Convert degree to rad
  * @deg: A value in degree