aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/industrialio-core.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-11-20 08:36:00 -0500
committerJonathan Cameron <jic23@kernel.org>2012-11-20 16:26:39 -0500
commit6807d7211327dbdd8df3692f3d26ca711514ba71 (patch)
tree3654bb4d0d6b2d9afd6534b3907f924c3d5e069d /drivers/iio/industrialio-core.c
parentc4f0c6936762ecd6b453275611a785dfdee0d417 (diff)
iio: Factor out fixed point number parsing into its own function
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>
Diffstat (limited to 'drivers/iio/industrialio-core.c')
-rw-r--r--drivers/iio/industrialio-core.c98
1 files changed, 63 insertions, 35 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 3dccd6c3a889..8848f16c547b 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -408,6 +408,64 @@ static ssize_t iio_read_channel_info(struct device *dev,
408 } 408 }
409} 409}
410 410
411/**
412 * iio_str_to_fixpoint() - Parse a fixed-point number from a string
413 * @str: The string to parse
414 * @fract_mult: Multiplier for the first decimal place, should be a power of 10
415 * @integer: The integer part of the number
416 * @fract: The fractional part of the number
417 *
418 * Returns 0 on success, or a negative error code if the string could not be
419 * parsed.
420 */
421int iio_str_to_fixpoint(const char *str, int fract_mult,
422 int *integer, int *fract)
423{
424 int i = 0, f = 0;
425 bool integer_part = true, negative = false;
426
427 if (str[0] == '-') {
428 negative = true;
429 str++;
430 } else if (str[0] == '+') {
431 str++;
432 }
433
434 while (*str) {
435 if ('0' <= *str && *str <= '9') {
436 if (integer_part) {
437 i = i * 10 + *str - '0';
438 } else {
439 f += fract_mult * (*str - '0');
440 fract_mult /= 10;
441 }
442 } else if (*str == '\n') {
443 if (*(str + 1) == '\0')
444 break;
445 else
446 return -EINVAL;
447 } else if (*str == '.' && integer_part) {
448 integer_part = false;
449 } else {
450 return -EINVAL;
451 }
452 str++;
453 }
454
455 if (negative) {
456 if (i)
457 i = -i;
458 else
459 f = -f;
460 }
461
462 *integer = i;
463 *fract = f;
464
465 return 0;
466}
467EXPORT_SYMBOL_GPL(iio_str_to_fixpoint);
468
411static ssize_t iio_write_channel_info(struct device *dev, 469static ssize_t iio_write_channel_info(struct device *dev,
412 struct device_attribute *attr, 470 struct device_attribute *attr,
413 const char *buf, 471 const char *buf,
@@ -415,8 +473,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
415{ 473{
416 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 474 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
417 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 475 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
418 int ret, integer = 0, fract = 0, fract_mult = 100000; 476 int ret, fract_mult = 100000;
419 bool integer_part = true, negative = false; 477 int integer, fract;
420 478
421 /* Assumes decimal - precision based on number of digits */ 479 /* Assumes decimal - precision based on number of digits */
422 if (!indio_dev->info->write_raw) 480 if (!indio_dev->info->write_raw)
@@ -435,39 +493,9 @@ static ssize_t iio_write_channel_info(struct device *dev,
435 return -EINVAL; 493 return -EINVAL;
436 } 494 }
437 495
438 if (buf[0] == '-') { 496 ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
439 negative = true; 497 if (ret)
440 buf++; 498 return ret;
441 } else if (buf[0] == '+') {
442 buf++;
443 }
444
445 while (*buf) {
446 if ('0' <= *buf && *buf <= '9') {
447 if (integer_part)
448 integer = integer*10 + *buf - '0';
449 else {
450 fract += fract_mult*(*buf - '0');
451 fract_mult /= 10;
452 }
453 } else if (*buf == '\n') {
454 if (*(buf + 1) == '\0')
455 break;
456 else
457 return -EINVAL;
458 } else if (*buf == '.' && integer_part) {
459 integer_part = false;
460 } else {
461 return -EINVAL;
462 }
463 buf++;
464 }
465 if (negative) {
466 if (integer)
467 integer = -integer;
468 else
469 fract = -fract;
470 }
471 499
472 ret = indio_dev->info->write_raw(indio_dev, this_attr->c, 500 ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
473 integer, fract, this_attr->address); 501 integer, fract, this_attr->address);