linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency
@ 2012-09-14 15:21 Lars-Peter Clausen
  2012-09-14 15:21 ` [PATCH 2/4] iio: Introduce a new fractional value type Lars-Peter Clausen
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2012-09-14 15:21 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Milo Kim, anish kumar, Lars-Peter Clausen

For the iio_read_channel_raw and iio_read_channel_scale the kerneldoc comment
refers to an argument called "channel", while the argument is called "chan" in
the function signature. This leads to the following warnings from kerneldoc:

	Warning(include/linux/iio/consumer.h:71): No description found for parameter 'chan'
	Warning(include/linux/iio/consumer.h:71): Excess function parameter 'channel' description in 'iio_read_channel_raw'
	Warning(include/linux/iio/consumer.h:109): No description found for parameter 'chan'
	Warning(include/linux/iio/consumer.h:109): Excess function parameter 'channel' description in 'iio_read_channel_scale'

This patch fixes the warnings by naming them consistently.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/linux/iio/consumer.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 06ab4ec..27759ac3 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -67,7 +67,7 @@ void iio_channel_release_all(struct iio_channel *chan);
  * Note raw reads from iio channels are in adc counts and hence
  * scale will need to be applied if standard units required.
  */
-int iio_read_channel_raw(struct iio_channel *chan,
+int iio_read_channel_raw(struct iio_channel *channel,
 			 int *val);
 
 /**
@@ -90,7 +90,7 @@ int iio_get_channel_type(struct iio_channel *channel,
  * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
  * + val2/1e6
  */
-int iio_read_channel_scale(struct iio_channel *chan, int *val,
+int iio_read_channel_scale(struct iio_channel *channel, int *val,
 			   int *val2);
 
 #endif
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] iio: Introduce a new fractional value type
  2012-09-14 15:21 [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Lars-Peter Clausen
@ 2012-09-14 15:21 ` Lars-Peter Clausen
  2012-09-15  9:13   ` Jonathan Cameron
  2012-09-14 15:21 ` [PATCH 3/4] iio:inkern: Add function to read the processed value Lars-Peter Clausen
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Lars-Peter Clausen @ 2012-09-14 15:21 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Milo Kim, anish kumar, Lars-Peter Clausen

Currently IIO uses a decimal fixed point representations for real type numbers.
This patch introduces a new representation for rational type numbers. The number
will be expressed by specifying a numerator and denominator. For converting a
raw value to a processed value multiply it by the numerator and divide it by the
denominator.

The reasoning for introducing this new type is that for a lot of devices the
scale can be represented easily by a fractional number, but it is not possible
to represent it as fixed point number without rounding.  E.g. for a simple DAC
the scale is often the reference voltage divided by the number of possible
values (Usually 2**n_bits - 1). Each driver currently implements the conversion
of this fraction to a fixed point number on its own.

Also when it comes to the in-kernel interface this allows to directly use the
fractional factors to convert a raw value to a processed value. This should on
one hand require less instructions and on the other hand increase the
precession.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/iio/industrialio-core.c |    6 ++++++
 include/linux/iio/types.h       |    1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 0499330..6eb24db 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -366,6 +366,7 @@ 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);
+	unsigned long long tmp;
 	int val, val2;
 	bool scale_db = false;
 	int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
@@ -391,6 +392,11 @@ static ssize_t iio_read_channel_info(struct device *dev,
 			return sprintf(buf, "-%d.%09u\n", val, -val2);
 		else
 			return sprintf(buf, "%d.%09u\n", val, val2);
+	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);
 	default:
 		return 0;
 	}
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 44e3977..5c647ec 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -57,5 +57,6 @@ enum iio_modifier {
 #define IIO_VAL_INT_PLUS_MICRO 2
 #define IIO_VAL_INT_PLUS_NANO 3
 #define IIO_VAL_INT_PLUS_MICRO_DB 4
+#define IIO_VAL_FRACTIONAL 10
 
 #endif /* _IIO_TYPES_H_ */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] iio:inkern: Add function to read the processed value
  2012-09-14 15:21 [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Lars-Peter Clausen
  2012-09-14 15:21 ` [PATCH 2/4] iio: Introduce a new fractional value type Lars-Peter Clausen
@ 2012-09-14 15:21 ` Lars-Peter Clausen
  2012-09-15  9:26   ` Jonathan Cameron
  2012-09-14 15:21 ` [PATCH 4/4] staging:iio:hwmon bridge: Use iio_read_channel_processed Lars-Peter Clausen
  2012-09-15  9:10 ` [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Jonathan Cameron
  3 siblings, 1 reply; 9+ messages in thread
From: Lars-Peter Clausen @ 2012-09-14 15:21 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Milo Kim, anish kumar, Lars-Peter Clausen

Add a function to read a processed value from a channel. The function will first
attempt to read the IIO_CHAN_INFO_PROCESSED attribute. If that fails it will
read the IIO_CHAN_INFO_RAW attribute and convert the result from a raw value to
a processed value.

The patch also introduces a function to convert raw value to a processed value
and exports it, in case a user needs or wants to do the conversion by itself.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/iio/inkern.c         |  114 ++++++++++++++++++++++++++++++++++++++----
 include/linux/iio/consumer.h |   38 ++++++++++++++
 include/linux/iio/iio.h      |   17 +++++++
 3 files changed, 160 insertions(+), 9 deletions(-)

diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index a14e55d..37299bf 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -229,9 +229,21 @@ void iio_channel_release_all(struct iio_channel *channels)
 }
 EXPORT_SYMBOL_GPL(iio_channel_release_all);
 
+static iio_channel_read(struct iio_channel *chan, int *val, int *val2,
+	enum iio_chan_info_enum info)
+{
+	int unused;
+
+	if (val2 == NULL)
+		val2 = &unused;
+
+	return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
+						val, val2, info);
+}
+
 int iio_read_channel_raw(struct iio_channel *chan, int *val)
 {
-	int val2, ret;
+	int ret;
 
 	mutex_lock(&chan->indio_dev->info_exist_lock);
 	if (chan->indio_dev->info == NULL) {
@@ -239,10 +251,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
 		goto err_unlock;
 	}
 
-	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
-					      chan->channel,
-					      val, &val2,
-					      IIO_CHAN_INFO_RAW);
+	ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
 err_unlock:
 	mutex_unlock(&chan->indio_dev->info_exist_lock);
 
@@ -250,6 +259,96 @@ err_unlock:
 }
 EXPORT_SYMBOL_GPL(iio_read_channel_raw);
 
+static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
+	int raw, int *processed, unsigned int scale)
+{
+	int scale_type, scale_val, scale_val2, offset;
+	s64 raw64 = raw;
+	int ret;
+
+	ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
+	if (ret == 0)
+		raw64 += offset;
+
+	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
+					IIO_CHAN_INFO_SCALE);
+	if (scale_type < 0)
+		return scale_type;
+
+	switch (scale_type) {
+	case IIO_VAL_INT:
+		*processed = raw * scale_val;
+		break;
+	case IIO_VAL_INT_PLUS_MICRO:
+		if (scale_val2 < 0)
+			*processed = -raw * scale_val;
+		else
+			*processed = raw * scale_val;
+		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000LL);
+		break;
+	case IIO_VAL_INT_PLUS_NANO:
+		if (scale_val2 < 0)
+			*processed = -raw * scale_val;
+		else
+			*processed = raw * scale_val;
+		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000000LL);
+		break;
+	case IIO_VAL_FRACTIONAL:
+		*processed = div_s64(raw * (s64)scale_val * scale, scale_val2);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
+	int *processed, unsigned int scale)
+{
+	int ret;
+
+	mutex_lock(&chan->indio_dev->info_exist_lock);
+	if (chan->indio_dev->info == NULL) {
+		ret = -ENODEV;
+		goto err_unlock;
+	}
+
+	ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
+							scale);
+err_unlock:
+	mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
+
+int iio_read_channel_processed(struct iio_channel *chan, int *val)
+{
+	int unused, ret;
+
+	mutex_lock(&chan->indio_dev->info_exist_lock);
+	if (chan->indio_dev->info == NULL) {
+		ret = -ENODEV;
+		goto err_unlock;
+	}
+
+	if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
+		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_PROCESSED);
+	} else {
+		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
+		if (ret < 0)
+			goto err_unlock;
+		ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
+	}
+
+err_unlock:
+	mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_read_channel_processed);
+
 int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
 {
 	int ret;
@@ -260,10 +359,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
 		goto err_unlock;
 	}
 
-	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
-					      chan->channel,
-					      val, val2,
-					      IIO_CHAN_INFO_SCALE);
+	ret = iio_read_channel(chan, val, val2, IIO_CHAN_INFO_SCALE);
 err_unlock:
 	mutex_unlock(&chan->indio_dev->info_exist_lock);
 
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 27759ac3..3f66304 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -71,6 +71,21 @@ int iio_read_channel_raw(struct iio_channel *channel,
 			 int *val);
 
 /**
+ * iio_read_channel_processed() - read processed value from a given channel
+ * @channel:		The channel being queried.
+ * @val:		Value read back.
+ *
+ * Returns an error code or 0.
+ *
+ * This function will read a processed value from a channel. A processed value
+ * means that this value will have the correct unit and not some device internal
+ * representation. If the device does not support reporting a processed value
+ * the function will query the raw value and the channels scale and offset and
+ * do the appropriate transformation.
+ */
+int iio_read_channel_processed(const struct iio_channel *channel, int *val);
+
+/**
  * iio_get_channel_type() - get the type of a channel
  * @channel:		The channel being queried.
  * @type:		The type of the channel.
@@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel,
 int iio_read_channel_scale(struct iio_channel *channel, int *val,
 			   int *val2);
 
+/**
+ * iio_convert_raw_to_processed() - Converts a raw value to a processed value
+ * @channel:		The channel being queried
+ * @raw:		The raw IIO to convert
+ * @processed:		The result of the conversion
+ * @scale:		Scale factor to apply during the conversion
+ *
+ * Returns an error code or 0.
+ *
+ * This function converts a raw value to processed value for a specific channel.
+ * A raw value is the device internal representation of a sample and the value
+ * returned by iio_read_channel_raw, so the unit of that value is device
+ * depended. A processed value on the other hand is value has a normed unit
+ * according with the IIO specification.
+ *
+ * The scale factor allows to increase the precession of the returned value. For
+ * a scale factor of 1 the function will return the result in the normal IIO
+ * unit for the channel type. E.g. millivolt for voltage channels, if you want
+ * nanovolts instead pass 1000 as the scale factor.
+ */
+int iio_convert_raw_to_processed(const struct iio_channel *channel, int raw,
+	int *processed, unsigned int scale);
+
 #endif
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 30affa5..c0ae76a 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -40,6 +40,8 @@ enum iio_chan_info_enum {
 
 #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2)
 #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1)
+#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \
+				    IIO_CHAN_INFO_SEPARATE_BIT(type))
 
 #define IIO_CHAN_INFO_RAW_SEPARATE_BIT			\
 	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW)
@@ -261,6 +263,21 @@ struct iio_chan_spec {
 	unsigned		differential:1;
 };
 
+
+/**
+ * iio_channel_has_info() - Checks whether a channel supports a info attribute
+ * @chan: The channel to be queried
+ * @type: Type of the info attribute to be checked
+ *
+ * Returns true if the channels supports reporting values for the given info
+ * attribute type, false otherwise.
+ */
+static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
+	enum iio_chan_info_enum type)
+{
+	return chan->info_mask & IIO_CHAN_INFO_BITS(type);
+}
+
 #define IIO_ST(si, rb, sb, sh)						\
 	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] staging:iio:hwmon bridge: Use iio_read_channel_processed
  2012-09-14 15:21 [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Lars-Peter Clausen
  2012-09-14 15:21 ` [PATCH 2/4] iio: Introduce a new fractional value type Lars-Peter Clausen
  2012-09-14 15:21 ` [PATCH 3/4] iio:inkern: Add function to read the processed value Lars-Peter Clausen
@ 2012-09-14 15:21 ` Lars-Peter Clausen
  2012-09-15  9:10 ` [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Jonathan Cameron
  3 siblings, 0 replies; 9+ messages in thread
From: Lars-Peter Clausen @ 2012-09-14 15:21 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Milo Kim, anish kumar, Lars-Peter Clausen

Use the iio_read_channel_processed function to read the sample value in the
proper unit instead of using iio_read_channel_raw and iio_read_channel_scale and
doing the unit conversion manually.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/iio/inkern.c            |    6 +++---
 drivers/staging/iio/iio_hwmon.c |   33 +++++----------------------------
 include/linux/iio/consumer.h    |    4 ++--
 3 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 37299bf..89fdf33 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -229,7 +229,7 @@ void iio_channel_release_all(struct iio_channel *channels)
 }
 EXPORT_SYMBOL_GPL(iio_channel_release_all);
 
-static iio_channel_read(struct iio_channel *chan, int *val, int *val2,
+static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
 	enum iio_chan_info_enum info)
 {
 	int unused;
@@ -325,7 +325,7 @@ EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
 
 int iio_read_channel_processed(struct iio_channel *chan, int *val)
 {
-	int unused, ret;
+	int ret;
 
 	mutex_lock(&chan->indio_dev->info_exist_lock);
 	if (chan->indio_dev->info == NULL) {
@@ -359,7 +359,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
 		goto err_unlock;
 	}
 
-	ret = iio_read_channel(chan, val, val2, IIO_CHAN_INFO_SCALE);
+	ret = iio_channel_read(chan, val, val2, IIO_CHAN_INFO_SCALE);
 err_unlock:
 	mutex_unlock(&chan->indio_dev->info_exist_lock);
 
diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c
index 69d4a3b..5d49122 100644
--- a/drivers/staging/iio/iio_hwmon.c
+++ b/drivers/staging/iio/iio_hwmon.c
@@ -42,40 +42,17 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
 				  struct device_attribute *attr,
 				  char *buf)
 {
-	long result;
-	int val, ret, scaleint, scalepart;
+	int result;
+	int ret;
 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
 	struct iio_hwmon_state *state = dev_get_drvdata(dev);
 
-	/*
-	 * No locking between this pair, so theoretically possible
-	 * the scale has changed.
-	 */
-	ret = iio_read_channel_raw(&state->channels[sattr->index],
-				      &val);
+	ret = iio_read_channel_processed(&state->channels[sattr->index],
+					&result);
 	if (ret < 0)
 		return ret;
 
-	ret = iio_read_channel_scale(&state->channels[sattr->index],
-					&scaleint, &scalepart);
-	if (ret < 0)
-		return ret;
-	switch (ret) {
-	case IIO_VAL_INT:
-		result = val * scaleint;
-		break;
-	case IIO_VAL_INT_PLUS_MICRO:
-		result = (s64)val * (s64)scaleint +
-			div_s64((s64)val * (s64)scalepart, 1000000LL);
-		break;
-	case IIO_VAL_INT_PLUS_NANO:
-		result = (s64)val * (s64)scaleint +
-			div_s64((s64)val * (s64)scalepart, 1000000000LL);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return sprintf(buf, "%ld\n", result);
+	return sprintf(buf, "%d\n", result);
 }
 
 static void iio_hwmon_free_attrs(struct iio_hwmon_state *st)
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 3f66304..d856e5d 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -83,7 +83,7 @@ int iio_read_channel_raw(struct iio_channel *channel,
  * the function will query the raw value and the channels scale and offset and
  * do the appropriate transformation.
  */
-int iio_read_channel_processed(const struct iio_channel *channel, int *val);
+int iio_read_channel_processed(struct iio_channel *channel, int *val);
 
 /**
  * iio_get_channel_type() - get the type of a channel
@@ -128,7 +128,7 @@ int iio_read_channel_scale(struct iio_channel *channel, int *val,
  * unit for the channel type. E.g. millivolt for voltage channels, if you want
  * nanovolts instead pass 1000 as the scale factor.
  */
-int iio_convert_raw_to_processed(const struct iio_channel *channel, int raw,
+int iio_convert_raw_to_processed(struct iio_channel *channel, int raw,
 	int *processed, unsigned int scale);
 
 #endif
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency
  2012-09-14 15:21 [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Lars-Peter Clausen
                   ` (2 preceding siblings ...)
  2012-09-14 15:21 ` [PATCH 4/4] staging:iio:hwmon bridge: Use iio_read_channel_processed Lars-Peter Clausen
@ 2012-09-15  9:10 ` Jonathan Cameron
  3 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2012-09-15  9:10 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Jonathan Cameron, linux-iio, Milo Kim, anish kumar

On 09/14/2012 04:21 PM, Lars-Peter Clausen wrote:
> For the iio_read_channel_raw and iio_read_channel_scale the kerneldoc comment
> refers to an argument called "channel", while the argument is called "chan" in
> the function signature. This leads to the following warnings from kerneldoc:
> 
> 	Warning(include/linux/iio/consumer.h:71): No description found for parameter 'chan'
> 	Warning(include/linux/iio/consumer.h:71): Excess function parameter 'channel' description in 'iio_read_channel_raw'
> 	Warning(include/linux/iio/consumer.h:109): No description found for parameter 'chan'
> 	Warning(include/linux/iio/consumer.h:109): Excess function parameter 'channel' description in 'iio_read_channel_scale'
> 
> This patch fixes the warnings by naming them consistently.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

Why do it this way round? It is inconsistent with most of the other functions
in consumer.h and if you were to do this I'd argue in favour of also changing
the naming in the implementation.. Much easier to just change the documentation
to match the implementation!
> ---
>  include/linux/iio/consumer.h |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
> index 06ab4ec..27759ac3 100644
> --- a/include/linux/iio/consumer.h
> +++ b/include/linux/iio/consumer.h
> @@ -67,7 +67,7 @@ void iio_channel_release_all(struct iio_channel *chan);
>   * Note raw reads from iio channels are in adc counts and hence
>   * scale will need to be applied if standard units required.
>   */
> -int iio_read_channel_raw(struct iio_channel *chan,
> +int iio_read_channel_raw(struct iio_channel *channel,
>  			 int *val);
>  
>  /**
> @@ -90,7 +90,7 @@ int iio_get_channel_type(struct iio_channel *channel,
>   * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
>   * + val2/1e6
>   */
> -int iio_read_channel_scale(struct iio_channel *chan, int *val,
> +int iio_read_channel_scale(struct iio_channel *channel, int *val,
>  			   int *val2);
>  
>  #endif
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] iio: Introduce a new fractional value type
  2012-09-14 15:21 ` [PATCH 2/4] iio: Introduce a new fractional value type Lars-Peter Clausen
@ 2012-09-15  9:13   ` Jonathan Cameron
  0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2012-09-15  9:13 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Jonathan Cameron, linux-iio, Milo Kim, anish kumar

On 09/14/2012 04:21 PM, Lars-Peter Clausen wrote:
> Currently IIO uses a decimal fixed point representations for real type numbers.
> This patch introduces a new representation for rational type numbers. The number
> will be expressed by specifying a numerator and denominator. For converting a
> raw value to a processed value multiply it by the numerator and divide it by the
> denominator.
> 
> The reasoning for introducing this new type is that for a lot of devices the
> scale can be represented easily by a fractional number, but it is not possible
> to represent it as fixed point number without rounding.  E.g. for a simple DAC
> the scale is often the reference voltage divided by the number of possible
> values (Usually 2**n_bits - 1). Each driver currently implements the conversion
> of this fraction to a fixed point number on its own.
> 
> Also when it comes to the in-kernel interface this allows to directly use the
> fractional factors to convert a raw value to a processed value. This should on
> one hand require less instructions and on the other hand increase the
> precession.
precession -> precision (fixed in merge)
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
merged to togreg branch of iio.git
> ---
>  drivers/iio/industrialio-core.c |    6 ++++++
>  include/linux/iio/types.h       |    1 +
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 0499330..6eb24db 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -366,6 +366,7 @@ 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);
> +	unsigned long long tmp;
>  	int val, val2;
>  	bool scale_db = false;
>  	int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
> @@ -391,6 +392,11 @@ static ssize_t iio_read_channel_info(struct device *dev,
>  			return sprintf(buf, "-%d.%09u\n", val, -val2);
>  		else
>  			return sprintf(buf, "%d.%09u\n", val, val2);
> +	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);
>  	default:
>  		return 0;
>  	}
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index 44e3977..5c647ec 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -57,5 +57,6 @@ enum iio_modifier {
>  #define IIO_VAL_INT_PLUS_MICRO 2
>  #define IIO_VAL_INT_PLUS_NANO 3
>  #define IIO_VAL_INT_PLUS_MICRO_DB 4
> +#define IIO_VAL_FRACTIONAL 10
>  
>  #endif /* _IIO_TYPES_H_ */
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] iio:inkern: Add function to read the processed value
  2012-09-14 15:21 ` [PATCH 3/4] iio:inkern: Add function to read the processed value Lars-Peter Clausen
@ 2012-09-15  9:26   ` Jonathan Cameron
  2012-09-15  9:31     ` Lars-Peter Clausen
  0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2012-09-15  9:26 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Jonathan Cameron, linux-iio, Milo Kim, anish kumar

On 09/14/2012 04:21 PM, Lars-Peter Clausen wrote:
> Add a function to read a processed value from a channel. The function will first
> attempt to read the IIO_CHAN_INFO_PROCESSED attribute. If that fails it will
> read the IIO_CHAN_INFO_RAW attribute and convert the result from a raw value to
> a processed value.
>
> The patch also introduces a function to convert raw value to a processed value
> and exports it, in case a user needs or wants to do the conversion by itself.
Take another look at this one... Either that or there is a dependency here on something
you haven't mentioned (and some of the sparse warnings are about stuff entirely in here).


drivers/iio/inkern.c:240:47: warning: incorrect type in return expression (invalid types)
drivers/iio/inkern.c:240:47:    expected incomplete type
drivers/iio/inkern.c:240:47:    got int
drivers/iio/inkern.c:254:13: warning: incorrect type in assignment (different base types)
drivers/iio/inkern.c:254:13:    expected int [signed] [assigned] ret
drivers/iio/inkern.c:254:13:    got incomplete type
drivers/iio/inkern.c:269:13: warning: incorrect type in assignment (different base types)
drivers/iio/inkern.c:269:13:    expected int [signed] ret
drivers/iio/inkern.c:269:13:    got incomplete type
drivers/iio/inkern.c:273:20: warning: incorrect type in assignment (different base types)
drivers/iio/inkern.c:273:20:    expected int [signed] scale_type
drivers/iio/inkern.c:273:20:    got incomplete type
drivers/iio/inkern.c:306:5: error: symbol 'iio_convert_raw_to_processed' redeclared with different type (originally
declared at include/linux/iio/consumer.h:131) - incompatible argument 1 (different modifiers)
drivers/iio/inkern.c:326:5: error: symbol 'iio_read_channel_processed' redeclared with different type (originally
declared at include/linux/iio/consumer.h:86) - incompatible argument 1 (different modifiers)
drivers/iio/inkern.c:362:15: error: undefined identifier 'iio_read_channel'
  CC [M]  drivers/iio/inkern.o
drivers/iio/inkern.c:232:8: warning: return type defaults to 'int'
drivers/iio/inkern.c:306:5: error: conflicting types for 'iio_convert_raw_to_processed'
include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
drivers/iio/inkern.c:324:1: error: conflicting types for 'iio_convert_raw_to_processed'
include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
drivers/iio/inkern.c:326:5: error: conflicting types for 'iio_read_channel_processed'
include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
drivers/iio/inkern.c: In function 'iio_read_channel_processed':
drivers/iio/inkern.c:328:6: warning: unused variable 'unused'
drivers/iio/inkern.c: At top level:
drivers/iio/inkern.c:350:1: error: conflicting types for 'iio_read_channel_processed'
include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
drivers/iio/inkern.c: In function 'iio_read_channel_scale':
drivers/iio/inkern.c:362:2: error: implicit declaration of function 'iio_read_channel'
make[2]: *** [drivers/iio/inkern.o] Error 1



>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  drivers/iio/inkern.c         |  114 ++++++++++++++++++++++++++++++++++++++----
>  include/linux/iio/consumer.h |   38 ++++++++++++++
>  include/linux/iio/iio.h      |   17 +++++++
>  3 files changed, 160 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
> index a14e55d..37299bf 100644
> --- a/drivers/iio/inkern.c
> +++ b/drivers/iio/inkern.c
> @@ -229,9 +229,21 @@ void iio_channel_release_all(struct iio_channel *channels)
>  }
>  EXPORT_SYMBOL_GPL(iio_channel_release_all);
>
> +static iio_channel_read(struct iio_channel *chan, int *val, int *val2,
> +	enum iio_chan_info_enum info)
> +{
> +	int unused;
> +
> +	if (val2 == NULL)
> +		val2 = &unused;
> +
> +	return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
> +						val, val2, info);
> +}
> +
>  int iio_read_channel_raw(struct iio_channel *chan, int *val)
>  {
> -	int val2, ret;
> +	int ret;
>
>  	mutex_lock(&chan->indio_dev->info_exist_lock);
>  	if (chan->indio_dev->info == NULL) {
> @@ -239,10 +251,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
>  		goto err_unlock;
>  	}
>
> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
> -					      chan->channel,
> -					      val, &val2,
> -					      IIO_CHAN_INFO_RAW);
> +	ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
>  err_unlock:
>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>
> @@ -250,6 +259,96 @@ err_unlock:
>  }
>  EXPORT_SYMBOL_GPL(iio_read_channel_raw);
>
> +static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
> +	int raw, int *processed, unsigned int scale)
> +{
> +	int scale_type, scale_val, scale_val2, offset;
> +	s64 raw64 = raw;
> +	int ret;
> +
> +	ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
> +	if (ret == 0)
> +		raw64 += offset;
> +
> +	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
> +					IIO_CHAN_INFO_SCALE);
> +	if (scale_type < 0)
> +		return scale_type;
> +
> +	switch (scale_type) {
> +	case IIO_VAL_INT:
> +		*processed = raw * scale_val;
> +		break;
> +	case IIO_VAL_INT_PLUS_MICRO:
> +		if (scale_val2 < 0)
> +			*processed = -raw * scale_val;
> +		else
> +			*processed = raw * scale_val;
> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000LL);
> +		break;
> +	case IIO_VAL_INT_PLUS_NANO:
> +		if (scale_val2 < 0)
> +			*processed = -raw * scale_val;
> +		else
> +			*processed = raw * scale_val;
> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000000LL);
> +		break;
> +	case IIO_VAL_FRACTIONAL:
> +		*processed = div_s64(raw * (s64)scale_val * scale, scale_val2);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
> +	int *processed, unsigned int scale)
> +{
> +	int ret;
> +
> +	mutex_lock(&chan->indio_dev->info_exist_lock);
> +	if (chan->indio_dev->info == NULL) {
> +		ret = -ENODEV;
> +		goto err_unlock;
> +	}
> +
> +	ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
> +							scale);
> +err_unlock:
> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
> +
chan not const here but is in the header..
> +int iio_read_channel_processed(struct iio_channel *chan, int *val)
> +{
> +	int unused, ret;
> +
> +	mutex_lock(&chan->indio_dev->info_exist_lock);
> +	if (chan->indio_dev->info == NULL) {
> +		ret = -ENODEV;
> +		goto err_unlock;
> +	}
> +
> +	if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_PROCESSED);
> +	} else {
> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
> +		if (ret < 0)
> +			goto err_unlock;
> +		ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
> +	}
> +
> +err_unlock:
> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(iio_read_channel_processed);
> +
>  int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>  {
>  	int ret;
> @@ -260,10 +359,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>  		goto err_unlock;
>  	}
>
> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
> -					      chan->channel,
> -					      val, val2,
> -					      IIO_CHAN_INFO_SCALE);
> +	ret = iio_read_channel(chan, val, val2, IIO_CHAN_INFO_SCALE);
>  err_unlock:
>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>
> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
> index 27759ac3..3f66304 100644
> --- a/include/linux/iio/consumer.h
> +++ b/include/linux/iio/consumer.h
> @@ -71,6 +71,21 @@ int iio_read_channel_raw(struct iio_channel *channel,
>  			 int *val);
>
>  /**
> + * iio_read_channel_processed() - read processed value from a given channel
> + * @channel:		The channel being queried.
> + * @val:		Value read back.
> + *
> + * Returns an error code or 0.
> + *
> + * This function will read a processed value from a channel. A processed value
> + * means that this value will have the correct unit and not some device internal
> + * representation. If the device does not support reporting a processed value
> + * the function will query the raw value and the channels scale and offset and
> + * do the appropriate transformation.
> + */
> +int iio_read_channel_processed(const struct iio_channel *channel, int *val);
> +
> +/**
>   * iio_get_channel_type() - get the type of a channel
>   * @channel:		The channel being queried.
>   * @type:		The type of the channel.
> @@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel,
>  int iio_read_channel_scale(struct iio_channel *channel, int *val,
>  			   int *val2);
>
> +/**
> + * iio_convert_raw_to_processed() - Converts a raw value to a processed value
> + * @channel:		The channel being queried
> + * @raw:		The raw IIO to convert
> + * @processed:		The result of the conversion
> + * @scale:		Scale factor to apply during the conversion
> + *
> + * Returns an error code or 0.
> + *
> + * This function converts a raw value to processed value for a specific channel.
> + * A raw value is the device internal representation of a sample and the value
> + * returned by iio_read_channel_raw, so the unit of that value is device
> + * depended. A processed value on the other hand is value has a normed unit
> + * according with the IIO specification.
> + *
> + * The scale factor allows to increase the precession of the returned value. For
> + * a scale factor of 1 the function will return the result in the normal IIO
> + * unit for the channel type. E.g. millivolt for voltage channels, if you want
> + * nanovolts instead pass 1000 as the scale factor.
> + */
> +int iio_convert_raw_to_processed(const struct iio_channel *channel, int raw,
> +	int *processed, unsigned int scale);
const here but not in implementation....
> +
>  #endif
> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
> index 30affa5..c0ae76a 100644
> --- a/include/linux/iio/iio.h
> +++ b/include/linux/iio/iio.h
> @@ -40,6 +40,8 @@ enum iio_chan_info_enum {
>
>  #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2)
>  #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1)
> +#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \
> +				    IIO_CHAN_INFO_SEPARATE_BIT(type))
>
>  #define IIO_CHAN_INFO_RAW_SEPARATE_BIT			\
>  	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW)
> @@ -261,6 +263,21 @@ struct iio_chan_spec {
>  	unsigned		differential:1;
>  };
>
> +
> +/**
> + * iio_channel_has_info() - Checks whether a channel supports a info attribute
> + * @chan: The channel to be queried
> + * @type: Type of the info attribute to be checked
> + *
> + * Returns true if the channels supports reporting values for the given info
> + * attribute type, false otherwise.
> + */
> +static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
> +	enum iio_chan_info_enum type)
> +{
> +	return chan->info_mask & IIO_CHAN_INFO_BITS(type);
> +}
> +
>  #define IIO_ST(si, rb, sb, sh)						\
>  	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] iio:inkern: Add function to read the processed value
  2012-09-15  9:26   ` Jonathan Cameron
@ 2012-09-15  9:31     ` Lars-Peter Clausen
  2012-09-15  9:35       ` Jonathan Cameron
  0 siblings, 1 reply; 9+ messages in thread
From: Lars-Peter Clausen @ 2012-09-15  9:31 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: Jonathan Cameron, linux-iio, Milo Kim, anish kumar

On 09/15/2012 11:26 AM, Jonathan Cameron wrote:
> On 09/14/2012 04:21 PM, Lars-Peter Clausen wrote:
>> Add a function to read a processed value from a channel. The function will first
>> attempt to read the IIO_CHAN_INFO_PROCESSED attribute. If that fails it will
>> read the IIO_CHAN_INFO_RAW attribute and convert the result from a raw value to
>> a processed value.
>>
>> The patch also introduces a function to convert raw value to a processed value
>> and exports it, in case a user needs or wants to do the conversion by itself.
> Take another look at this one... Either that or there is a dependency here on something
> you haven't mentioned (and some of the sparse warnings are about stuff entirely in here).
> 

I should clearly stop sending out patches late in the afternoon... the fixes
for all these errors slipped into patch 4...

> 
> drivers/iio/inkern.c:240:47: warning: incorrect type in return expression (invalid types)
> drivers/iio/inkern.c:240:47:    expected incomplete type
> drivers/iio/inkern.c:240:47:    got int
> drivers/iio/inkern.c:254:13: warning: incorrect type in assignment (different base types)
> drivers/iio/inkern.c:254:13:    expected int [signed] [assigned] ret
> drivers/iio/inkern.c:254:13:    got incomplete type
> drivers/iio/inkern.c:269:13: warning: incorrect type in assignment (different base types)
> drivers/iio/inkern.c:269:13:    expected int [signed] ret
> drivers/iio/inkern.c:269:13:    got incomplete type
> drivers/iio/inkern.c:273:20: warning: incorrect type in assignment (different base types)
> drivers/iio/inkern.c:273:20:    expected int [signed] scale_type
> drivers/iio/inkern.c:273:20:    got incomplete type
> drivers/iio/inkern.c:306:5: error: symbol 'iio_convert_raw_to_processed' redeclared with different type (originally
> declared at include/linux/iio/consumer.h:131) - incompatible argument 1 (different modifiers)
> drivers/iio/inkern.c:326:5: error: symbol 'iio_read_channel_processed' redeclared with different type (originally
> declared at include/linux/iio/consumer.h:86) - incompatible argument 1 (different modifiers)
> drivers/iio/inkern.c:362:15: error: undefined identifier 'iio_read_channel'
>   CC [M]  drivers/iio/inkern.o
> drivers/iio/inkern.c:232:8: warning: return type defaults to 'int'
> drivers/iio/inkern.c:306:5: error: conflicting types for 'iio_convert_raw_to_processed'
> include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
> drivers/iio/inkern.c:324:1: error: conflicting types for 'iio_convert_raw_to_processed'
> include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
> drivers/iio/inkern.c:326:5: error: conflicting types for 'iio_read_channel_processed'
> include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
> drivers/iio/inkern.c: In function 'iio_read_channel_processed':
> drivers/iio/inkern.c:328:6: warning: unused variable 'unused'
> drivers/iio/inkern.c: At top level:
> drivers/iio/inkern.c:350:1: error: conflicting types for 'iio_read_channel_processed'
> include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
> drivers/iio/inkern.c: In function 'iio_read_channel_scale':
> drivers/iio/inkern.c:362:2: error: implicit declaration of function 'iio_read_channel'
> make[2]: *** [drivers/iio/inkern.o] Error 1
> 
> 
> 
>>
>> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
>> ---
>>  drivers/iio/inkern.c         |  114 ++++++++++++++++++++++++++++++++++++++----
>>  include/linux/iio/consumer.h |   38 ++++++++++++++
>>  include/linux/iio/iio.h      |   17 +++++++
>>  3 files changed, 160 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
>> index a14e55d..37299bf 100644
>> --- a/drivers/iio/inkern.c
>> +++ b/drivers/iio/inkern.c
>> @@ -229,9 +229,21 @@ void iio_channel_release_all(struct iio_channel *channels)
>>  }
>>  EXPORT_SYMBOL_GPL(iio_channel_release_all);
>>
>> +static iio_channel_read(struct iio_channel *chan, int *val, int *val2,
>> +	enum iio_chan_info_enum info)
>> +{
>> +	int unused;
>> +
>> +	if (val2 == NULL)
>> +		val2 = &unused;
>> +
>> +	return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
>> +						val, val2, info);
>> +}
>> +
>>  int iio_read_channel_raw(struct iio_channel *chan, int *val)
>>  {
>> -	int val2, ret;
>> +	int ret;
>>
>>  	mutex_lock(&chan->indio_dev->info_exist_lock);
>>  	if (chan->indio_dev->info == NULL) {
>> @@ -239,10 +251,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
>>  		goto err_unlock;
>>  	}
>>
>> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
>> -					      chan->channel,
>> -					      val, &val2,
>> -					      IIO_CHAN_INFO_RAW);
>> +	ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
>>  err_unlock:
>>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>
>> @@ -250,6 +259,96 @@ err_unlock:
>>  }
>>  EXPORT_SYMBOL_GPL(iio_read_channel_raw);
>>
>> +static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
>> +	int raw, int *processed, unsigned int scale)
>> +{
>> +	int scale_type, scale_val, scale_val2, offset;
>> +	s64 raw64 = raw;
>> +	int ret;
>> +
>> +	ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
>> +	if (ret == 0)
>> +		raw64 += offset;
>> +
>> +	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
>> +					IIO_CHAN_INFO_SCALE);
>> +	if (scale_type < 0)
>> +		return scale_type;
>> +
>> +	switch (scale_type) {
>> +	case IIO_VAL_INT:
>> +		*processed = raw * scale_val;
>> +		break;
>> +	case IIO_VAL_INT_PLUS_MICRO:
>> +		if (scale_val2 < 0)
>> +			*processed = -raw * scale_val;
>> +		else
>> +			*processed = raw * scale_val;
>> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000LL);
>> +		break;
>> +	case IIO_VAL_INT_PLUS_NANO:
>> +		if (scale_val2 < 0)
>> +			*processed = -raw * scale_val;
>> +		else
>> +			*processed = raw * scale_val;
>> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000000LL);
>> +		break;
>> +	case IIO_VAL_FRACTIONAL:
>> +		*processed = div_s64(raw * (s64)scale_val * scale, scale_val2);
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
>> +	int *processed, unsigned int scale)
>> +{
>> +	int ret;
>> +
>> +	mutex_lock(&chan->indio_dev->info_exist_lock);
>> +	if (chan->indio_dev->info == NULL) {
>> +		ret = -ENODEV;
>> +		goto err_unlock;
>> +	}
>> +
>> +	ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
>> +							scale);
>> +err_unlock:
>> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
>> +
> chan not const here but is in the header..
>> +int iio_read_channel_processed(struct iio_channel *chan, int *val)
>> +{
>> +	int unused, ret;
>> +
>> +	mutex_lock(&chan->indio_dev->info_exist_lock);
>> +	if (chan->indio_dev->info == NULL) {
>> +		ret = -ENODEV;
>> +		goto err_unlock;
>> +	}
>> +
>> +	if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
>> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_PROCESSED);
>> +	} else {
>> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
>> +		if (ret < 0)
>> +			goto err_unlock;
>> +		ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
>> +	}
>> +
>> +err_unlock:
>> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(iio_read_channel_processed);
>> +
>>  int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>>  {
>>  	int ret;
>> @@ -260,10 +359,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>>  		goto err_unlock;
>>  	}
>>
>> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
>> -					      chan->channel,
>> -					      val, val2,
>> -					      IIO_CHAN_INFO_SCALE);
>> +	ret = iio_read_channel(chan, val, val2, IIO_CHAN_INFO_SCALE);
>>  err_unlock:
>>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>
>> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
>> index 27759ac3..3f66304 100644
>> --- a/include/linux/iio/consumer.h
>> +++ b/include/linux/iio/consumer.h
>> @@ -71,6 +71,21 @@ int iio_read_channel_raw(struct iio_channel *channel,
>>  			 int *val);
>>
>>  /**
>> + * iio_read_channel_processed() - read processed value from a given channel
>> + * @channel:		The channel being queried.
>> + * @val:		Value read back.
>> + *
>> + * Returns an error code or 0.
>> + *
>> + * This function will read a processed value from a channel. A processed value
>> + * means that this value will have the correct unit and not some device internal
>> + * representation. If the device does not support reporting a processed value
>> + * the function will query the raw value and the channels scale and offset and
>> + * do the appropriate transformation.
>> + */
>> +int iio_read_channel_processed(const struct iio_channel *channel, int *val);
>> +
>> +/**
>>   * iio_get_channel_type() - get the type of a channel
>>   * @channel:		The channel being queried.
>>   * @type:		The type of the channel.
>> @@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel,
>>  int iio_read_channel_scale(struct iio_channel *channel, int *val,
>>  			   int *val2);
>>
>> +/**
>> + * iio_convert_raw_to_processed() - Converts a raw value to a processed value
>> + * @channel:		The channel being queried
>> + * @raw:		The raw IIO to convert
>> + * @processed:		The result of the conversion
>> + * @scale:		Scale factor to apply during the conversion
>> + *
>> + * Returns an error code or 0.
>> + *
>> + * This function converts a raw value to processed value for a specific channel.
>> + * A raw value is the device internal representation of a sample and the value
>> + * returned by iio_read_channel_raw, so the unit of that value is device
>> + * depended. A processed value on the other hand is value has a normed unit
>> + * according with the IIO specification.
>> + *
>> + * The scale factor allows to increase the precession of the returned value. For
>> + * a scale factor of 1 the function will return the result in the normal IIO
>> + * unit for the channel type. E.g. millivolt for voltage channels, if you want
>> + * nanovolts instead pass 1000 as the scale factor.
>> + */
>> +int iio_convert_raw_to_processed(const struct iio_channel *channel, int raw,
>> +	int *processed, unsigned int scale);
> const here but not in implementation....
>> +
>>  #endif
>> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
>> index 30affa5..c0ae76a 100644
>> --- a/include/linux/iio/iio.h
>> +++ b/include/linux/iio/iio.h
>> @@ -40,6 +40,8 @@ enum iio_chan_info_enum {
>>
>>  #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2)
>>  #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1)
>> +#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \
>> +				    IIO_CHAN_INFO_SEPARATE_BIT(type))
>>
>>  #define IIO_CHAN_INFO_RAW_SEPARATE_BIT			\
>>  	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW)
>> @@ -261,6 +263,21 @@ struct iio_chan_spec {
>>  	unsigned		differential:1;
>>  };
>>
>> +
>> +/**
>> + * iio_channel_has_info() - Checks whether a channel supports a info attribute
>> + * @chan: The channel to be queried
>> + * @type: Type of the info attribute to be checked
>> + *
>> + * Returns true if the channels supports reporting values for the given info
>> + * attribute type, false otherwise.
>> + */
>> +static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
>> +	enum iio_chan_info_enum type)
>> +{
>> +	return chan->info_mask & IIO_CHAN_INFO_BITS(type);
>> +}
>> +
>>  #define IIO_ST(si, rb, sb, sh)						\
>>  	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
>>
>>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] iio:inkern: Add function to read the processed value
  2012-09-15  9:31     ` Lars-Peter Clausen
@ 2012-09-15  9:35       ` Jonathan Cameron
  0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2012-09-15  9:35 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Jonathan Cameron, linux-iio, Milo Kim, anish kumar

On 09/15/2012 10:31 AM, Lars-Peter Clausen wrote:
> On 09/15/2012 11:26 AM, Jonathan Cameron wrote:
>> On 09/14/2012 04:21 PM, Lars-Peter Clausen wrote:
>>> Add a function to read a processed value from a channel. The function will first
>>> attempt to read the IIO_CHAN_INFO_PROCESSED attribute. If that fails it will
>>> read the IIO_CHAN_INFO_RAW attribute and convert the result from a raw value to
>>> a processed value.
>>>
>>> The patch also introduces a function to convert raw value to a processed value
>>> and exports it, in case a user needs or wants to do the conversion by itself.
>> Take another look at this one... Either that or there is a dependency here on something
>> you haven't mentioned (and some of the sparse warnings are about stuff entirely in here).
>>
> 
> I should clearly stop sending out patches late in the afternoon... the fixes
> for all these errors slipped into patch 4...
*laughs* I didn't think of looking there. Not to worry we all do this sort of thing
from time to time.  Also, the original fractional series came with a patch for a driver
(dac i think). I'd like to see that fairly soon to act as an example of it's usage.

> 
>>
>> drivers/iio/inkern.c:240:47: warning: incorrect type in return expression (invalid types)
>> drivers/iio/inkern.c:240:47:    expected incomplete type
>> drivers/iio/inkern.c:240:47:    got int
>> drivers/iio/inkern.c:254:13: warning: incorrect type in assignment (different base types)
>> drivers/iio/inkern.c:254:13:    expected int [signed] [assigned] ret
>> drivers/iio/inkern.c:254:13:    got incomplete type
>> drivers/iio/inkern.c:269:13: warning: incorrect type in assignment (different base types)
>> drivers/iio/inkern.c:269:13:    expected int [signed] ret
>> drivers/iio/inkern.c:269:13:    got incomplete type
>> drivers/iio/inkern.c:273:20: warning: incorrect type in assignment (different base types)
>> drivers/iio/inkern.c:273:20:    expected int [signed] scale_type
>> drivers/iio/inkern.c:273:20:    got incomplete type
>> drivers/iio/inkern.c:306:5: error: symbol 'iio_convert_raw_to_processed' redeclared with different type (originally
>> declared at include/linux/iio/consumer.h:131) - incompatible argument 1 (different modifiers)
>> drivers/iio/inkern.c:326:5: error: symbol 'iio_read_channel_processed' redeclared with different type (originally
>> declared at include/linux/iio/consumer.h:86) - incompatible argument 1 (different modifiers)
>> drivers/iio/inkern.c:362:15: error: undefined identifier 'iio_read_channel'
>>   CC [M]  drivers/iio/inkern.o
>> drivers/iio/inkern.c:232:8: warning: return type defaults to 'int'
>> drivers/iio/inkern.c:306:5: error: conflicting types for 'iio_convert_raw_to_processed'
>> include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
>> drivers/iio/inkern.c:324:1: error: conflicting types for 'iio_convert_raw_to_processed'
>> include/linux/iio/consumer.h:131:5: note: previous declaration of 'iio_convert_raw_to_processed' was here
>> drivers/iio/inkern.c:326:5: error: conflicting types for 'iio_read_channel_processed'
>> include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
>> drivers/iio/inkern.c: In function 'iio_read_channel_processed':
>> drivers/iio/inkern.c:328:6: warning: unused variable 'unused'
>> drivers/iio/inkern.c: At top level:
>> drivers/iio/inkern.c:350:1: error: conflicting types for 'iio_read_channel_processed'
>> include/linux/iio/consumer.h:86:5: note: previous declaration of 'iio_read_channel_processed' was here
>> drivers/iio/inkern.c: In function 'iio_read_channel_scale':
>> drivers/iio/inkern.c:362:2: error: implicit declaration of function 'iio_read_channel'
>> make[2]: *** [drivers/iio/inkern.o] Error 1
>>
>>
>>
>>>
>>> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
>>> ---
>>>  drivers/iio/inkern.c         |  114 ++++++++++++++++++++++++++++++++++++++----
>>>  include/linux/iio/consumer.h |   38 ++++++++++++++
>>>  include/linux/iio/iio.h      |   17 +++++++
>>>  3 files changed, 160 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
>>> index a14e55d..37299bf 100644
>>> --- a/drivers/iio/inkern.c
>>> +++ b/drivers/iio/inkern.c
>>> @@ -229,9 +229,21 @@ void iio_channel_release_all(struct iio_channel *channels)
>>>  }
>>>  EXPORT_SYMBOL_GPL(iio_channel_release_all);
>>>
>>> +static iio_channel_read(struct iio_channel *chan, int *val, int *val2,
>>> +	enum iio_chan_info_enum info)
>>> +{
>>> +	int unused;
>>> +
>>> +	if (val2 == NULL)
>>> +		val2 = &unused;
>>> +
>>> +	return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
>>> +						val, val2, info);
>>> +}
>>> +
>>>  int iio_read_channel_raw(struct iio_channel *chan, int *val)
>>>  {
>>> -	int val2, ret;
>>> +	int ret;
>>>
>>>  	mutex_lock(&chan->indio_dev->info_exist_lock);
>>>  	if (chan->indio_dev->info == NULL) {
>>> @@ -239,10 +251,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
>>>  		goto err_unlock;
>>>  	}
>>>
>>> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
>>> -					      chan->channel,
>>> -					      val, &val2,
>>> -					      IIO_CHAN_INFO_RAW);
>>> +	ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
>>>  err_unlock:
>>>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>>
>>> @@ -250,6 +259,96 @@ err_unlock:
>>>  }
>>>  EXPORT_SYMBOL_GPL(iio_read_channel_raw);
>>>
>>> +static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
>>> +	int raw, int *processed, unsigned int scale)
>>> +{
>>> +	int scale_type, scale_val, scale_val2, offset;
>>> +	s64 raw64 = raw;
>>> +	int ret;
>>> +
>>> +	ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
>>> +	if (ret == 0)
>>> +		raw64 += offset;
>>> +
>>> +	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
>>> +					IIO_CHAN_INFO_SCALE);
>>> +	if (scale_type < 0)
>>> +		return scale_type;
>>> +
>>> +	switch (scale_type) {
>>> +	case IIO_VAL_INT:
>>> +		*processed = raw * scale_val;
>>> +		break;
>>> +	case IIO_VAL_INT_PLUS_MICRO:
>>> +		if (scale_val2 < 0)
>>> +			*processed = -raw * scale_val;
>>> +		else
>>> +			*processed = raw * scale_val;
>>> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000LL);
>>> +		break;
>>> +	case IIO_VAL_INT_PLUS_NANO:
>>> +		if (scale_val2 < 0)
>>> +			*processed = -raw * scale_val;
>>> +		else
>>> +			*processed = raw * scale_val;
>>> +		*processed += div_s64(raw * (s64)scale_val2 * scale, 1000000000LL);
>>> +		break;
>>> +	case IIO_VAL_FRACTIONAL:
>>> +		*processed = div_s64(raw * (s64)scale_val * scale, scale_val2);
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
>>> +	int *processed, unsigned int scale)
>>> +{
>>> +	int ret;
>>> +
>>> +	mutex_lock(&chan->indio_dev->info_exist_lock);
>>> +	if (chan->indio_dev->info == NULL) {
>>> +		ret = -ENODEV;
>>> +		goto err_unlock;
>>> +	}
>>> +
>>> +	ret = iio_convert_raw_to_processed_unlocked(chan, raw, processed,
>>> +							scale);
>>> +err_unlock:
>>> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>> +
>>> +	return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
>>> +
>> chan not const here but is in the header..
>>> +int iio_read_channel_processed(struct iio_channel *chan, int *val)
>>> +{
>>> +	int unused, ret;
>>> +
>>> +	mutex_lock(&chan->indio_dev->info_exist_lock);
>>> +	if (chan->indio_dev->info == NULL) {
>>> +		ret = -ENODEV;
>>> +		goto err_unlock;
>>> +	}
>>> +
>>> +	if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
>>> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_PROCESSED);
>>> +	} else {
>>> +		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
>>> +		if (ret < 0)
>>> +			goto err_unlock;
>>> +		ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
>>> +	}
>>> +
>>> +err_unlock:
>>> +	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>> +
>>> +	return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(iio_read_channel_processed);
>>> +
>>>  int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>>>  {
>>>  	int ret;
>>> @@ -260,10 +359,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
>>>  		goto err_unlock;
>>>  	}
>>>
>>> -	ret = chan->indio_dev->info->read_raw(chan->indio_dev,
>>> -					      chan->channel,
>>> -					      val, val2,
>>> -					      IIO_CHAN_INFO_SCALE);
>>> +	ret = iio_read_channel(chan, val, val2, IIO_CHAN_INFO_SCALE);
>>>  err_unlock:
>>>  	mutex_unlock(&chan->indio_dev->info_exist_lock);
>>>
>>> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
>>> index 27759ac3..3f66304 100644
>>> --- a/include/linux/iio/consumer.h
>>> +++ b/include/linux/iio/consumer.h
>>> @@ -71,6 +71,21 @@ int iio_read_channel_raw(struct iio_channel *channel,
>>>  			 int *val);
>>>
>>>  /**
>>> + * iio_read_channel_processed() - read processed value from a given channel
>>> + * @channel:		The channel being queried.
>>> + * @val:		Value read back.
>>> + *
>>> + * Returns an error code or 0.
>>> + *
>>> + * This function will read a processed value from a channel. A processed value
>>> + * means that this value will have the correct unit and not some device internal
>>> + * representation. If the device does not support reporting a processed value
>>> + * the function will query the raw value and the channels scale and offset and
>>> + * do the appropriate transformation.
>>> + */
>>> +int iio_read_channel_processed(const struct iio_channel *channel, int *val);
>>> +
>>> +/**
>>>   * iio_get_channel_type() - get the type of a channel
>>>   * @channel:		The channel being queried.
>>>   * @type:		The type of the channel.
>>> @@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel,
>>>  int iio_read_channel_scale(struct iio_channel *channel, int *val,
>>>  			   int *val2);
>>>
>>> +/**
>>> + * iio_convert_raw_to_processed() - Converts a raw value to a processed value
>>> + * @channel:		The channel being queried
>>> + * @raw:		The raw IIO to convert
>>> + * @processed:		The result of the conversion
>>> + * @scale:		Scale factor to apply during the conversion
>>> + *
>>> + * Returns an error code or 0.
>>> + *
>>> + * This function converts a raw value to processed value for a specific channel.
>>> + * A raw value is the device internal representation of a sample and the value
>>> + * returned by iio_read_channel_raw, so the unit of that value is device
>>> + * depended. A processed value on the other hand is value has a normed unit
>>> + * according with the IIO specification.
>>> + *
>>> + * The scale factor allows to increase the precession of the returned value. For
>>> + * a scale factor of 1 the function will return the result in the normal IIO
>>> + * unit for the channel type. E.g. millivolt for voltage channels, if you want
>>> + * nanovolts instead pass 1000 as the scale factor.
>>> + */
>>> +int iio_convert_raw_to_processed(const struct iio_channel *channel, int raw,
>>> +	int *processed, unsigned int scale);
>> const here but not in implementation....
>>> +
>>>  #endif
>>> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
>>> index 30affa5..c0ae76a 100644
>>> --- a/include/linux/iio/iio.h
>>> +++ b/include/linux/iio/iio.h
>>> @@ -40,6 +40,8 @@ enum iio_chan_info_enum {
>>>
>>>  #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2)
>>>  #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1)
>>> +#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \
>>> +				    IIO_CHAN_INFO_SEPARATE_BIT(type))
>>>
>>>  #define IIO_CHAN_INFO_RAW_SEPARATE_BIT			\
>>>  	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW)
>>> @@ -261,6 +263,21 @@ struct iio_chan_spec {
>>>  	unsigned		differential:1;
>>>  };
>>>
>>> +
>>> +/**
>>> + * iio_channel_has_info() - Checks whether a channel supports a info attribute
>>> + * @chan: The channel to be queried
>>> + * @type: Type of the info attribute to be checked
>>> + *
>>> + * Returns true if the channels supports reporting values for the given info
>>> + * attribute type, false otherwise.
>>> + */
>>> +static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
>>> +	enum iio_chan_info_enum type)
>>> +{
>>> +	return chan->info_mask & IIO_CHAN_INFO_BITS(type);
>>> +}
>>> +
>>>  #define IIO_ST(si, rb, sb, sh)						\
>>>  	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
>>>
>>>
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-09-15  9:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-14 15:21 [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Lars-Peter Clausen
2012-09-14 15:21 ` [PATCH 2/4] iio: Introduce a new fractional value type Lars-Peter Clausen
2012-09-15  9:13   ` Jonathan Cameron
2012-09-14 15:21 ` [PATCH 3/4] iio:inkern: Add function to read the processed value Lars-Peter Clausen
2012-09-15  9:26   ` Jonathan Cameron
2012-09-15  9:31     ` Lars-Peter Clausen
2012-09-15  9:35       ` Jonathan Cameron
2012-09-14 15:21 ` [PATCH 4/4] staging:iio:hwmon bridge: Use iio_read_channel_processed Lars-Peter Clausen
2012-09-15  9:10 ` [PATCH 1/4] iio: consumer.h: Fix kernel doc incosistency Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).