Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c04af04 authored by Michael Hennerich's avatar Michael Hennerich Committed by Greg Kroah-Hartman
Browse files

iio: industrialio-core: iio_write_channel_info accept IIO_VAL_INT_PLUS_NANO



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: default avatarMichael Hennerich <michael.hennerich@analog.com>
Acked-by: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 43a4360e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);

+21 −6
Original line number Diff line number Diff line
@@ -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;