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>
This commit is contained in:
parent
c4f0c69367
commit
6807d72113
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue