linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/11] IIO: Add core support for _available interfaces
@ 2013-11-17 15:14 Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 01/11] iio:core: add a callback to allow drivers to provide _available attributes Jonathan Cameron
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Dear All,

Firstly this is an RFC rather than a final proposal for a couple of reasons
1) Others may have better idea of the the interface, particularly wrt to te
   range attributes (we are restricted by existing userspace interface for
   the list of available options one).
2) I've only converted a small number of drivers and honestly I suspect I've
   broken some of them trying to avoid multiple coppies of the same data.
3) The range version isn't documented yet.

In brief what I propose here has come up a few times in the depths of random
driver reviews: An interface to tell the subsystem what values are possible
for a given info_mask element.  This is then exported to userspace with the
same interface as was being used by the 'custom' attributes previously deployed
to indicate this stuff.  It is importantly also available to inkernel
consumers of the IIO channels.

There are two forms:

1. The conventional list of values.  A flat array is provided by the driver
with either one element (IIO_VAL_INT) or two (IIO_VAL_INT_PLUS etc) per value.
Note this array must be constant at the time of passing to ensure no race
conditions occur.

2. A new range approach. The format for this is open to discussion.
In this proposal 3 (single or pairs of) values are provided in a flat array.
These provide inclusive end markers and a step size between them.
Thus [0..1..3] is the equivalent of 0 1 2 3.

I would envision that many more of our info_mask elements will have
_available attributes than currently, many of which will make use of this
second interface.

The actual conversions of drivers is only painful in the 'clever' common
library ones.  The solution proposed here for the AD_SD drivers is clunky
but I can't immediately see how to do things in a cleaner fashion.

Anyhow, all comments welcome!  Whilst I think we need an interface
to provide this functionality, I am far from fixed on this necessarily
being the right way to do it.  It's just the best one I've thought up
yet.

Jonathan

Jonathan Cameron (11):
  iio:core: add a callback to allow drivers to provide _available
    attributes
  staging:iio:dummy driver: Add example usecases for the new *_available
    interface.
  iio:accel:bma180 use new read_avail to replace *_available attrs.
  iio:accel:kxsd9 use new read_avail to replace accel_scan_available.
  iio:st sensors: remove custom sampling frequence attribute in favour
    of core support.
  iio: ad_sigma_delta provide macro parameters for available info masks
  iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all.
  iio:adc:ad7793: Use the read_avail callback to provide the scale and
    sampling frequency interfaces.
  iio:adc:ad7791 Provide sampling frequency and scale_available access
    via core.
  staging:iio:adc:ad7192 use infomask* to provide access to sampling
    frequency and scale_available
  iio:adc:mcp3422: use core to provide _available information rather
    than custom attrs.

 drivers/iio/accel/bma180.c                      |  61 +++---
 drivers/iio/accel/kxsd9.c                       |  52 ++---
 drivers/iio/accel/st_accel_core.c               |  12 +-
 drivers/iio/adc/ad7791.c                        | 106 ++++-----
 drivers/iio/adc/ad7793.c                        | 275 ++++++++++++------------
 drivers/iio/adc/mcp3422.c                       |  72 ++++---
 drivers/iio/common/st_sensors/st_sensors_core.c |  29 ---
 drivers/iio/gyro/st_gyro_core.c                 |  12 +-
 drivers/iio/industrialio-core.c                 | 209 ++++++++++++++++--
 drivers/iio/magnetometer/st_magn_core.c         |  12 +-
 drivers/iio/pressure/st_pressure_core.c         |  27 ++-
 drivers/staging/iio/adc/ad7192.c                | 166 ++++++--------
 drivers/staging/iio/adc/ad7780.c                |   2 +-
 drivers/staging/iio/iio_simple_dummy.c          |  29 ++-
 include/linux/iio/adc/ad_sigma_delta.h          |  47 +++-
 include/linux/iio/common/st_sensors.h           |  15 +-
 include/linux/iio/iio.h                         |  11 +
 include/linux/iio/types.h                       |   5 +
 18 files changed, 696 insertions(+), 446 deletions(-)

-- 
1.8.4.2


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

* [PATCH 01/11] iio:core: add a callback to allow drivers to provide _available attributes
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 02/11] staging:iio:dummy driver: Add example usecases for the new *_available interface Jonathan Cameron
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

A large number of attributes can only take a limited range of values.
Currently in IIO this is handled by directly registering additional
*_available attributes thus providing this information to userspace.

It is desirable to provide this information via the core for much the same
reason this was done for the actual channel information attributes in the
first place.  If it isn't there, then it can only really be accessed from
userspace.  Other in kernel IIO consumers have no access to what valid
parameters are.

Two forms are currently supported:
* list of values in one particular IIO_VAL_* format.
	e.g. 1.300000 1.500000 1.730000
* range specification with a step size:
	e.g. [1.000000 0.500000 2.500000]
	equivalent to 1.000000 1.5000000 2.000000 2.500000

An addition set of masks are used to allow different sharing rules for the
*_available attributes generated.

This allows for example:

in_accel_x_offset
in_accel_y_offset
in_accel_offset_available.

We could have gone with having a specification for each and every
info_mask element but that would have meant changing the existing userspace
ABI.  This approach does not.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/industrialio-core.c | 209 +++++++++++++++++++++++++++++++++++++---
 include/linux/iio/iio.h         |  11 +++
 include/linux/iio/types.h       |   5 +
 3 files changed, 209 insertions(+), 16 deletions(-)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 2fe88c189f74..a0466f3dd2c8 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -367,50 +367,58 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 }
 EXPORT_SYMBOL_GPL(iio_enum_write);
 
-/**
- * iio_format_value() - Formats a IIO value into its string representation
- * @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.
- */
-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 val, int val2)
 {
 	unsigned long long tmp;
 	bool scale_db = false;
 
 	switch (type) {
 	case IIO_VAL_INT:
-		return sprintf(buf, "%d\n", val);
+		return sprintf(buf, "%d", val);
 	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,
+			return sprintf(buf, "-%ld.%06u%s", abs(val), -val2,
 				scale_db ? " dB" : "");
 		else
-			return sprintf(buf, "%d.%06u%s\n", val, val2,
+			return sprintf(buf, "%d.%06u%s", val, val2,
 				scale_db ? " dB" : "");
 	case IIO_VAL_INT_PLUS_NANO:
 		if (val2 < 0)
-			return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
+			return sprintf(buf, "-%ld.%09u", abs(val), -val2);
 		else
-			return sprintf(buf, "%d.%09u\n", val, val2);
+			return sprintf(buf, "%d.%09u", 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);
+		return sprintf(buf, "%d.%09u", val, val2);
 	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);
+		return sprintf(buf, "%d.%09u", val, val2);
 	default:
 		return 0;
 	}
 }
+/**
+ * iio_format_value() - Formats a IIO value into its string representation
+ * @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.
+ */
+ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2)
+{
+	ssize_t len;
+
+	len = __iio_format_value(buf, type, val, val2);
+
+	return len + sprintf(buf + len, "\n");
+}
 
 static ssize_t iio_read_channel_info(struct device *dev,
 				     struct device_attribute *attr,
@@ -428,6 +436,111 @@ static ssize_t iio_read_channel_info(struct device *dev,
 	return iio_format_value(buf, ret, val, val2);
 }
 
+static ssize_t iio_format_avail_list(char *buf, const int *vals, int type, int length)
+{
+	int i;
+	ssize_t len = 0;
+	switch (type) {
+	case IIO_VAL_INT:
+		for (i = 0; i < length; i++) {
+			len += __iio_format_value(buf + len, type, vals[i], 0);
+			if (i < length - 1)
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						" ");
+			else
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						"\n");
+		}
+		break;
+	default:
+		for (i = 0; i < length / 2; i++) {
+			len += __iio_format_value(buf + len,
+						  type,
+						  vals[i * 2],
+						  vals[i * 2 + 1]);
+			if (i < length / 2 - 1)
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						" ");
+			else
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						"\n");
+		}
+	};
+
+	return len;
+}
+
+static ssize_t iio_format_avail_range(char *buf, const int *vals, int type)
+{
+	int i;
+	ssize_t len;
+
+	len = snprintf(buf, PAGE_SIZE, "[");
+	switch (type) {
+	case IIO_VAL_INT:
+		for (i = 0; i < 3; i++) {
+			len += __iio_format_value(buf + len, type, vals[i], 0);
+			if (i < 2)
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						" ");
+			else
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						"]\n");
+		}
+		break;
+	default:
+		for (i = 0; i < 3; i++) {
+			len += __iio_format_value(buf + len,
+						  type,
+						  vals[i * 2],
+						  vals[i * 2 + 1]);
+			if (i < 2)
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						" ");
+			else
+				len += snprintf(buf + len,
+						PAGE_SIZE - len,
+						"]\n");
+		}
+	};
+
+	return len;
+}
+
+static ssize_t iio_read_channel_info_avail(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	const int *vals;
+	int ret;
+	int length;
+	int type;
+
+	ret = indio_dev->info->read_avail(indio_dev, this_attr->c,
+					  &vals, &type, &length,
+					  this_attr->address);
+
+	if (ret < 0)
+		return ret;
+	switch (ret) {
+	case IIO_AVAIL_LIST:
+		return iio_format_avail_list(buf, vals, type, length);
+	case IIO_AVAIL_RANGE:
+		return iio_format_avail_range(buf, vals, type);
+	default:
+		return -EINVAL;
+	}
+}
+
 /**
  * iio_str_to_fixpoint() - Parse a fixed-point number from a string
  * @str: The string to parse
@@ -749,6 +862,40 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
 	return attrcount;
 }
 
+static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev,
+					       struct iio_chan_spec const *chan,
+					       enum iio_shared_by shared_by,
+					       const long *infomask)
+{
+	int i, ret, attrcount = 0;
+	char *avail_postfix;
+
+	for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+		avail_postfix = kasprintf(GFP_KERNEL,
+					  "%s_available",
+					  iio_chan_info_postfix[i]);
+		if (avail_postfix == NULL)
+			return -ENOMEM;
+
+		ret = __iio_add_chan_devattr(avail_postfix,
+					     chan,
+					     &iio_read_channel_info_avail,
+					     NULL,
+					     i,
+					     shared_by,
+					     &indio_dev->dev,
+					     &indio_dev->channel_attr_list);
+		kfree(avail_postfix);
+		if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
+			continue;
+		else if (ret < 0)
+			return ret;
+		attrcount++;
+	}
+
+	return attrcount;
+}
+
 static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
 					struct iio_chan_spec const *chan)
 {
@@ -764,6 +911,14 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
 		return ret;
 	attrcount += ret;
 
+	ret = iio_device_add_info_mask_type_avail(indio_dev, chan,
+						  IIO_SEPARATE,
+						  &chan->
+						  info_mask_separate_available);
+	if (ret < 0)
+		return ret;
+	attrcount += ret;
+
 	ret = iio_device_add_info_mask_type(indio_dev, chan,
 					    IIO_SHARED_BY_TYPE,
 					    &chan->info_mask_shared_by_type);
@@ -771,6 +926,14 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
 		return ret;
 	attrcount += ret;
 
+	ret = iio_device_add_info_mask_type_avail(indio_dev, chan,
+						  IIO_SHARED_BY_TYPE,
+						  &chan->
+						  info_mask_shared_by_type_available);
+	if (ret < 0)
+		return ret;
+	attrcount += ret;
+
 	ret = iio_device_add_info_mask_type(indio_dev, chan,
 					    IIO_SHARED_BY_DIR,
 					    &chan->info_mask_shared_by_dir);
@@ -778,6 +941,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
 		return ret;
 	attrcount += ret;
 
+	ret = iio_device_add_info_mask_type_avail(indio_dev, chan,
+						  IIO_SHARED_BY_DIR,
+						  &chan->info_mask_shared_by_dir_available);
+	if (ret < 0)
+		return ret;
+	attrcount += ret;
+
 	ret = iio_device_add_info_mask_type(indio_dev, chan,
 					    IIO_SHARED_BY_ALL,
 					    &chan->info_mask_shared_by_all);
@@ -785,6 +955,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
 		return ret;
 	attrcount += ret;
 
+	ret = iio_device_add_info_mask_type_avail(indio_dev, chan,
+						  IIO_SHARED_BY_ALL,
+						  &chan->info_mask_shared_by_all_available);
+	if (ret < 0)
+		return ret;
+	attrcount += ret;
+
 	if (chan->ext_info) {
 		unsigned int i = 0;
 		for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 5b125fd554e4..6ce897840a2b 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -223,9 +223,13 @@ struct iio_chan_spec {
 		enum iio_endian endianness;
 	} scan_type;
 	long			info_mask_separate;
+	long			info_mask_separate_available;
 	long			info_mask_shared_by_type;
+	long			info_mask_shared_by_type_available;
 	long			info_mask_shared_by_dir;
+	long			info_mask_shared_by_dir_available;
 	long			info_mask_shared_by_all;
+	long			info_mask_shared_by_all_available;
 	long			event_mask;
 	const struct iio_event_spec *event_spec;
 	unsigned int		num_event_specs;
@@ -334,6 +338,13 @@ struct iio_info {
 			int *val2,
 			long mask);
 
+	int (*read_avail)(struct iio_dev *indio_dev,
+			  struct iio_chan_spec const *chan,
+			  const int **vals,
+			  int *type,
+			  int *length,
+			  long mask_el);
+
 	int (*write_raw)(struct iio_dev *indio_dev,
 			 struct iio_chan_spec const *chan,
 			 int val,
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 4ac928ee31c5..766659dea679 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -81,4 +81,9 @@ enum iio_event_direction {
 #define IIO_VAL_FRACTIONAL 10
 #define IIO_VAL_FRACTIONAL_LOG2 11
 
+enum iio_available_type {
+  IIO_AVAIL_LIST,
+  IIO_AVAIL_RANGE,
+};
+
 #endif /* _IIO_TYPES_H_ */
-- 
1.8.4.2


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

* [PATCH 02/11] staging:iio:dummy driver: Add example usecases for the new *_available interface.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 01/11] iio:core: add a callback to allow drivers to provide _available attributes Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 03/11] iio:accel:bma180 use new read_avail to replace *_available attrs Jonathan Cameron
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/staging/iio/iio_simple_dummy.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index 1fac9894b18c..8697bdcedf07 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -84,6 +84,9 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 		/* Channel has a numeric index of 0 */
 		.indexed = 1,
 		.channel = 0,
+		.info_mask_separate_available =
+		BIT(IIO_CHAN_INFO_RAW) |
+		BIT(IIO_CHAN_INFO_OFFSET),
 		/* What other information is available? */
 		.info_mask_separate =
 		/*
@@ -304,7 +307,30 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
 	mutex_unlock(&st->lock);
 	return ret;
 }
-
+static const int test_avail_list[] = { 0, 1, 1, 0, 3, 3000 };
+
+static int iio_dummy_read_avail(struct iio_dev *indio_dev,
+				struct iio_chan_spec const *chan,
+				const int **vals,
+				int *type,
+				int *length,
+				long mask_el)
+{
+	switch (mask_el) {
+	case IIO_CHAN_INFO_RAW:
+		*length = ARRAY_SIZE(test_avail_list);
+		*vals = test_avail_list;
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_OFFSET:
+		*length = ARRAY_SIZE(test_avail_list);
+		*vals = test_avail_list;
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_RANGE;
+	default:
+		return -EINVAL;
+	}
+}
 /**
  * iio_dummy_write_raw() - data write function.
  * @indio_dev:	the struct iio_dev associated with this device instance
@@ -368,6 +394,7 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
 static const struct iio_info iio_dummy_info = {
 	.driver_module = THIS_MODULE,
 	.read_raw = &iio_dummy_read_raw,
+	.read_avail = &iio_dummy_read_avail,
 	.write_raw = &iio_dummy_write_raw,
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
 	.read_event_config_new = &iio_simple_dummy_read_event_config,
-- 
1.8.4.2

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

* [PATCH 03/11] iio:accel:bma180 use new read_avail to replace *_available attrs.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 01/11] iio:core: add a callback to allow drivers to provide _available attributes Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 02/11] staging:iio:dummy driver: Add example usecases for the new *_available interface Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 04/11] iio:accel:kxsd9 use new read_avail to replace accel_scan_available Jonathan Cameron
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

This allows access to all of these parameters via the core.
Patch also adds const to the two value arrays specifying the available
values.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/accel/bma180.c | 61 +++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 25 deletions(-)

diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 28b39283bccf..5c66f62d6f67 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -70,12 +70,6 @@
 #define BMA180_DEF_BW		20
 #define BMA180_DEF_SCALE	250
 
-/* Available values for sysfs */
-#define BMA180_FLP_FREQ_AVAILABLE \
-	"10 20 40 75 150 300"
-#define BMA180_SCALE_AVAILABLE \
-	"0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
-
 struct bma180_data {
 	struct i2c_client *client;
 	struct iio_trigger *trig;
@@ -93,8 +87,37 @@ enum bma180_axis {
 	AXIS_Z,
 };
 
-static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
-static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
+static const int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
+static const int scale_table[] = { 0, 130,
+				   0, 190,
+				   0, 250,
+				   0, 380,
+				   0, 500,
+				   0, 990,
+				   0, 1980 };
+
+static int bma180_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals,
+			     int *type,
+			     int *length,
+			     long mask_el)
+{
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*length = ARRAY_SIZE(bw_table);
+		*vals = bw_table;
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+		*length = ARRAY_SIZE(scale_table);
+		*vals = scale_table;
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
 
 static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
 {
@@ -209,8 +232,8 @@ static int bma180_set_scale(struct bma180_data *data, int val)
 	if (data->sleep_state)
 		return -EBUSY;
 
-	for (i = 0; i < ARRAY_SIZE(scale_table); ++i)
-		if (scale_table[i] == val) {
+	for (i = 0; i < ARRAY_SIZE(scale_table) / 2; ++i)
+		if (scale_table[i * 2 + 1] == val) {
 			ret = bma180_set_bits(data,
 					BMA180_OFFSET_LSB1, BMA180_RANGE, i);
 			if (ret) {
@@ -316,20 +339,6 @@ err:
 	dev_err(&data->client->dev, "failed to disable the chip\n");
 }
 
-static IIO_CONST_ATTR(in_accel_filter_low_pass_3db_frequency_available,
-		BMA180_FLP_FREQ_AVAILABLE);
-static IIO_CONST_ATTR(in_accel_scale_available, BMA180_SCALE_AVAILABLE);
-
-static struct attribute *bma180_attributes[] = {
-	&iio_const_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
-	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group bma180_attrs_group = {
-	.attrs = bma180_attributes,
-};
-
 static int bma180_read_raw(struct iio_dev *indio_dev,
 		struct iio_chan_spec const *chan, int *val, int *val2,
 		long mask)
@@ -401,8 +410,8 @@ static int bma180_update_scan_mode(struct iio_dev *indio_dev,
 }
 
 static const struct iio_info bma180_info = {
-	.attrs			= &bma180_attrs_group,
 	.read_raw		= bma180_read_raw,
+	.read_avail		= bma180_read_avail,
 	.write_raw		= bma180_write_raw,
 	.update_scan_mode	= bma180_update_scan_mode,
 	.driver_module		= THIS_MODULE,
@@ -454,6 +463,8 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
 		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
+	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) | \
+		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), 	\
 	.scan_index = (_index),						\
 	.scan_type = IIO_ST('s', 14, 16, 2),				\
 	.ext_info = bma180_ext_info,					\
-- 
1.8.4.2


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

* [PATCH 04/11] iio:accel:kxsd9 use new read_avail to replace accel_scan_available.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (2 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 03/11] iio:accel:bma180 use new read_avail to replace *_available attrs Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support Jonathan Cameron
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Note that there is a small abi change in here as we will gain an in_
prefix on the accel_scan_available.  We have tightened the abi in recent
times so that the in_ prefix is no the standard thing to do.

This change is probably in the if no one notices, it doesn't count as
breakage category.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/accel/kxsd9.c | 52 ++++++++++++++++++++++++-----------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index d72118d1189c..d99601f4219b 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -57,13 +57,28 @@ struct kxsd9_state {
 	u8 tx[KXSD9_STATE_TX_SIZE];
 };
 
-#define KXSD9_SCALE_2G "0.011978"
-#define KXSD9_SCALE_4G "0.023927"
-#define KXSD9_SCALE_6G "0.035934"
-#define KXSD9_SCALE_8G "0.047853"
-
-/* reverse order */
-static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
+static const int kxsd9_scales[] = { 0, 11978,
+				    0, 23927,
+				    0, 35934,
+				    0, 47853 };
+
+static int kxsd9_read_avail(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    const int **vals,
+			    int *type,
+			    int *length,
+			    long mask_el)
+{
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SCALE:
+		*length = ARRAY_SIZE(kxsd9_scales);
+		*vals = kxsd9_scales;
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
 
 static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
 {
@@ -72,7 +87,7 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
 	bool foundit = false;
 
 	for (i = 0; i < 4; i++)
-		if (micro == kxsd9_micro_scales[i]) {
+		if (micro == kxsd9_scales[ (3 - i) * 2 + 1]) {
 			foundit = true;
 			break;
 		}
@@ -117,17 +132,6 @@ static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
 	return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
 }
 
-static IIO_CONST_ATTR(accel_scale_available,
-		KXSD9_SCALE_2G " "
-		KXSD9_SCALE_4G " "
-		KXSD9_SCALE_6G " "
-		KXSD9_SCALE_8G);
-
-static struct attribute *kxsd9_attributes[] = {
-	&iio_const_attr_accel_scale_available.dev_attr.attr,
-	NULL,
-};
-
 static int kxsd9_write_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan,
 			   int val,
@@ -164,7 +168,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
 		ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
 		if (ret)
 			goto error_ret;
-		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
+		*val2 = kxsd9_scales[(3 - (ret & KXSD9_FS_MASK))* 2 + 1];
 		ret = IIO_VAL_INT_PLUS_MICRO;
 		break;
 	}
@@ -179,6 +183,8 @@ error_ret:
 		.channel2 = IIO_MOD_##axis,				\
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+		.info_mask_shared_by_type_available =			\
+			BIT(IIO_CHAN_INFO_SCALE),			\
 		.address = KXSD9_REG_##axis,				\
 	}
 
@@ -192,10 +198,6 @@ static const struct iio_chan_spec kxsd9_channels[] = {
 	}
 };
 
-static const struct attribute_group kxsd9_attribute_group = {
-	.attrs = kxsd9_attributes,
-};
-
 static int kxsd9_power_up(struct kxsd9_state *st)
 {
 	int ret;
@@ -213,8 +215,8 @@ static int kxsd9_power_up(struct kxsd9_state *st)
 
 static const struct iio_info kxsd9_info = {
 	.read_raw = &kxsd9_read_raw,
+	.read_avail = &kxsd9_read_avail,
 	.write_raw = &kxsd9_write_raw,
-	.attrs = &kxsd9_attribute_group,
 	.driver_module = THIS_MODULE,
 };
 
-- 
1.8.4.2


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

* [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (3 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 04/11] iio:accel:kxsd9 use new read_avail to replace accel_scan_available Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-18 18:25   ` Lars-Peter Clausen
  2013-11-17 15:14 ` [PATCH 06/11] iio: ad_sigma_delta provide macro parameters for available info masks Jonathan Cameron
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

This allows in kernel client drivers to access this

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/accel/st_accel_core.c               | 12 ++++++++--
 drivers/iio/common/st_sensors/st_sensors_core.c | 29 -------------------------
 drivers/iio/gyro/st_gyro_core.c                 | 12 ++++++++--
 drivers/iio/magnetometer/st_magn_core.c         | 12 ++++++++--
 drivers/iio/pressure/st_pressure_core.c         | 27 +++++++++++++++++++++--
 include/linux/iio/common/st_sensors.h           | 15 +++++--------
 6 files changed, 61 insertions(+), 46 deletions(-)

diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 38caedc76b98..237d85142ad8 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -393,6 +393,9 @@ static int st_accel_read_raw(struct iio_dev *indio_dev,
 		*val = 0;
 		*val2 = adata->current_fullscale->gain;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = adata->odr;
+		return IIO_VAL_INT;
 	default:
 		return -EINVAL;
 	}
@@ -410,6 +413,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SCALE:
 		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val2)
+			return -EINVAL;
+		mutex_lock(&indio_dev->mlock);
+		err = st_sensors_set_odr(indio_dev, val);
+		mutex_unlock(&indio_dev->mlock);
+		return err;
 	default:
 		return -EINVAL;
 	}
@@ -417,14 +427,12 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
 	return err;
 }
 
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
 
 static struct attribute *st_accel_attributes[] = {
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	NULL,
 };
 
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 7ba1ef270213..890bdc83cafb 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -426,35 +426,6 @@ read_wai_error:
 }
 EXPORT_SYMBOL(st_sensors_check_device_support);
 
-ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct st_sensor_data *adata = iio_priv(dev_get_drvdata(dev));
-
-	return sprintf(buf, "%d\n", adata->odr);
-}
-EXPORT_SYMBOL(st_sensors_sysfs_get_sampling_frequency);
-
-ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	int err;
-	unsigned int odr;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
-	err = kstrtoint(buf, 10, &odr);
-	if (err < 0)
-		goto conversion_error;
-
-	mutex_lock(&indio_dev->mlock);
-	err = st_sensors_set_odr(indio_dev, odr);
-	mutex_unlock(&indio_dev->mlock);
-
-conversion_error:
-	return err < 0 ? err : size;
-}
-EXPORT_SYMBOL(st_sensors_sysfs_set_sampling_frequency);
-
 ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index d53d91adfb55..fc9f449a342a 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -246,6 +246,9 @@ static int st_gyro_read_raw(struct iio_dev *indio_dev,
 		*val = 0;
 		*val2 = gdata->current_fullscale->gain;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = gdata->odr;
+		return IIO_VAL_INT;
 	default:
 		return -EINVAL;
 	}
@@ -263,6 +266,13 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SCALE:
 		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val2)
+			return -EINVAL;
+		mutex_lock(&indio_dev->mlock);
+		err = st_sensors_set_odr(indio_dev, val);
+		mutex_unlock(&indio_dev->mlock);
+		return err;
 	default:
 		err = -EINVAL;
 	}
@@ -270,14 +280,12 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
 	return err;
 }
 
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
 
 static struct attribute *st_gyro_attributes[] = {
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	NULL,
 };
 
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index 52bbcfa1e077..34fc1a70a974 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -299,6 +299,9 @@ static int st_magn_read_raw(struct iio_dev *indio_dev,
 		else
 			*val2 = mdata->current_fullscale->gain;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = mdata->odr;
+		return IIO_VAL_INT;
 	default:
 		return -EINVAL;
 	}
@@ -316,6 +319,13 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SCALE:
 		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val2)
+			return -EINVAL;
+		mutex_lock(&indio_dev->mlock);
+		err = st_sensors_set_odr(indio_dev, val);
+		mutex_unlock(&indio_dev->mlock);
+		return err;
 	default:
 		err = -EINVAL;
 	}
@@ -323,14 +333,12 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
 	return err;
 }
 
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
 
 static struct attribute *st_magn_attributes[] = {
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_in_magn_scale_available.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	NULL,
 };
 
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index 58083f9d51c5..a6d2855cefb0 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -235,6 +235,27 @@ static const struct st_sensors st_press_sensors[] = {
 	},
 };
 
+static int st_press_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *ch,
+			      int val,
+			      int val2,
+			      long mask)
+{
+	int err;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val2)
+			return -EINVAL;
+		mutex_lock(&indio_dev->mlock);
+		err = st_sensors_set_odr(indio_dev, val);
+		mutex_unlock(&indio_dev->mlock);
+		return err;
+	default:
+		return -EINVAL;
+	}
+}
+
 static int st_press_read_raw(struct iio_dev *indio_dev,
 			struct iio_chan_spec const *ch, int *val,
 							int *val2, long mask)
@@ -277,6 +298,9 @@ static int st_press_read_raw(struct iio_dev *indio_dev,
 		}
 
 		return IIO_VAL_FRACTIONAL;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = pdata->odr;
+		return IIO_VAL_INT;
 	default:
 		return -EINVAL;
 	}
@@ -285,12 +309,10 @@ read_error:
 	return err;
 }
 
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 
 static struct attribute *st_press_attributes[] = {
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	NULL,
 };
 
@@ -302,6 +324,7 @@ static const struct iio_info press_info = {
 	.driver_module = THIS_MODULE,
 	.attrs = &st_press_attribute_group,
 	.read_raw = &st_press_read_raw,
+	.write_raw = &st_press_write_raw,
 };
 
 #ifdef CONFIG_IIO_TRIGGER
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 3c005eb3a0a4..ffcd1f2b96c9 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -47,6 +47,7 @@
 	.type = device_type, \
 	.modified = mod, \
 	.info_mask_separate = mask, \
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
 	.scan_index = index, \
 	.channel2 = ch2, \
 	.address = addr, \
@@ -59,11 +60,6 @@
 	}, \
 }
 
-#define ST_SENSOR_DEV_ATTR_SAMP_FREQ() \
-		IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, \
-			st_sensors_sysfs_get_sampling_frequency, \
-			st_sensors_sysfs_set_sampling_frequency)
-
 #define ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL() \
 		IIO_DEV_ATTR_SAMP_FREQ_AVAIL( \
 			st_sensors_sysfs_sampling_frequency_avail)
@@ -281,11 +277,12 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
 int st_sensors_check_device_support(struct iio_dev *indio_dev,
 			int num_sensors_list, const struct st_sensors *sensors);
 
-ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
-				struct device_attribute *attr, char *buf);
+int st_sensors_get_sampling_frequency(struct iio_dev *indio_dev,
+				      int *val,
+				      int *val2);
 
-ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size);
+int st_sensors_set_sampling_frequency(struct iio_dev *indio_dev, int *val,
+				      int *val2);
 
 ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
 				struct device_attribute *attr, char *buf);
-- 
1.8.4.2


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

* [PATCH 06/11] iio: ad_sigma_delta provide macro parameters for available info masks
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (4 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:14 ` [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all Jonathan Cameron
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

For now all are set to 0 to allow the drivers to undergo conversion
one at a time.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/ad7791.c               | 14 +++----
 drivers/iio/adc/ad7793.c               | 69 ++++++++++++++++++++++------------
 drivers/staging/iio/adc/ad7192.c       | 16 ++++----
 drivers/staging/iio/adc/ad7780.c       |  2 +-
 include/linux/iio/adc/ad_sigma_delta.h | 47 +++++++++++++++++------
 5 files changed, 97 insertions(+), 51 deletions(-)

diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c
index c19f8fd1b4b7..a5abc1c2453e 100644
--- a/drivers/iio/adc/ad7791.c
+++ b/drivers/iio/adc/ad7791.c
@@ -68,23 +68,23 @@
 #define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
-		(bits), (storagebits), 0), \
-	AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
+	AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0, 0, 0, 0), \
 	AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \
-		(bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
 	AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR,  \
-		(bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
-		(bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
 	AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \
-		(bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
 	AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \
-		(bits), (storagebits), 0), \
+		(bits), (storagebits), 0, 0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(3), \
 }
 
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 4dddeabdfbb0..0af42b693eb4 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -586,45 +586,66 @@ static const struct iio_info ad7797_info = {
 
 #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
 const struct iio_chan_spec _name##_channels[] = { \
-	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
-	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
-	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
-	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
-	AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
-	AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
+	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s), \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s), \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s), \
+	0, 0, 0), \
+	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s), \
+	0, 0, 0), \
+	AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s), 0, 0, 0), \
+	AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s), \
+	0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(6), \
 }
 
 #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
-	AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-	AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
-	AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0, 0, 0, 0),	\
+	AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
+	0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(9), \
 }
 
 #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-	AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-	AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
-	AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0, 0, 0, 0),	\
+	AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
+	0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
-	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
-	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
-	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
-	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
+	0, 0, 0), \
+	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
+	0, 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(5), \
 }
 
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 83bb44b38152..75187fc8e4b4 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -595,14 +595,14 @@ static const struct iio_info ad7195_info = {
 };
 
 static const struct iio_chan_spec ad7192_channels[] = {
-	AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0),
-	AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0),
-	AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0),
-	AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0),
-	AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0),
-	AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0),
-	AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0),
-	AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0),
+	AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0, 0, 0, 0),
+	AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0, 0, 0, 0),
+	AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0, 0, 0, 0),
+	AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0, 0, 0, 0),
+	AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0, 0, 0, 0),
+	AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0, 0, 0, 0),
+	AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0, 0, 0, 0),
+	AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0, 0, 0, 0),
 	IIO_CHAN_SOFT_TIMESTAMP(8),
 };
 
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 273add3ed63f..f4827dfaec65 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -131,7 +131,7 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
 };
 
 #define AD7780_CHANNEL(bits, wordsize) \
-	AD_SD_CHANNEL(1, 0, 0, bits, 32, wordsize - bits)
+	AD_SD_CHANNEL(1, 0, 0, bits, 32, wordsize - bits, 0, 0, 0)
 
 static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
 	[ID_AD7170] = {
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h
index e7fdec4db9da..c19f4711a1e0 100644
--- a/include/linux/iio/adc/ad_sigma_delta.h
+++ b/include/linux/iio/adc/ad_sigma_delta.h
@@ -124,7 +124,9 @@ void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev);
 int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
 
 #define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-	_storagebits, _shift, _extend_name, _type) \
+	_storagebits, _shift, _extend_name, _type, \
+	_im_shared_by_all, \
+	_im_shared_all_av, _im_shared_type_av) \
 	{ \
 		.type = (_type), \
 		.differential = (_channel2 == -1 ? 0 : 1), \
@@ -136,6 +138,9 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 			BIT(IIO_CHAN_INFO_OFFSET), \
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+		.info_mask_shared_by_all = _im_shared_by_all, \
+		.info_mask_shared_by_all_available = _im_shared_all_av, \
+		.info_mask_shared_by_type_available = _im_shared_type_av, \
 		.scan_index = (_si), \
 		.scan_type = { \
 			.sign = 'u', \
@@ -147,27 +152,47 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
 	}
 
 #define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-	_storagebits, _shift) \
+	_storagebits, _shift, \
+	_shared_by_all, \
+	_shared_by_all_available, _shared_by_type_available)	\
 	__AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
-		_storagebits, _shift, NULL, IIO_VOLTAGE)
+		_storagebits, _shift, NULL, IIO_VOLTAGE, \
+		_shared_by_all, \
+		_shared_by_all_available, _shared_by_type_available)
 
 #define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
-	_storagebits, _shift) \
+	_storagebits, _shift, \
+	_shared_by_all, \
+	_shared_by_all_available, _shared_by_type_available) \
 	__AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \
-		_storagebits, _shift, "shorted", IIO_VOLTAGE)
+		_storagebits, _shift, "shorted", IIO_VOLTAGE, \
+		_shared_by_all, \
+		_shared_by_all_available, _shared_by_type_available)
 
 #define AD_SD_CHANNEL(_si, _channel, _address, _bits, \
-	_storagebits, _shift) \
+	_storagebits, _shift, \
+	_shared_by_all, \
+	_shared_by_all_available, _shared_by_type_available) \
 	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
-		_storagebits, _shift, NULL, IIO_VOLTAGE)
+		_storagebits, _shift, NULL, IIO_VOLTAGE, \
+		_shared_by_all, \
+		_shared_by_all_available, _shared_by_type_available)
 
-#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
+#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift, \
+	_shared_by_all, \
+	_shared_by_all_available, _shared_by_type_available) \
 	__AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \
-		_storagebits, _shift, NULL, IIO_TEMP)
+		_storagebits, _shift, NULL, IIO_TEMP, \
+		_shared_by_all, \
+		_shared_by_all_available, _shared_by_type_available)
 
 #define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
-	_shift) \
+	_shift, \
+	_shared_by_all, \
+	_shared_by_all_available, _shared_by_type_available) \
 	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
-		_storagebits, _shift, "supply", IIO_VOLTAGE)
+		_storagebits, _shift, "supply", IIO_VOLTAGE, \
+		_shared_by_all, \
+		_shared_by_all_available, _shared_by_type_available)
 
 #endif
-- 
1.8.4.2


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

* [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (5 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 06/11] iio: ad_sigma_delta provide macro parameters for available info masks Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-18 18:29   ` Lars-Peter Clausen
  2013-11-17 15:14 ` [PATCH 08/11] iio:adc:ad7793: Use the read_avail callback to provide the scale and sampling frequency interfaces Jonathan Cameron
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

This replaces the previous use of a custom attribute to create the same
interface.  One big advantage is that this allows in kernel access.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/ad7793.c | 124 +++++++++++++++++------------------------------
 1 file changed, 45 insertions(+), 79 deletions(-)

diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 0af42b693eb4..9fd85b0032a6 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -348,60 +348,7 @@ static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
 static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
 					33, 0, 17, 16, 12, 10, 8, 6, 4};
 
-static ssize_t ad7793_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7793_state *st = iio_priv(indio_dev);
-
-	return sprintf(buf, "%d\n",
-	       st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
-}
-
-static ssize_t ad7793_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7793_state *st = iio_priv(indio_dev);
-	long lval;
-	int i, ret;
-
-	mutex_lock(&indio_dev->mlock);
-	if (iio_buffer_enabled(indio_dev)) {
-		mutex_unlock(&indio_dev->mlock);
-		return -EBUSY;
-	}
-	mutex_unlock(&indio_dev->mlock);
 
-	ret = kstrtol(buf, 10, &lval);
-	if (ret)
-		return ret;
-
-	if (lval == 0)
-		return -EINVAL;
-
-	ret = -EINVAL;
-
-	for (i = 0; i < 16; i++)
-		if (lval == st->chip_info->sample_freq_avail[i]) {
-			mutex_lock(&indio_dev->mlock);
-			st->mode &= ~AD7793_MODE_RATE(-1);
-			st->mode |= AD7793_MODE_RATE(i);
-			ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
-					 sizeof(st->mode), st->mode);
-			mutex_unlock(&indio_dev->mlock);
-			ret = 0;
-		}
-
-	return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		ad7793_read_frequency,
-		ad7793_write_frequency);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
 	"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
@@ -430,7 +377,6 @@ static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
 		ad7793_show_scale_available, NULL, 0);
 
 static struct attribute *ad7793_attributes[] = {
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
 	NULL
@@ -441,7 +387,6 @@ static const struct attribute_group ad7793_attribute_group = {
 };
 
 static struct attribute *ad7797_attributes[] = {
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
 	NULL
 };
@@ -512,6 +457,10 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
 			*val -= offset;
 		}
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = st->chip_info->
+			sample_freq_avail[AD7793_MODE_RATE(st->mode)];
+		return IIO_VAL_INT;
 	}
 	return -EINVAL;
 }
@@ -551,6 +500,20 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
 				break;
 			}
 		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val == 0)
+			return -EINVAL;
+
+		ret = -EINVAL;
+		for (i = 0; i < 16; i++)
+			if (val == st->chip_info->sample_freq_avail[i]) {
+				st->mode &= ~AD7793_MODE_RATE(-1);
+				st->mode |= AD7793_MODE_RATE(i);
+				ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
+						sizeof(st->mode), st->mode);
+				ret = 0;
+			}
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -587,65 +550,68 @@ static const struct iio_info ad7797_info = {
 #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s), \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s), \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s), \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s), \
-	0, 0, 0), \
-	AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s), 0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s), \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(6), \
 }
 
 #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
-	AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0, 0, 0, 0),	\
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0, \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0),	\
 	AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(9), \
 }
 
 #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
-	AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0, 0, 0, 0),	\
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0, \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0),	\
 	AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	0, 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(5), \
 }
 
-- 
1.8.4.2


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

* [PATCH 08/11] iio:adc:ad7793: Use the read_avail callback to provide the scale and sampling frequency interfaces.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (6 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all Jonathan Cameron
@ 2013-11-17 15:14 ` Jonathan Cameron
  2013-11-17 15:15 ` [PATCH 09/11] iio:adc:ad7791 Provide sampling frequency and scale_available access via core Jonathan Cameron
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:14 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

This is preferred over the previous approach of custom attributes as
it allows in kernel access to these values.  This is useful for consumers
of IIO channels.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/ad7793.c | 178 ++++++++++++++++++++++++++---------------------
 1 file changed, 97 insertions(+), 81 deletions(-)

diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 9fd85b0032a6..a0ea25876059 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -157,8 +157,7 @@ struct ad7793_state {
 	u16				int_vref_mv;
 	u16				mode;
 	u16				conf;
-	u32				scale_avail[8][2];
-
+	int				scale_avail[16];
 	struct ad_sigma_delta		sd;
 
 };
@@ -326,14 +325,14 @@ static int ad7793_setup(struct iio_dev *indio_dev,
 		goto out;
 
 	/* Populate available ADC input ranges */
-	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
+	for (i = 0; i < ARRAY_SIZE(st->scale_avail) / 2; i++) {
 		scale_uv = ((u64)vref_mv * 100000000)
 			>> (st->chip_info->channels[0].scan_type.realbits -
 			(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
 		scale_uv >>= i;
 
-		st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
-		st->scale_avail[i][0] = scale_uv;
+		st->scale_avail[i * 2 + 1] = do_div(scale_uv, 100000000) * 10;
+		st->scale_avail[i * 2 + 0] = scale_uv;
 	}
 
 	return 0;
@@ -345,55 +344,16 @@ out:
 static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
 					33, 19, 17, 16, 12, 10, 8, 6, 4};
 
+static const int ad7793_sample_freq_avail_packed[] = { 470, 242, 123, 62,
+						       50, 39, 33, 19,
+						       17, 16, 12, 10,
+						       8, 6, 4};
+
 static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
 					33, 0, 17, 16, 12, 10, 8, 6, 4};
 
-
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
-	"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
-
-static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
-	sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
-
-static ssize_t ad7793_show_scale_available(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7793_state *st = iio_priv(indio_dev);
-	int i, len = 0;
-
-	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
-		len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0],
-			       st->scale_avail[i][1]);
-
-	len += sprintf(buf + len, "\n");
-
-	return len;
-}
-
-static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
-		in_voltage-voltage_scale_available, S_IRUGO,
-		ad7793_show_scale_available, NULL, 0);
-
-static struct attribute *ad7793_attributes[] = {
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group ad7793_attribute_group = {
-	.attrs = ad7793_attributes,
-};
-
-static struct attribute *ad7797_attributes[] = {
-	&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group ad7797_attribute_group = {
-	.attrs = ad7797_attributes,
-};
+static const int ad7797_sample_freq_avail_packed[] = {123, 62, 50,
+					33, 17, 16, 12, 10, 8, 6, 4};
 
 static int ad7793_read_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan,
@@ -419,9 +379,9 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
 		case IIO_VOLTAGE:
 			if (chan->differential) {
 				*val = st->
-					scale_avail[(st->conf >> 8) & 0x7][0];
+					scale_avail[((st->conf >> 8) & 0x7) * 2 + 0];
 				*val2 = st->
-					scale_avail[(st->conf >> 8) & 0x7][1];
+					scale_avail[((st->conf >> 8) & 0x7) * 2 + 1];
 				return IIO_VAL_INT_PLUS_NANO;
 			} else {
 				/* 1170mV / 2^23 * 6 */
@@ -484,8 +444,8 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
 	switch (mask) {
 	case IIO_CHAN_INFO_SCALE:
 		ret = -EINVAL;
-		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
-			if (val2 == st->scale_avail[i][1]) {
+		for (i = 0; i < ARRAY_SIZE(st->scale_avail) / 2; i++)
+			if (val2 == st->scale_avail[i * 2 + 1]) {
 				ret = 0;
 				tmp = st->conf;
 				st->conf &= ~AD7793_CONF_GAIN(-1);
@@ -529,20 +489,63 @@ static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
 	return IIO_VAL_INT_PLUS_NANO;
 }
 
+static int ad7793_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals,
+			     int *type,
+			     int *length,
+			     long mask_el)
+{
+	struct ad7793_state *st = iio_priv(indio_dev);
+
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*length = ARRAY_SIZE(ad7793_sample_freq_avail_packed);
+		*vals =  ad7793_sample_freq_avail_packed;
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_SCALE:
+		*length = 16;
+		*vals = st->scale_avail;
+		*type = IIO_VAL_INT_PLUS_NANO;
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad7797_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals,
+			     int *type,
+			     int *length,
+			     long mask_el)
+{
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*length = ARRAY_SIZE(ad7797_sample_freq_avail_packed);
+		*vals =  ad7797_sample_freq_avail_packed;
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct iio_info ad7793_info = {
 	.read_raw = &ad7793_read_raw,
+	.read_avail = &ad7793_read_avail,
 	.write_raw = &ad7793_write_raw,
 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
-	.attrs = &ad7793_attribute_group,
 	.validate_trigger = ad_sd_validate_trigger,
 	.driver_module = THIS_MODULE,
 };
 
 static const struct iio_info ad7797_info = {
 	.read_raw = &ad7793_read_raw,
+	.read_avail = &ad7797_read_avail,
 	.write_raw = &ad7793_write_raw,
 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
-	.attrs = &ad7793_attribute_group,
 	.validate_trigger = ad_sd_validate_trigger,
 	.driver_module = THIS_MODULE,
 };
@@ -550,68 +553,81 @@ static const struct iio_info ad7797_info = {
 #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s), \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(6), \
 }
 
 #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0),	\
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0),	\
 	AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(9), \
 }
 
+/* AD7797 is the only device not to provide scale_available */
 #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0),	\
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0),	\
 	AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
 const struct iio_chan_spec _name##_channels[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SCALE)), \
 	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
-	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
+	BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(5), \
 }
 
-- 
1.8.4.2


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

* [PATCH 09/11] iio:adc:ad7791 Provide sampling frequency and scale_available access via core.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (7 preceding siblings ...)
  2013-11-17 15:14 ` [PATCH 08/11] iio:adc:ad7793: Use the read_avail callback to provide the scale and sampling frequency interfaces Jonathan Cameron
@ 2013-11-17 15:15 ` Jonathan Cameron
  2013-11-17 15:15 ` [PATCH 10/11] staging:iio:adc:ad7192 use infomask* to provide access to sampling frequency and scale_available Jonathan Cameron
  2013-11-17 15:15 ` [PATCH 11/11] iio:adc:mcp3422: use core to provide _available information rather than custom attrs Jonathan Cameron
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:15 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Doing it this way instead of using custom attributes makes these elements
accessible to in kernel consumers of the IIO channels.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/ad7791.c | 106 ++++++++++++++++++++++++-----------------------
 1 file changed, 55 insertions(+), 51 deletions(-)

diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c
index a5abc1c2453e..a01c0bb8aa0d 100644
--- a/drivers/iio/adc/ad7791.c
+++ b/drivers/iio/adc/ad7791.c
@@ -68,23 +68,30 @@
 #define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
-		(bits), (storagebits), 0, 0, 0, 0), \
-	AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
+	AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \
-		(bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR,  \
-		(bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(4), \
 }
 
 #define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \
 const struct iio_chan_spec name[] = { \
 	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \
-		(bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \
-		(bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \
-		(bits), (storagebits), 0, 0, 0, 0), \
+		(bits), (storagebits), 0, \
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ), 0), \
 	IIO_CHAN_SOFT_TIMESTAMP(3), \
 }
 
@@ -197,10 +204,21 @@ static const struct ad_sigma_delta_info ad7791_sigma_delta_info = {
 	.read_mask = BIT(3),
 };
 
+static const int ad7791_samp_freqs[] = {
+       120, 0,
+       100, 0,
+       33, 300000,
+       20, 0,
+       16, 600000,
+       16, 700000,
+       13, 300000,
+       9, 500000 };
+
 static int ad7791_read_raw(struct iio_dev *indio_dev,
 	const struct iio_chan_spec *chan, int *val, int *val2, long info)
 {
 	struct ad7791_state *st = iio_priv(indio_dev);
+	unsigned int rate;
 	bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR);
 
 	switch (info) {
@@ -239,36 +257,19 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
 			*val2 = chan->scan_type.realbits - 1;
 
 		return IIO_VAL_FRACTIONAL_LOG2;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		rate = st->filter & AD7791_FILTER_RATE_MASK;
+		*val = ad7791_samp_freqs[2 * rate];
+		*val2 = ad7791_samp_freqs[2 * rate + 1];
+		return IIO_VAL_INT_PLUS_MICRO;
 	}
 
 	return -EINVAL;
 }
 
-static const char * const ad7791_sample_freq_avail[] = {
-	[AD7791_FILTER_RATE_120] = "120",
-	[AD7791_FILTER_RATE_100] = "100",
-	[AD7791_FILTER_RATE_33_3] = "33.3",
-	[AD7791_FILTER_RATE_20] = "20",
-	[AD7791_FILTER_RATE_16_6] = "16.6",
-	[AD7791_FILTER_RATE_16_7] = "16.7",
-	[AD7791_FILTER_RATE_13_3] = "13.3",
-	[AD7791_FILTER_RATE_9_5] = "9.5",
-};
-
-static ssize_t ad7791_read_frequency(struct device *dev,
-	struct device_attribute *attr, char *buf)
+static int ad7791_write_raw(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, int val, int val2, long info)
 {
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7791_state *st = iio_priv(indio_dev);
-	unsigned int rate = st->filter & AD7791_FILTER_RATE_MASK;
-
-	return sprintf(buf, "%s\n", ad7791_sample_freq_avail[rate]);
-}
-
-static ssize_t ad7791_write_frequency(struct device *dev,
-	struct device_attribute *attr, const char *buf, size_t len)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct ad7791_state *st = iio_priv(indio_dev);
 	int i, ret;
 
@@ -281,9 +282,9 @@ static ssize_t ad7791_write_frequency(struct device *dev,
 
 	ret = -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(ad7791_sample_freq_avail); i++) {
-		if (sysfs_streq(ad7791_sample_freq_avail[i], buf)) {
-
+	for (i = 0; i < ARRAY_SIZE(ad7791_samp_freqs) / 2; i++) {
+		if ((val == ad7791_samp_freqs[2 * i]) &&
+		    (val2 == ad7791_samp_freqs[2 * i + 1])) {
 			mutex_lock(&indio_dev->mlock);
 			st->filter &= ~AD7791_FILTER_RATE_MASK;
 			st->filter |= i;
@@ -295,28 +296,31 @@ static ssize_t ad7791_write_frequency(struct device *dev,
 		}
 	}
 
-	return ret ? ret : len;
+	return ret;
 }
 
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		ad7791_read_frequency,
-		ad7791_write_frequency);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("120 100 33.3 20 16.7 16.6 13.3 9.5");
-
-static struct attribute *ad7791_attributes[] = {
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group ad7791_attribute_group = {
-	.attrs = ad7791_attributes,
-};
+static int ad7791_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals,
+			     int *type,
+			     int *length,
+			     long mask_el)
+{
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*length = ARRAY_SIZE(ad7791_samp_freqs);
+		*vals =  ad7791_samp_freqs;
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
 
 static const struct iio_info ad7791_info = {
 	.read_raw = &ad7791_read_raw,
-	.attrs = &ad7791_attribute_group,
+	.read_avail = &ad7791_read_avail,
+	.write_raw = &ad7791_write_raw,
 	.validate_trigger = ad_sd_validate_trigger,
 	.driver_module = THIS_MODULE,
 };
-- 
1.8.4.2


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

* [PATCH 10/11] staging:iio:adc:ad7192 use infomask* to provide access to sampling frequency and scale_available
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (8 preceding siblings ...)
  2013-11-17 15:15 ` [PATCH 09/11] iio:adc:ad7791 Provide sampling frequency and scale_available access via core Jonathan Cameron
@ 2013-11-17 15:15 ` Jonathan Cameron
  2013-11-17 15:15 ` [PATCH 11/11] iio:adc:mcp3422: use core to provide _available information rather than custom attrs Jonathan Cameron
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:15 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Doing it this way rather than via custom attributes makes this information
available to in kernel consumers of the IIO channels.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/staging/iio/adc/ad7192.c | 166 ++++++++++++++++-----------------------
 1 file changed, 67 insertions(+), 99 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 75187fc8e4b4..804062aa64a0 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -142,7 +142,7 @@ struct ad7192_state {
 	u32				f_order;
 	u32				mode;
 	u32				conf;
-	u32				scale_avail[8][2];
+	u32				scale_avail[8 * 2];
 	u8				gpocon;
 	u8				devid;
 
@@ -289,14 +289,14 @@ static int ad7192_setup(struct ad7192_state *st,
 		goto out;
 
 	/* Populate available ADC input ranges */
-	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
+	for (i = 0; i < ARRAY_SIZE(st->scale_avail) / 2; i++) {
 		scale_uv = ((u64)st->int_vref_mv * 100000000)
 			>> (indio_dev->channels[0].scan_type.realbits -
 			((st->conf & AD7192_CONF_UNIPOLAR) ? 0 : 1));
 		scale_uv >>= i;
 
-		st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
-		st->scale_avail[i][0] = scale_uv;
+		st->scale_avail[i * 2 + 1] = do_div(scale_uv, 100000000) * 10;
+		st->scale_avail[i * 2 + 0] = scale_uv;
 	}
 
 	return 0;
@@ -305,82 +305,6 @@ out:
 	return ret;
 }
 
-static ssize_t ad7192_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7192_state *st = iio_priv(indio_dev);
-
-	return sprintf(buf, "%d\n", st->mclk /
-			(st->f_order * 1024 * AD7192_MODE_RATE(st->mode)));
-}
-
-static ssize_t ad7192_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7192_state *st = iio_priv(indio_dev);
-	unsigned long lval;
-	int div, ret;
-
-	ret = kstrtoul(buf, 10, &lval);
-	if (ret)
-		return ret;
-	if (lval == 0)
-		return -EINVAL;
-
-	mutex_lock(&indio_dev->mlock);
-	if (iio_buffer_enabled(indio_dev)) {
-		mutex_unlock(&indio_dev->mlock);
-		return -EBUSY;
-	}
-
-	div = st->mclk / (lval * st->f_order * 1024);
-	if (div < 1 || div > 1023) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	st->mode &= ~AD7192_MODE_RATE(-1);
-	st->mode |= AD7192_MODE_RATE(div);
-	ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
-
-out:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		ad7192_read_frequency,
-		ad7192_write_frequency);
-
-static ssize_t ad7192_show_scale_available(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7192_state *st = iio_priv(indio_dev);
-	int i, len = 0;
-
-	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
-		len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0],
-			       st->scale_avail[i][1]);
-
-	len += sprintf(buf + len, "\n");
-
-	return len;
-}
-
-static IIO_DEVICE_ATTR_NAMED(in_v_m_v_scale_available,
-			     in_voltage-voltage_scale_available,
-			     S_IRUGO, ad7192_show_scale_available, NULL, 0);
-
-static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
-		       ad7192_show_scale_available, NULL, 0);
-
 static ssize_t ad7192_show_ac_excitation(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -457,9 +381,6 @@ static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR,
 		       AD7192_REG_MODE);
 
 static struct attribute *ad7192_attributes[] = {
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
-	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
 	&iio_dev_attr_bridge_switch_en.dev_attr.attr,
 	&iio_dev_attr_ac_excitation_en.dev_attr.attr,
 	NULL
@@ -470,9 +391,6 @@ static const struct attribute_group ad7192_attribute_group = {
 };
 
 static struct attribute *ad7195_attributes[] = {
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
-	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
 	&iio_dev_attr_bridge_switch_en.dev_attr.attr,
 	NULL
 };
@@ -502,8 +420,8 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			mutex_lock(&indio_dev->mlock);
-			*val = st->scale_avail[AD7192_CONF_GAIN(st->conf)][0];
-			*val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf)][1];
+			*val = st->scale_avail[AD7192_CONF_GAIN(st->conf) * 2 + 0];
+			*val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf) * 2 + 1];
 			mutex_unlock(&indio_dev->mlock);
 			return IIO_VAL_INT_PLUS_NANO;
 		case IIO_TEMP:
