diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2014-04-29 00:51:00 +0100 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2014-04-29 22:05:32 +0100 |
commit | 9fbfb4b37ed23f71aa9484484266381c6c6964cb (patch) | |
tree | 441b1f942d51a1729d10a3237c7a28853f482ff9 /drivers/iio/industrialio-core.c | |
parent | 3046365bb470f0ec2f7cf5cb07a8ee7e4b490103 (diff) | |
download | linux-9fbfb4b37ed23f71aa9484484266381c6c6964cb.tar.bz2 |
IIO: core: Introduce read_raw_multi
This callback is introduced to overcome some limitations of existing
read_raw callback. The functionality of both existing read_raw and
read_raw_multi is similar, both are used to request values from the
device. The current read_raw callback allows only two return values.
The new read_raw_multi allows returning multiple values. Instead of
passing just address of val and val2, it passes length and pointer
to values. Depending on the type and length of passed buffer, iio
client drivers can return multiple values.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/industrialio-core.c')
-rw-r--r-- | drivers/iio/industrialio-core.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 184444db62ac..59540859bfae 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -373,41 +373,53 @@ EXPORT_SYMBOL_GPL(iio_enum_write); * @buf: The buffer to which the formated value gets written * @type: One of the IIO_VAL_... constants. This decides how the val and val2 * parameters are formatted. - * @val: First part of the value, exact meaning depends on the type parameter. - * @val2: Second part of the value, exact meaning depends on the type parameter. + * @vals: pointer to the values, exact meaning depends on the type parameter. */ -ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2) +ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals) { unsigned long long tmp; bool scale_db = false; switch (type) { case IIO_VAL_INT: - return sprintf(buf, "%d\n", val); + return sprintf(buf, "%d\n", vals[0]); case IIO_VAL_INT_PLUS_MICRO_DB: scale_db = true; case IIO_VAL_INT_PLUS_MICRO: - if (val2 < 0) - return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2, + if (vals[1] < 0) + return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]), + -vals[1], scale_db ? " dB" : ""); else - return sprintf(buf, "%d.%06u%s\n", val, val2, + return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1], scale_db ? " dB" : ""); case IIO_VAL_INT_PLUS_NANO: - if (val2 < 0) - return sprintf(buf, "-%ld.%09u\n", abs(val), -val2); + if (vals[1] < 0) + return sprintf(buf, "-%ld.%09u\n", abs(vals[0]), + -vals[1]); else - return sprintf(buf, "%d.%09u\n", val, val2); + return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); case IIO_VAL_FRACTIONAL: - tmp = div_s64((s64)val * 1000000000LL, val2); - val2 = do_div(tmp, 1000000000LL); - val = tmp; - return sprintf(buf, "%d.%09u\n", val, val2); + tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); + vals[1] = do_div(tmp, 1000000000LL); + vals[0] = tmp; + return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); case IIO_VAL_FRACTIONAL_LOG2: - tmp = (s64)val * 1000000000LL >> val2; - val2 = do_div(tmp, 1000000000LL); - val = tmp; - return sprintf(buf, "%d.%09u\n", val, val2); + tmp = (s64)vals[0] * 1000000000LL >> vals[1]; + vals[1] = do_div(tmp, 1000000000LL); + vals[0] = tmp; + return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); + case IIO_VAL_INT_MULTIPLE: + { + int i; + int len = 0; + + for (i = 0; i < size; ++i) + len += snprintf(&buf[len], PAGE_SIZE - len, "%d ", + vals[i]); + len += snprintf(&buf[len], PAGE_SIZE - len, "\n"); + return len; + } default: return 0; } @@ -419,14 +431,23 @@ static ssize_t iio_read_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 val, val2; - int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, - &val, &val2, this_attr->address); + int vals[INDIO_MAX_RAW_ELEMENTS]; + int ret; + int val_len = 2; + + if (indio_dev->info->read_raw_multi) + ret = indio_dev->info->read_raw_multi(indio_dev, this_attr->c, + INDIO_MAX_RAW_ELEMENTS, + vals, &val_len, + this_attr->address); + else + ret = indio_dev->info->read_raw(indio_dev, this_attr->c, + &vals[0], &vals[1], this_attr->address); if (ret < 0) return ret; - return iio_format_value(buf, ret, val, val2); + return iio_format_value(buf, ret, val_len, vals); } /** |