aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/industrialio-core.c98
-rw-r--r--include/linux/iio/iio.h3
2 files changed, 66 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);
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index adca93a999a7..da8c776ba0bd 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -620,6 +620,9 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
620}; 620};
621#endif 621#endif
622 622
623int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
624 int *fract);
625
623/** 626/**
624 * IIO_DEGREE_TO_RAD() - Convert degree to rad 627 * IIO_DEGREE_TO_RAD() - Convert degree to rad
625 * @deg: A value in degree 628 * @deg: A value in degree