@@ -522,11 +440,34 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
 		if (chan->type == IIO_TEMP)
 			*val -= 273 * ad7192_get_temp_scale(unipolar);
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val =  st->mclk /
+			(st->f_order * 1024 * AD7192_MODE_RATE(st->mode));
+		return IIO_VAL_INT;
 	}
 
 	return -EINVAL;
 }
 
+static int ad7192_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals,
+			     int *type,
+			     int *length,
+			     long mask_el)
+{
+	struct ad7192_state *st = iio_priv(indio_dev);
+
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SCALE:
+		*vals = st->scale_avail;
+		*length = ARRAY_SIZE(st->scale_avail);
+		*type = IIO_VAL_INT;
+		break;
+	}
+	return -EINVAL;
+}
+
 static int ad7192_write_raw(struct iio_dev *indio_dev,
 			       struct iio_chan_spec const *chan,
 			       int val,
@@ -534,7 +475,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
 			       long mask)
 {
 	struct ad7192_state *st = iio_priv(indio_dev);
-	int ret, i;
+	int ret, i, div;
 	unsigned int tmp;
 
 	mutex_lock(&indio_dev->mlock);
@@ -546,8 +487,8 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
 	switch (mask) {
 	case IIO_CHAN_INFO_SCALE:
 		ret = -EINVAL;
-		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
-			if (val2 == st->scale_avail[i][1]) {
+		for (i = 0; i < ARRAY_SIZE(st->scale_avail) / 2; i++)
+			if (val2 == st->scale_avail[i * 2 + 1]) {
 				ret = 0;
 				tmp = st->conf;
 				st->conf &= ~AD7192_CONF_GAIN(-1);
@@ -560,6 +501,23 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
 				break;
 			}
 		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val2 != 0) {
+			ret = -EINVAL;
+			break;
+		}
+		div = st->mclk / (val * st->f_order * 1024);
+		if (div < 1 || div > 1023) {
+			ret = -EINVAL;
+			break;
+		}
+
+		st->mode &= ~AD7192_MODE_RATE(-1);
+		st->mode |= AD7192_MODE_RATE(div);
+		ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
+		ret = 0;
+		break;
+		
 	default:
 		ret = -EINVAL;
 	}
@@ -578,6 +536,7 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
 
 static const struct iio_info ad7192_info = {
 	.read_raw = &ad7192_read_raw,
+	.read_avail = &ad7192_read_avail,
 	.write_raw = &ad7192_write_raw,
 	.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
 	.attrs = &ad7192_attribute_group,
@@ -587,6 +546,7 @@ static const struct iio_info ad7192_info = {
 
 static const struct iio_info ad7195_info = {
 	.read_raw = &ad7192_read_raw,
+	.read_avail = &ad7192_read_avail,
 	.write_raw = &ad7192_write_raw,
 	.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
 	.attrs = &ad7195_attribute_group,
@@ -595,14 +555,22 @@ static const struct iio_info ad7195_info = {
 };
 
 static const struct iio_chan_spec ad7192_channels[] = {
-	AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0, 0, 0, 0),
-	AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0, 0, 0, 0),
-	AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0, 0, 0, 0),
-	AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0, 0, 0, 0),
-	AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0, 0, 0, 0),
-	AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0, 0, 0, 0),
-	AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0, 0, 0, 0),
-	AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0, 0, 0, 0),
+	AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0, 
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0),
+	AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
+	AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, BIT(IIO_CHAN_INFO_SCALE)),
 	IIO_CHAN_SOFT_TIMESTAMP(8),
 };
 
-- 
1.8.4.2


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

* [PATCH 11/11] iio:adc:mcp3422: use core to provide _available information rather than custom attrs.
  2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
                   ` (9 preceding siblings ...)
  2013-11-17 15:15 ` [PATCH 10/11] staging:iio:adc:ad7192 use infomask* to provide access to sampling frequency and scale_available Jonathan Cameron
@ 2013-11-17 15:15 ` Jonathan Cameron
  10 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-17 15:15 UTC (permalink / raw)
  To: linux-iio; +Cc: lars, Jonathan Cameron

Passing this information through the new core callbacks makes it available
to in kernel consumers of the channels.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/mcp3422.c | 72 ++++++++++++++++++++++++-----------------------
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
index dbdbd77f69ea..1f627cce1029 100644
--- a/drivers/iio/adc/mcp3422.c
+++ b/drivers/iio/adc/mcp3422.c
@@ -55,6 +55,8 @@
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
 				| BIT(IIO_CHAN_INFO_SCALE), \
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+		.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
 	}
 
 /* LSB is in nV to eliminate floating point */
@@ -66,11 +68,11 @@ static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};
  *  pga is 1 for 0, 2
  */
 
-static const int mcp3422_scales[4][4] = {
-	{ 1000000, 250000, 62500, 15625 },
-	{ 500000 , 125000, 31250, 7812 },
-	{ 250000 , 62500 , 15625, 3906 },
-	{ 125000 , 31250 , 7812 , 1953 } };
+static const int mcp3422_scales[4][8] = {
+	{ 0, 1000000, 0, 250000, 0, 62500, 0, 15625 },
+	{ 0, 500000, 0, 125000, 0, 31250, 0, 7812 },
+	{ 0, 250000, 0, 62500, 0, 15625, 0, 3906 },
+	{ 0, 125000, 0, 31250, 0, 7812 , 0, 1953 } };
 
 /* Constant msleep times for data acquisitions */
 static const int mcp3422_read_times[4] = {
@@ -181,8 +183,8 @@ static int mcp3422_read_raw(struct iio_dev *iio,
 
 	case IIO_CHAN_INFO_SCALE:
 
-		*val1 = 0;
-		*val2 = mcp3422_scales[sample_rate][pga];
+		*val1 = mcp3422_scales[sample_rate][pga * 2 + 0];
+		*val2 = mcp3422_scales[sample_rate][pga * 2 + 1];
 		return IIO_VAL_INT_PLUS_NANO;
 
 	case IIO_CHAN_INFO_SAMP_FREQ:
@@ -196,6 +198,33 @@ static int mcp3422_read_raw(struct iio_dev *iio,
 	return -EINVAL;
 }
 
+static const int mcp3422_samp_freqs[] = { 240, 60, 15, 3 };
+static int mcp3422_read_avail(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      const int **vals,
+			      int *type,
+			      int *length,
+			      long mask_el)
+{
+	struct mcp3422 *adc = iio_priv(indio_dev);
+	u8 sample_rate;
+
+	switch (mask_el) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*vals = mcp3422_samp_freqs;
+		*length = ARRAY_SIZE(mcp3422_samp_freqs);
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_SCALE:
+		sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+		*vals = mcp3422_scales[sample_rate];
+		*length = ARRAY_SIZE(mcp3422_scales[0]);
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_LIST;
+	}
+	return -EINVAL;
+}
+
 static int mcp3422_write_raw(struct iio_dev *iio,
 			struct iio_chan_spec const *channel, int val1,
 			int val2, long mask)
@@ -271,33 +300,6 @@ static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev,
 	}
 }
 
-static ssize_t mcp3422_show_scales(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
-	u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
-
-	return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n",
-		mcp3422_scales[sample_rate][0],
-		mcp3422_scales[sample_rate][1],
-		mcp3422_scales[sample_rate][2],
-		mcp3422_scales[sample_rate][3]);
-}
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
-static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
-		mcp3422_show_scales, NULL, 0);
-
-static struct attribute *mcp3422_attributes[] = {
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group mcp3422_attribute_group = {
-	.attrs = mcp3422_attributes,
-};
-
 static const struct iio_chan_spec mcp3422_channels[] = {
 	MCP3422_CHAN(0),
 	MCP3422_CHAN(1),
@@ -312,9 +314,9 @@ static const struct iio_chan_spec mcp3424_channels[] = {
 
 static const struct iio_info mcp3422_info = {
 	.read_raw = mcp3422_read_raw,
+	.read_avail = mcp3422_read_avail,
 	.write_raw = mcp3422_write_raw,
 	.write_raw_get_fmt = mcp3422_write_raw_get_fmt,
-	.attrs = &mcp3422_attribute_group,
 	.driver_module = THIS_MODULE,
 };
 
-- 
1.8.4.2


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

* Re: [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support.
  2013-11-17 15:14 ` [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support Jonathan Cameron
@ 2013-11-18 18:25   ` Lars-Peter Clausen
  0 siblings, 0 replies; 15+ messages in thread
From: Lars-Peter Clausen @ 2013-11-18 18:25 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On 11/17/2013 04:14 PM, Jonathan Cameron wrote:
> This allows in kernel client drivers to access this

This one seems to be independent from the reset of the series and could
probably merged as-is.

> 
> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
> ---
>  drivers/iio/accel/st_accel_core.c               | 12 ++++++++--
>  drivers/iio/common/st_sensors/st_sensors_core.c | 29 -------------------------
>  drivers/iio/gyro/st_gyro_core.c                 | 12 ++++++++--
>  drivers/iio/magnetometer/st_magn_core.c         | 12 ++++++++--
>  drivers/iio/pressure/st_pressure_core.c         | 27 +++++++++++++++++++++--
>  include/linux/iio/common/st_sensors.h           | 15 +++++--------
>  6 files changed, 61 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
> index 38caedc76b98..237d85142ad8 100644
> --- a/drivers/iio/accel/st_accel_core.c
> +++ b/drivers/iio/accel/st_accel_core.c
> @@ -393,6 +393,9 @@ static int st_accel_read_raw(struct iio_dev *indio_dev,
>  		*val = 0;
>  		*val2 = adata->current_fullscale->gain;
>  		return IIO_VAL_INT_PLUS_MICRO;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = adata->odr;
> +		return IIO_VAL_INT;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -410,6 +413,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_SCALE:
>  		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
>  		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		if (val2)
> +			return -EINVAL;
> +		mutex_lock(&indio_dev->mlock);
> +		err = st_sensors_set_odr(indio_dev, val);
> +		mutex_unlock(&indio_dev->mlock);
> +		return err;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -417,14 +427,12 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
>  	return err;
>  }
>  
> -static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
>  static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
>  static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
>  
>  static struct attribute *st_accel_attributes[] = {
>  	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
>  	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
> -	&iio_dev_attr_sampling_frequency.dev_attr.attr,
>  	NULL,
>  };
>  
> diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
> index 7ba1ef270213..890bdc83cafb 100644
> --- a/drivers/iio/common/st_sensors/st_sensors_core.c
> +++ b/drivers/iio/common/st_sensors/st_sensors_core.c
> @@ -426,35 +426,6 @@ read_wai_error:
>  }
>  EXPORT_SYMBOL(st_sensors_check_device_support);
>  
> -ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
> -				struct device_attribute *attr, char *buf)
> -{
> -	struct st_sensor_data *adata = iio_priv(dev_get_drvdata(dev));
> -
> -	return sprintf(buf, "%d\n", adata->odr);
> -}
> -EXPORT_SYMBOL(st_sensors_sysfs_get_sampling_frequency);
> -
> -ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
> -		struct device_attribute *attr, const char *buf, size_t size)
> -{
> -	int err;
> -	unsigned int odr;
> -	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> -
> -	err = kstrtoint(buf, 10, &odr);
> -	if (err < 0)
> -		goto conversion_error;
> -
> -	mutex_lock(&indio_dev->mlock);
> -	err = st_sensors_set_odr(indio_dev, odr);
> -	mutex_unlock(&indio_dev->mlock);
> -
> -conversion_error:
> -	return err < 0 ? err : size;
> -}
> -EXPORT_SYMBOL(st_sensors_sysfs_set_sampling_frequency);
> -
>  ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
>  				struct device_attribute *attr, char *buf)
>  {
> diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
> index d53d91adfb55..fc9f449a342a 100644
> --- a/drivers/iio/gyro/st_gyro_core.c
> +++ b/drivers/iio/gyro/st_gyro_core.c
> @@ -246,6 +246,9 @@ static int st_gyro_read_raw(struct iio_dev *indio_dev,
>  		*val = 0;
>  		*val2 = gdata->current_fullscale->gain;
>  		return IIO_VAL_INT_PLUS_MICRO;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = gdata->odr;
> +		return IIO_VAL_INT;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -263,6 +266,13 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_SCALE:
>  		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
>  		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		if (val2)
> +			return -EINVAL;
> +		mutex_lock(&indio_dev->mlock);
> +		err = st_sensors_set_odr(indio_dev, val);
> +		mutex_unlock(&indio_dev->mlock);
> +		return err;
>  	default:
>  		err = -EINVAL;
>  	}
> @@ -270,14 +280,12 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
>  	return err;
>  }
>  
> -static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
>  static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
>  static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
>  
>  static struct attribute *st_gyro_attributes[] = {
>  	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
>  	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
> -	&iio_dev_attr_sampling_frequency.dev_attr.attr,
>  	NULL,
>  };
>  
> diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
> index 52bbcfa1e077..34fc1a70a974 100644
> --- a/drivers/iio/magnetometer/st_magn_core.c
> +++ b/drivers/iio/magnetometer/st_magn_core.c
> @@ -299,6 +299,9 @@ static int st_magn_read_raw(struct iio_dev *indio_dev,
>  		else
>  			*val2 = mdata->current_fullscale->gain;
>  		return IIO_VAL_INT_PLUS_MICRO;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = mdata->odr;
> +		return IIO_VAL_INT;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -316,6 +319,13 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_SCALE:
>  		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
>  		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		if (val2)
> +			return -EINVAL;
> +		mutex_lock(&indio_dev->mlock);
> +		err = st_sensors_set_odr(indio_dev, val);
> +		mutex_unlock(&indio_dev->mlock);
> +		return err;
>  	default:
>  		err = -EINVAL;
>  	}
> @@ -323,14 +333,12 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
>  	return err;
>  }
>  
> -static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
>  static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
>  static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
>  
>  static struct attribute *st_magn_attributes[] = {
>  	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
>  	&iio_dev_attr_in_magn_scale_available.dev_attr.attr,
> -	&iio_dev_attr_sampling_frequency.dev_attr.attr,
>  	NULL,
>  };
>  
> diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
> index 58083f9d51c5..a6d2855cefb0 100644
> --- a/drivers/iio/pressure/st_pressure_core.c
> +++ b/drivers/iio/pressure/st_pressure_core.c
> @@ -235,6 +235,27 @@ static const struct st_sensors st_press_sensors[] = {
>  	},
>  };
>  
> +static int st_press_write_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *ch,
> +			      int val,
> +			      int val2,
> +			      long mask)
> +{
> +	int err;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		if (val2)
> +			return -EINVAL;
> +		mutex_lock(&indio_dev->mlock);
> +		err = st_sensors_set_odr(indio_dev, val);
> +		mutex_unlock(&indio_dev->mlock);
> +		return err;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static int st_press_read_raw(struct iio_dev *indio_dev,
>  			struct iio_chan_spec const *ch, int *val,
>  							int *val2, long mask)
> @@ -277,6 +298,9 @@ static int st_press_read_raw(struct iio_dev *indio_dev,
>  		}
>  
>  		return IIO_VAL_FRACTIONAL;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = pdata->odr;
> +		return IIO_VAL_INT;
>  	default:
>  		return -EINVAL;
>  	}
> @@ -285,12 +309,10 @@ read_error:
>  	return err;
>  }
>  
> -static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
>  static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
>  
>  static struct attribute *st_press_attributes[] = {
>  	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
> -	&iio_dev_attr_sampling_frequency.dev_attr.attr,
>  	NULL,
>  };
>  
> @@ -302,6 +324,7 @@ static const struct iio_info press_info = {
>  	.driver_module = THIS_MODULE,
>  	.attrs = &st_press_attribute_group,
>  	.read_raw = &st_press_read_raw,
> +	.write_raw = &st_press_write_raw,
>  };
>  
>  #ifdef CONFIG_IIO_TRIGGER
> diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
> index 3c005eb3a0a4..ffcd1f2b96c9 100644
> --- a/include/linux/iio/common/st_sensors.h
> +++ b/include/linux/iio/common/st_sensors.h
> @@ -47,6 +47,7 @@
>  	.type = device_type, \
>  	.modified = mod, \
>  	.info_mask_separate = mask, \
> +	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
>  	.scan_index = index, \
>  	.channel2 = ch2, \
>  	.address = addr, \
> @@ -59,11 +60,6 @@
>  	}, \
>  }
>  
> -#define ST_SENSOR_DEV_ATTR_SAMP_FREQ() \
> -		IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, \
> -			st_sensors_sysfs_get_sampling_frequency, \
> -			st_sensors_sysfs_set_sampling_frequency)
> -
>  #define ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL() \
>  		IIO_DEV_ATTR_SAMP_FREQ_AVAIL( \
>  			st_sensors_sysfs_sampling_frequency_avail)
> @@ -281,11 +277,12 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
>  int st_sensors_check_device_support(struct iio_dev *indio_dev,
>  			int num_sensors_list, const struct st_sensors *sensors);
>  
> -ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
> -				struct device_attribute *attr, char *buf);
> +int st_sensors_get_sampling_frequency(struct iio_dev *indio_dev,
> +				      int *val,
> +				      int *val2);
>  
> -ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
> -		struct device_attribute *attr, const char *buf, size_t size);
> +int st_sensors_set_sampling_frequency(struct iio_dev *indio_dev, int *val,
> +				      int *val2);
>  
>  ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
>  				struct device_attribute *attr, char *buf);
> 

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

* Re: [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all.
  2013-11-17 15:14 ` [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all Jonathan Cameron
@ 2013-11-18 18:29   ` Lars-Peter Clausen
  2013-11-18 20:52     ` Jonathan Cameron
  0 siblings, 1 reply; 15+ messages in thread
From: Lars-Peter Clausen @ 2013-11-18 18:29 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

On 11/17/2013 04:14 PM, Jonathan Cameron wrote:
> This replaces the previous use of a custom attribute to create the same
> interface.  One big advantage is that this allows in kernel access.

Looks mostly good, can probably also be merged without waiting for the reset
of the series

[...]
> @@ -512,6 +457,10 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
>  			*val -= offset;
>  		}
>  		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = st->chip_info->
> +			sample_freq_avail[AD7793_MODE_RATE(st->mode)];
> +		return IIO_VAL_INT;
>  	}
>  	return -EINVAL;
>  }
> @@ -551,6 +500,20 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
>  				break;
>  			}
>  		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		if (val == 0)
> +			return -EINVAL;
> +
> +		ret = -EINVAL;
> +		for (i = 0; i < 16; i++)
> +			if (val == st->chip_info->sample_freq_avail[i]) {
> +				st->mode &= ~AD7793_MODE_RATE(-1);
> +				st->mode |= AD7793_MODE_RATE(i);
> +				ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
> +						sizeof(st->mode), st->mode);
> +				ret = 0;
> +			}

In order to keep the indentation level low I'd put this into it's own function.

> +		break;
>  	default:
>  		ret = -EINVAL;
>  	}
[...]
>  #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
>  const struct iio_chan_spec _name##_channels[] = { \
>  	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0, \
> -	0, 0, 0), \
> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>  	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0, \
> -	0, 0, 0), \
> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>  	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0, \
> -	0, 0, 0), \
> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>  	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0, \
> -	0, 0, 0), \
> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>  	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0, \
> -	0, 0, 0), \
> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>  	IIO_CHAN_SOFT_TIMESTAMP(5), \
>  }

Do we actually have any channels that won't have the SAMP_FREQ attribute set?

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

* Re: [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all.
  2013-11-18 18:29   ` Lars-Peter Clausen
@ 2013-11-18 20:52     ` Jonathan Cameron
  0 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2013-11-18 20:52 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: linux-iio



Lars-Peter Clausen <lars@metafoo.de> wrote:
>On 11/17/2013 04:14 PM, Jonathan Cameron wrote:
>> This replaces the previous use of a custom attribute to create the
>same
>> interface.  One big advantage is that this allows in kernel access.
>
>Looks mostly good, can probably also be merged without waiting for the
>reset
>of the series
>
>[...]
>> @@ -512,6 +457,10 @@ static int ad7793_read_raw(struct iio_dev
>*indio_dev,
>>  			*val -= offset;
>>  		}
>>  		return IIO_VAL_INT;
>> +	case IIO_CHAN_INFO_SAMP_FREQ:
>> +		*val = st->chip_info->
>> +			sample_freq_avail[AD7793_MODE_RATE(st->mode)];
>> +		return IIO_VAL_INT;
>>  	}
>>  	return -EINVAL;
>>  }
>> @@ -551,6 +500,20 @@ static int ad7793_write_raw(struct iio_dev
>*indio_dev,
>>  				break;
>>  			}
>>  		break;
>> +	case IIO_CHAN_INFO_SAMP_FREQ:
>> +		if (val == 0)
>> +			return -EINVAL;
>> +
>> +		ret = -EINVAL;
>> +		for (i = 0; i < 16; i++)
>> +			if (val == st->chip_info->sample_freq_avail[i]) {
>> +				st->mode &= ~AD7793_MODE_RATE(-1);
>> +				st->mode |= AD7793_MODE_RATE(i);
>> +				ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
>> +						sizeof(st->mode), st->mode);
>> +				ret = 0;
>> +			}
>
>In order to keep the indentation level low I'd put this into it's own
>function.
>
>> +		break;
>>  	default:
>>  		ret = -EINVAL;
>>  	}
>[...]
>>  #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
>>  const struct iio_chan_spec _name##_channels[] = { \
>>  	AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0,
>\
>> -	0, 0, 0), \
>> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>>  	AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0,
>\
>> -	0, 0, 0), \
>> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>>  	AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0,
>\
>> -	0, 0, 0), \
>> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>>  	AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0,
>\
>> -	0, 0, 0), \
>> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>>  	AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0,
>\
>> -	0, 0, 0), \
>> +	BIT(IIO_CHAN_INFO_SAMP_FREQ), 0, 0), \
>>  	IIO_CHAN_SOFT_TIMESTAMP(5), \
>>  }
>
>Do we actually have any channels that won't have the SAMP_FREQ
>attribute set?
Yes in one of the drivers ad7780 I think...

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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

end of thread, other threads:[~2013-11-18 20:52 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-17 15:14 [RFC PATCH 00/11] IIO: Add core support for _available interfaces Jonathan Cameron
2013-11-17 15:14 ` [PATCH 01/11] iio:core: add a callback to allow drivers to provide _available attributes Jonathan Cameron
2013-11-17 15:14 ` [PATCH 02/11] staging:iio:dummy driver: Add example usecases for the new *_available interface Jonathan Cameron
2013-11-17 15:14 ` [PATCH 03/11] iio:accel:bma180 use new read_avail to replace *_available attrs Jonathan Cameron
2013-11-17 15:14 ` [PATCH 04/11] iio:accel:kxsd9 use new read_avail to replace accel_scan_available Jonathan Cameron
2013-11-17 15:14 ` [PATCH 05/11] iio:st sensors: remove custom sampling frequence attribute in favour of core support Jonathan Cameron
2013-11-18 18:25   ` Lars-Peter Clausen
2013-11-17 15:14 ` [PATCH 06/11] iio: ad_sigma_delta provide macro parameters for available info masks Jonathan Cameron
2013-11-17 15:14 ` [PATCH 07/11] iio:adc:ad7793: use samp_freq element of info_mask_shared_by_all Jonathan Cameron
2013-11-18 18:29   ` Lars-Peter Clausen
2013-11-18 20:52     ` Jonathan Cameron
2013-11-17 15:14 ` [PATCH 08/11] iio:adc:ad7793: Use the read_avail callback to provide the scale and sampling frequency interfaces Jonathan Cameron
2013-11-17 15:15 ` [PATCH 09/11] iio:adc:ad7791 Provide sampling frequency and scale_available access via core Jonathan Cameron
2013-11-17 15:15 ` [PATCH 10/11] staging:iio:adc:ad7192 use infomask* to provide access to sampling frequency and scale_available Jonathan Cameron
2013-11-17 15:15 ` [PATCH 11/11] iio:adc:mcp3422: use core to provide _available information rather than custom attrs 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).