All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] staging:iio: CDC and other driver updates.
@ 2011-08-26 10:19 Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 01/16] staging:iio:dac:ad5791 chan spec conversion Jonathan Cameron
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Hi All,

Straight forward series - as you can see I've rolled in Michael's
recent posting so you can see where they fit.

This lot sits on top of
staging:iio: New stuff and reworks.

Nothing terribly interesting.  Mostly bringing a few drivers into
line with the abi.  Thanks particularly to Michael for testing my
hardware free changes and chasing down all the bugs!

Jonathan

Jonathan Cameron (7):
  staging:iio:dac:ad5791 chan spec conversion.
  staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop
    unused poweroff timeout control.
  staging:iio:adc:ad7152 use smbus read / write functions + checkpatch
    fixes
  staging:iio:adc:ad7152 set correct number of channels for ad7153.
  staging:iio:adc:ad7152 bring more into line with abi.
  staging:iio:adc:ad7291 bring into line with current abi + chan_spec
    conversion.
  staging:iio:imu:adis16400 cleanups

Michael Hennerich (9):
  staging:iio:adc:ad7150: remove conversion mode handling.
  staging:iio:adc:ad7150: Add support for the second interrupt strobe.
  staging:iio:adc:ad7152: increase readability by introducing proper
    bit defines
  staging:iio:adc:ad7152: Miscellaneous fixes and touch-up
  staging:iio:adc:ad7152: update scale handling
  staging:iio:adc:ad7152: Add proper locking
  staging:iio:adc:ad7152: Update sample rate, conversion time, digital
    filter handling
  staging:iio:adc:ad7152: Fix differential channel return value and
    increase delay.
  iio: imu: adis16400: Avoid using printk facility

 drivers/staging/iio/adc/ad7150.c            |  930 +++++++++++----------------
 drivers/staging/iio/adc/ad7152.c            |  783 +++++++++++------------
 drivers/staging/iio/adc/ad7291.c            |  892 +++++++++-----------------
 drivers/staging/iio/dac/ad5791.c            |  158 ++---
 drivers/staging/iio/dac/ad5791.h            |    4 -
 drivers/staging/iio/imu/adis16400_core.c    |  607 ++++++++++++------
 drivers/staging/iio/imu/adis16400_trigger.c |    2 +-
 7 files changed, 1560 insertions(+), 1816 deletions(-)

-- 
1.7.3.4

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

* [PATCH 01/16] staging:iio:dac:ad5791 chan spec conversion.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 02/16] staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/dac/ad5791.c |  158 +++++++++++++++++---------------------
 drivers/staging/iio/dac/ad5791.h |    4 -
 2 files changed, 72 insertions(+), 90 deletions(-)

diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
index b266513..d904c14 100644
--- a/drivers/staging/iio/dac/ad5791.c
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -71,48 +71,22 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
 	return ret;
 }
 
-static ssize_t ad5791_write_dac(struct device *dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5791_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long readin;
-	int ret;
-
-	ret = strict_strtol(buf, 10, &readin);
-	if (ret)
-		return ret;
-
-	readin += (1 << (st->chip_info->bits - 1));
-	readin &= AD5791_RES_MASK(st->chip_info->bits);
-	readin <<= st->chip_info->left_shift;
-
-	ret = ad5791_spi_write(st->spi, this_attr->address, readin);
-	return ret ? ret : len;
+#define AD5791_CHAN(bits, shift) {			\
+	.type = IIO_VOLTAGE,				\
+	.output = 1,					\
+	.indexed = 1,					\
+	.address = AD5791_ADDR_DAC0,			\
+	.channel = 0,					\
+	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),	\
+	.scan_type = IIO_ST('u', bits, 24, shift)	\
 }
 
-static ssize_t ad5791_read_dac(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5791_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	int val;
-
-	ret = ad5791_spi_read(st->spi, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	val &= AD5791_DAC_MASK;
-	val >>= st->chip_info->left_shift;
-	val -= (1 << (st->chip_info->bits - 1));
-
-	return sprintf(buf, "%d\n", val);
-}
+static const struct iio_chan_spec ad5791_channels[] = {
+	[ID_AD5760] = AD5791_CHAN(16, 4),
+	[ID_AD5780] = AD5791_CHAN(18, 2),
+	[ID_AD5781] = AD5791_CHAN(18, 2),
+	[ID_AD5791] = AD5791_CHAN(20, 0)
+};
 
 static ssize_t ad5791_read_powerdown_mode(struct device *dev,
 				      struct device_attribute *attr, char *buf)
@@ -183,37 +157,6 @@ static ssize_t ad5791_write_dac_powerdown(struct device *dev,
 	return ret ? ret : len;
 }
 
-static ssize_t ad5791_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5791_state *st = iio_priv(indio_dev);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5791_show_scale, NULL, 0);
-
-static ssize_t ad5791_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5791_state *st = iio_priv(indio_dev);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5791_show_name, NULL, 0);
-
-#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(out##_num##_raw,				\
-			S_IRUGO | S_IWUSR, _show, _store, _addr)
-
-static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5791_read_dac,
-	ad5791_write_dac, AD5791_ADDR_DAC0);
-
 static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
 			S_IWUSR, ad5791_read_powerdown_mode,
 			ad5791_write_powerdown_mode, 0);
@@ -229,12 +172,9 @@ static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown,
 				   ad5791_write_dac_powerdown, 0);
 
 static struct attribute *ad5791_attributes[] = {
-	&iio_dev_attr_out0_raw.dev_attr.attr,
 	&iio_dev_attr_out0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_out_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -263,31 +203,74 @@ static int ad5780_get_lin_comp(unsigned int span)
 	else
 		return AD5780_LINCOMP_10_20;
 }
-
 static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
 	[ID_AD5760] = {
-		.bits = 16,
-		.left_shift = 4,
 		.get_lin_comp = ad5780_get_lin_comp,
 	},
 	[ID_AD5780] = {
-		.bits = 18,
-		.left_shift = 2,
 		.get_lin_comp = ad5780_get_lin_comp,
 	},
 	[ID_AD5781] = {
-		.bits = 18,
-		.left_shift = 2,
 		.get_lin_comp = ad5791_get_lin_comp,
 	},
 	[ID_AD5791] = {
-		.bits = 20,
-		.left_shift = 0,
 		.get_lin_comp = ad5791_get_lin_comp,
 	},
 };
 
+static int ad5791_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
+{
+	struct ad5791_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (m) {
+	case 0:
+		ret = ad5791_spi_read(st->spi, chan->address, val);
+		if (ret)
+			return ret;
+		*val &= AD5791_DAC_MASK;
+		*val >>= chan->scan_type.shift;
+		*val -= (1 << (chan->scan_type.storagebits - 1));
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		*val = 0;
+		*val2 = (st->vref_mv * 1000) >> chan->scan_type.storagebits;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+
+};
+
+
+static int ad5791_write_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int val,
+			    int val2,
+			    long mask)
+{
+	struct ad5791_state *st = iio_priv(indio_dev);
+
+	switch (mask) {
+	case 0:
+		val += (1 << (chan->scan_type.storagebits - 1));
+		val &= AD5791_RES_MASK(chan->scan_type.storagebits);
+		val <<= chan->scan_type.shift;
+
+		return ad5791_spi_write(st->spi, chan->address, val);
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct iio_info ad5791_info = {
+	.read_raw = &ad5791_read_raw,
+	.write_raw = &ad5791_write_raw,
 	.attrs = &ad5791_attribute_group,
 	.driver_module = THIS_MODULE,
 };
@@ -337,8 +320,8 @@ static int __devinit ad5791_probe(struct spi_device *spi)
 	if (ret)
 		goto error_disable_reg_neg;
 
-	st->chip_info =
-		&ad5791_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+	st->chip_info =	&ad5791_chip_info_tbl[spi_get_device_id(spi)
+					      ->driver_data];
 
 
 	st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
@@ -354,7 +337,10 @@ static int __devinit ad5791_probe(struct spi_device *spi)
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->info = &ad5791_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-
+	indio_dev->channels
+		= &ad5791_channels[spi_get_device_id(spi)->driver_data];
+	indio_dev->num_channels = 1;
+	indio_dev->name = spi_get_device_id(st->spi)->name;
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_disable_reg_neg;
diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h
index c807f26..2a50a11 100644
--- a/drivers/staging/iio/dac/ad5791.h
+++ b/drivers/staging/iio/dac/ad5791.h
@@ -68,14 +68,10 @@ struct ad5791_platform_data {
 
 /**
  * struct ad5791_chip_info - chip specific information
- * @bits:		accuracy of the DAC in bits
- * @left_shift:		number of bits the datum must be shifted
  * @get_lin_comp:	function pointer to the device specific function
  */
 
 struct ad5791_chip_info {
-	u8			bits;
-	u8			left_shift;
 	int (*get_lin_comp)	(unsigned int span);
 };
 
-- 
1.7.3.4

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

* [PATCH 02/16] staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop unused poweroff timeout control.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 01/16] staging:iio:dac:ad5791 chan spec conversion Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 03/16] staging:iio:adc:ad7150: remove conversion mode handling Jonathan Cameron
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Minimal changes to code layout as going to do chan spec conversion shortly.
Otherwise, there are numerous code sharing opportunities in here and abi
elements that are uterly non compliant.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7150.c |  840 ++++++++++++++++++--------------------
 1 files changed, 389 insertions(+), 451 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 3e4801f..0eb1992 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -23,22 +23,16 @@
 #define AD7150_STATUS_OUT1         (1 << 3)
 #define AD7150_STATUS_OUT2         (1 << 5)
 #define AD7150_CH1_DATA_HIGH       1
-#define AD7150_CH1_DATA_LOW        2
 #define AD7150_CH2_DATA_HIGH       3
-#define AD7150_CH2_DATA_LOW        4
 #define AD7150_CH1_AVG_HIGH        5
-#define AD7150_CH1_AVG_LOW         6
 #define AD7150_CH2_AVG_HIGH        7
-#define AD7150_CH2_AVG_LOW         8
 #define AD7150_CH1_SENSITIVITY     9
 #define AD7150_CH1_THR_HOLD_H      9
 #define AD7150_CH1_TIMEOUT         10
-#define AD7150_CH1_THR_HOLD_L      10
 #define AD7150_CH1_SETUP           11
 #define AD7150_CH2_SENSITIVITY     12
 #define AD7150_CH2_THR_HOLD_H      12
 #define AD7150_CH2_TIMEOUT         13
-#define AD7150_CH2_THR_HOLD_L      13
 #define AD7150_CH2_SETUP           14
 #define AD7150_CFG                 15
 #define AD7150_CFG_FIX             (1 << 7)
@@ -53,25 +47,45 @@
 
 #define AD7150_MAX_CONV_MODE       4
 
-/*
- * struct ad7150_chip_info - chip specifc information
+/**
+ * Todo list:
+ * - Review whether old_state usage makes sense.
+ * - get rid of explicit control of conversion mode
  */
 
+/**
+ * struct ad7150_chip_info - instance specific chip data
+ * @client: i2c client for this device
+ * @current_event: device always has one type of event enabled.
+ *	This element stores the event code of the current one.
+ * @threshold: thresholds for simple capacitance value events
+ * @thresh_sensitivity: threshold for simple capacitance offset
+ *	from 'average' value.
+ * @mag_sensitity: threshold for magnitude of capacitance offset from
+ *	from 'average' value.
+ * @thresh_timeout: a timeout, in samples from the moment an
+ *	adaptive threshold event occurs to when the average
+ *	value jumps to current value.
+ * @mag_timeout: a timeout, in sample from the moment an
+ *	adaptive magnitude event occurs to when the average
+ *	value jumps to the current value.
+ * @old_state: store state from previous event, allowing confirmation
+ *	of new condition.
+ * @conversion_mode: the current conversion mode.
+ * @state_lock: ensure consistent state of this structure wrt the
+ *	hardware.
+ */
 struct ad7150_chip_info {
 	struct i2c_client *client;
-	bool inter;
-	u16 ch1_threshold;     /* Ch1 Threshold (in fixed threshold mode) */
-	u8  ch1_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
-	u8  ch1_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
-	u8  ch1_setup;
-	u16 ch2_threshold;     /* Ch2 Threshold (in fixed threshold mode) */
-	u8  ch2_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
-	u8  ch2_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
-	u8  ch2_setup;
-	u8  powerdown_timer;
-	char threshold_mode[10]; /* adaptive/fixed threshold mode */
+	u64 current_event;
+	u16 threshold[2][2];
+	u8 thresh_sensitivity[2][2];
+	u8 mag_sensitivity[2][2];
+	u8 thresh_timeout[2][2];
+	u8 mag_timeout[2][2];
 	int old_state;
 	char *conversion_mode;
+	struct mutex state_lock;
 };
 
 struct ad7150_conversion_mode {
@@ -88,80 +102,13 @@ ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
 };
 
 /*
- * ad7150 register access by I2C
- */
-
-static int ad7150_i2c_read(struct ad7150_chip_info *chip, u8 reg, u8 *data, int len)
-{
-	struct i2c_client *client = chip->client;
-	int ret = 0;
-
-	ret = i2c_master_send(client, &reg, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C write error\n");
-		return ret;
-	}
-
-	ret = i2c_master_recv(client, data, len);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C read error\n");
-		return ret;
-	}
-
-	return ret;
-}
-
-static int ad7150_i2c_write(struct ad7150_chip_info *chip, u8 reg, u8 data)
-{
-	struct i2c_client *client = chip->client;
-	int ret = 0;
-
-	u8 tx[2] = {
-		reg,
-		data,
-	};
-
-	ret = i2c_master_send(client, tx, 2);
-	if (ret < 0)
-		dev_err(&client->dev, "I2C write error\n");
-
-	return ret;
-}
-
-/*
  * sysfs nodes
  */
 
-#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)				\
+#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)			\
 	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
 #define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
 	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(_show)				\
-	IIO_DEVICE_ATTR(available_threshold_modes, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_THRESHOLD_MODE(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(threshold_mode, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_THRESHOLD(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(ch1_threshold, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_THRESHOLD(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(ch2_threshold, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_SENSITIVITY(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_sensitivity, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_SENSITIVITY(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch2_sensitivity, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_TIMEOUT(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_timeout, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_TIMEOUT(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch2_timeout, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_VALUE(_show)		\
-	IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_CH2_VALUE(_show)		\
-	IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_POWERDOWN_TIMER(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(powerdown_timer, _mode, _show, _store, 0)
 
 static ssize_t ad7150_show_conversion_modes(struct device *dev,
 		struct device_attribute *attr,
@@ -171,7 +118,8 @@ static ssize_t ad7150_show_conversion_modes(struct device *dev,
 	int len = 0;
 
 	for (i = 0; i < AD7150_MAX_CONV_MODE; i++)
-		len += sprintf(buf + len, "%s\n", ad7150_conv_mode_table[i].name);
+		len += sprintf(buf + len, "%s\n",
+			       ad7150_conv_mode_table[i].name);
 
 	return len;
 }
@@ -196,16 +144,24 @@ static ssize_t ad7150_store_conversion_mode(struct device *dev,
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
 	u8 cfg;
-	int i;
+	int i, ret;
 
-	ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1);
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
+	if (ret < 0)
+		return ret;
+	cfg = ret;
 
 	for (i = 0; i < AD7150_MAX_CONV_MODE; i++) {
 		if (strncmp(buf, ad7150_conv_mode_table[i].name,
-				strlen(ad7150_conv_mode_table[i].name) - 1) == 0) {
+				strlen(ad7150_conv_mode_table[i].name) - 1) ==
+		    0) {
 			chip->conversion_mode = ad7150_conv_mode_table[i].name;
 			cfg |= 0x18 | ad7150_conv_mode_table[i].reg_cfg;
-			ad7150_i2c_write(chip, AD7150_CFG, cfg);
+			ret = i2c_smbus_write_byte_data(chip->client,
+							AD7150_CFG,
+							cfg);
+			if (ret < 0)
+				return ret;
 			return len;
 		}
 	}
@@ -219,419 +175,376 @@ static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
 		ad7150_show_conversion_mode,
 		ad7150_store_conversion_mode);
 
-static ssize_t ad7150_show_threshold_modes(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return sprintf(buf, "adaptive\nfixed\n");
-}
-
-static IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(ad7150_show_threshold_modes);
-
-static ssize_t ad7150_show_ch1_value(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
-
-	ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
-}
-
-static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value);
-
-static ssize_t ad7150_show_ch2_value(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
-
-	ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
-}
-
-static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value);
-
-static ssize_t ad7150_show_threshold_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%s\n", chip->threshold_mode);
-}
-
-static ssize_t ad7150_store_threshold_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 cfg;
-
-	ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1);
-
-	if (strncmp(buf, "fixed", 5) == 0) {
-		strcpy(chip->threshold_mode, "fixed");
-		cfg |= AD7150_CFG_FIX;
-		ad7150_i2c_write(chip, AD7150_CFG, cfg);
-
-		return len;
-	} else if (strncmp(buf, "adaptive", 8) == 0) {
-		strcpy(chip->threshold_mode, "adaptive");
-		cfg &= ~AD7150_CFG_FIX;
-		ad7150_i2c_write(chip, AD7150_CFG, cfg);
-
-		return len;
-	}
-
-	dev_err(dev, "not supported threshold mode\n");
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_THRESHOLD_MODE(S_IRUGO | S_IWUSR,
-		ad7150_show_threshold_mode,
-		ad7150_store_threshold_mode);
-
-static ssize_t ad7150_show_ch1_threshold(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch1_threshold);
-}
+static const u8 ad7150_addresses[][6] = {
+	{ AD7150_CH1_DATA_HIGH, AD7150_CH1_AVG_HIGH,
+	  AD7150_CH1_SETUP, AD7150_CH1_THR_HOLD_H,
+	  AD7150_CH1_SENSITIVITY, AD7150_CH1_TIMEOUT },
+	{ AD7150_CH2_DATA_HIGH, AD7150_CH2_AVG_HIGH,
+	  AD7150_CH2_SETUP, AD7150_CH2_THR_HOLD_H,
+	  AD7150_CH2_SENSITIVITY, AD7150_CH2_TIMEOUT },
+};
 
-static ssize_t ad7150_store_ch1_threshold(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int ad7150_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long mask)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
 	int ret;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_H, data >> 8);
-		ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_L, data);
-		chip->ch1_threshold = data;
-		return len;
+	switch (mask) {
+	case 0:
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7150_addresses[chan->channel][0]);
+		if (ret < 0)
+			return ret;
+		*val = swab16(ret);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE):
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7150_addresses[chan->channel][1]);
+		if (ret < 0)
+			return ret;
+		*val = swab16(ret);
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
 	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR,
-		ad7150_show_ch1_threshold,
-		ad7150_store_ch1_threshold);
-
-static ssize_t ad7150_show_ch2_threshold(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch2_threshold);
 }
 
-static ssize_t ad7150_store_ch2_threshold(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
 	int ret;
+	u8 threshtype;
+	bool adaptive;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING);
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_H, data >> 8);
-		ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_L, data);
-		chip->ch2_threshold = data;
-		return len;
-	}
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
+	if (ret < 0)
+		return ret;
 
+	threshtype = (ret >> 5) & 0x03;
+	adaptive = !!(ret & 0x80);
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		if (rising)
+			return adaptive && (threshtype == 0x1);
+		else
+			return adaptive && (threshtype == 0x0);
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		if (rising)
+			return adaptive && (threshtype == 0x3);
+		else
+			return adaptive && (threshtype == 0x2);
+
+	case IIO_EV_TYPE_THRESH:
+		if (rising)
+			return !adaptive && (threshtype == 0x1);
+		else
+			return !adaptive && (threshtype == 0x0);
+	};
 	return -EINVAL;
 }
 
-static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_threshold,
-		ad7150_store_ch2_threshold);
-
-static ssize_t ad7150_show_ch1_sensitivity(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch1_sensitivity);
-}
-
-static ssize_t ad7150_store_ch1_sensitivity(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+/* lock should be held */
+static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
 	int ret;
+	u16 value;
+	u8 sens, timeout;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING);
+
+	if (event_code != chip->current_event)
+		return 0;
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+		/* Note completely different from the adaptive versions */
+	case IIO_EV_TYPE_THRESH:
+		value = chip->threshold[rising][chan];
+		ret = i2c_smbus_write_word_data(chip->client,
+						ad7150_addresses[chan][3],
+						swab16(value));
+		if (ret < 0)
+			return ret;
+		return 0;
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		sens = chip->mag_sensitivity[rising][chan];
+		timeout = chip->mag_timeout[rising][chan];
+		break;
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		sens = chip->thresh_sensitivity[rising][chan];
+		timeout = chip->thresh_timeout[rising][chan];
+		break;
+	default:
+		return -EINVAL;
+	};
+	ret = i2c_smbus_write_byte_data(chip->client,
+					ad7150_addresses[chan][4],
+					sens);
+	if (ret < 0)
+		return ret;
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data);
-		chip->ch1_sensitivity = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR,
-		ad7150_show_ch1_sensitivity,
-		ad7150_store_ch1_sensitivity);
-
-static ssize_t ad7150_show_ch2_sensitivity(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
+	ret = i2c_smbus_write_byte_data(chip->client,
+					ad7150_addresses[chan][5],
+					timeout);
+	if (ret < 0)
+		return ret;
 
-	return sprintf(buf, "%d\n", chip->ch2_sensitivity);
+	return 0;
 }
 
-static ssize_t ad7150_store_ch2_sensitivity(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int ad7150_write_event_config(struct iio_dev *indio_dev,
+				     u64 event_code, int state)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u8 thresh_type, cfg, adaptive;
 	int ret;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING);
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data);
-		chip->ch2_sensitivity = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_sensitivity,
-		ad7150_store_ch2_sensitivity);
-
-static ssize_t ad7150_show_ch1_timeout(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch1_timeout);
-}
+	/* Something must always be turned on */
+	if (state == 0)
+		return -EINVAL;
 
-static ssize_t ad7150_store_ch1_timeout(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
+	if (event_code == chip->current_event)
+		return 0;
+	mutex_lock(&chip->state_lock);
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
+	if (ret < 0)
+		goto error_ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	cfg = ret & ~((0x03 << 5) | (0x1 << 7));
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		adaptive = 1;
+		if (rising)
+			thresh_type = 0x1;
+		else
+			thresh_type = 0x0;
+		break;
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		adaptive = 1;
+		if (rising)
+			thresh_type = 0x3;
+		else
+			thresh_type = 0x2;
+		break;
+	case IIO_EV_TYPE_THRESH:
+		adaptive = 0;
+		if (rising)
+			thresh_type = 0x1;
+		else
+			thresh_type = 0x0;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_ret;
+	};
 
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data);
-		chip->ch1_timeout = data;
-		return len;
-	}
+	cfg |= (!adaptive << 7) | (thresh_type << 5);
 
-	return -EINVAL;
-}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CFG, cfg);
+	if (ret < 0)
+		goto error_ret;
 
-static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR,
-		ad7150_show_ch1_timeout,
-		ad7150_store_ch1_timeout);
+	chip->current_event = event_code;
 
-static ssize_t ad7150_show_ch2_timeout(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
+	/* update control attributes */
+	ret = ad7150_write_event_params(indio_dev, event_code);
+error_ret:
+	mutex_unlock(&chip->state_lock);
 
-	return sprintf(buf, "%d\n", chip->ch2_timeout);
+	return 0;
 }
 
-static ssize_t ad7150_store_ch2_timeout(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int ad7150_read_event_value(struct iio_dev *indio_dev,
+				   u64 event_code,
+				   int *val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &data);
+	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING);
 
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data);
-		chip->ch2_timeout = data;
-		return len;
-	}
+	/* Complex register sharing going on here */
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		*val = chip->mag_sensitivity[rising][chan];
+		return 0;
 
-	return -EINVAL;
-}
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		*val = chip->thresh_sensitivity[rising][chan];
+		return 0;
 
-static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_timeout,
-		ad7150_store_ch2_timeout);
+	case IIO_EV_TYPE_THRESH:
+		*val = chip->threshold[rising][chan];
+		return 0;
 
-static ssize_t ad7150_show_ch1_setup(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "0x%02x\n", chip->ch1_setup);
+	default:
+		return -EINVAL;
+	};
 }
 
-static ssize_t ad7150_store_ch1_setup(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static int ad7150_write_event_value(struct iio_dev *indio_dev,
+				   u64 event_code,
+				   int val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
 	int ret;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING);
+
+	mutex_lock(&chip->state_lock);
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		chip->mag_sensitivity[rising][chan] = val;
+		break;
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		chip->thresh_sensitivity[rising][chan] = val;
+		break;
+	case IIO_EV_TYPE_THRESH:
+		chip->threshold[rising][chan] = val;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_ret;
+	};
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH1_SETUP, data);
-		chip->ch1_setup = data;
-		return len;
-	}
-
+	/* write back if active */
+	ret = ad7150_write_event_params(indio_dev, event_code);
 
-	return -EINVAL;
+	mutex_unlock(&chip->state_lock);
+error_ret:
+	return ret;
 }
 
-static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
-		ad7150_show_ch1_setup,
-		ad7150_store_ch1_setup);
-
-static ssize_t ad7150_show_ch2_setup(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static ssize_t ad7150_show_timeout(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	u8 value;
+
+	/* use the event code for consistency reasons */
+	int chan = IIO_EVENT_CODE_EXTRACT_NUM(this_attr->address);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address)
+			== IIO_EV_DIR_RISING);
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		value = chip->mag_timeout[rising][chan];
+		break;
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		value = chip->thresh_timeout[rising][chan];
+		break;
+	default:
+		return -EINVAL;
+	};
 
-	return sprintf(buf, "0x%02x\n", chip->ch2_setup);
+	return sprintf(buf, "%d\n", value);
 }
 
-static ssize_t ad7150_store_ch2_setup(struct device *dev,
+static ssize_t ad7150_store_timeout(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
 		size_t len)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int chan = IIO_EVENT_CODE_EXTRACT_NUM(this_attr->address);
+	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
+			IIO_EV_DIR_RISING);
+	u8 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH2_SETUP, data);
-		chip->ch2_setup = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_setup,
-		ad7150_store_ch2_setup);
-
-static ssize_t ad7150_show_powerdown_timer(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "0x%02x\n", chip->powerdown_timer);
-}
+	ret = kstrtou8(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
-static ssize_t ad7150_store_powerdown_timer(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
+	mutex_lock(&chip->state_lock);
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		chip->mag_timeout[rising][chan] = data;
+		break;
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		chip->thresh_timeout[rising][chan] = data;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_ret;
+	};
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = ad7150_write_event_params(indio_dev, this_attr->address);
+error_ret:
+	mutex_unlock(&chip->state_lock);
 
-	if ((!ret) && (data < 0x40)) {
-		chip->powerdown_timer = data;
-		return len;
-	}
+	if (ret < 0)
+		return ret;
 
-	return -EINVAL;
+	return len;
 }
 
-static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR,
-		ad7150_show_powerdown_timer,
-		ad7150_store_powerdown_timer);
+#define AD7150_TIMEOUT(chan, type, dir, ev_type, ev_dir)		\
+	IIO_DEVICE_ATTR(in_capacitance##chan##_##type##_##dir##_timeout, \
+		S_IRUGO | S_IWUSR,					\
+		&ad7150_show_timeout,					\
+		&ad7150_store_timeout,					\
+		IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE,			\
+				     chan,				\
+				     IIO_EV_TYPE_##ev_type,		\
+				     IIO_EV_DIR_##ev_dir))
+static AD7150_TIMEOUT(0, mag_adaptive, rising, MAG_ADAPTIVE, RISING);
+static AD7150_TIMEOUT(0, mag_adaptive, falling, MAG_ADAPTIVE, FALLING);
+static AD7150_TIMEOUT(1, mag_adaptive, rising, MAG_ADAPTIVE, RISING);
+static AD7150_TIMEOUT(1, mag_adaptive, falling, MAG_ADAPTIVE, FALLING);
+static AD7150_TIMEOUT(0, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
+static AD7150_TIMEOUT(0, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
+static AD7150_TIMEOUT(1, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
+static AD7150_TIMEOUT(1, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
+
+static const struct iio_chan_spec ad7150_channels[] = {
+	{
+		.type = IIO_CAPACITANCE,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
+		.event_mask =
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
+		IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+	}, {
+		.type = IIO_CAPACITANCE,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
+		.event_mask =
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
+		IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
+		IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+	},
+};
 
 static struct attribute *ad7150_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
-	&iio_dev_attr_available_threshold_modes.dev_attr.attr,
-	&iio_dev_attr_threshold_mode.dev_attr.attr,
-	&iio_dev_attr_ch1_threshold.dev_attr.attr,
-	&iio_dev_attr_ch2_threshold.dev_attr.attr,
-	&iio_dev_attr_ch1_timeout.dev_attr.attr,
-	&iio_dev_attr_ch2_timeout.dev_attr.attr,
-	&iio_dev_attr_ch1_setup.dev_attr.attr,
-	&iio_dev_attr_ch2_setup.dev_attr.attr,
-	&iio_dev_attr_ch1_sensitivity.dev_attr.attr,
-	&iio_dev_attr_ch2_sensitivity.dev_attr.attr,
-	&iio_dev_attr_powerdown_timer.dev_attr.attr,
-	&iio_dev_attr_ch1_value.dev_attr.attr,
-	&iio_dev_attr_ch2_value.dev_attr.attr,
 	NULL,
 };
 
@@ -649,8 +562,13 @@ static irqreturn_t ad7150_event_handler(int irq, void *private)
 	struct ad7150_chip_info *chip = iio_priv(indio_dev);
 	u8 int_status;
 	s64 timestamp = iio_get_time_ns();
+	int ret;
 
-	ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1);
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_STATUS);
+	if (ret < 0)
+		return IRQ_HANDLED;
+
+	int_status = ret;
 
 	if ((int_status & AD7150_STATUS_OUT1) &&
 	    !(chip->old_state & AD7150_STATUS_OUT1))
@@ -685,19 +603,30 @@ static irqreturn_t ad7150_event_handler(int irq, void *private)
 						    IIO_EV_TYPE_THRESH,
 						    IIO_EV_DIR_FALLING),
 			       timestamp);
+	/* store the status to avoid repushing same events */
+	chip->old_state = int_status;
+
 	return IRQ_HANDLED;
 }
 
-static IIO_CONST_ATTR(ch1_high_en, "1");
-static IIO_CONST_ATTR(ch2_high_en, "1");
-static IIO_CONST_ATTR(ch1_low_en, "1");
-static IIO_CONST_ATTR(ch2_low_en, "1");
-
+/* Timeouts not currently handled by core */
 static struct attribute *ad7150_event_attributes[] = {
-	&iio_const_attr_ch1_high_en.dev_attr.attr,
-	&iio_const_attr_ch2_high_en.dev_attr.attr,
-	&iio_const_attr_ch1_low_en.dev_attr.attr,
-	&iio_const_attr_ch2_low_en.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_mag_adaptive_rising_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_mag_adaptive_falling_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_mag_adaptive_rising_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_mag_adaptive_falling_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_thresh_adaptive_rising_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_thresh_adaptive_falling_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_thresh_adaptive_rising_timeout
+	.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_thresh_adaptive_falling_timeout
+	.dev_attr.attr,
 	NULL,
 };
 
@@ -710,7 +639,13 @@ static const struct iio_info ad7150_info = {
 	.attrs = &ad7150_attribute_group,
 	.event_attrs = &ad7150_event_attribute_group,
 	.driver_module = THIS_MODULE,
+	.read_raw = &ad7150_read_raw,
+	.read_event_config = &ad7150_read_event_config,
+	.write_event_config = &ad7150_write_event_config,
+	.read_event_value = &ad7150_read_event_value,
+	.write_event_value = &ad7150_write_event_value,
 };
+
 /*
  * device probe and remove
  */
@@ -728,13 +663,16 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 		goto error_ret;
 	}
 	chip = iio_priv(indio_dev);
+	mutex_init(&chip->state_lock);
 	/* this is only used for device removal purposes */
 	i2c_set_clientdata(client, indio_dev);
 
 	chip->client = client;
 
-	/* Establish that the iio_dev is a child of the i2c device */
 	indio_dev->name = id->name;
+	indio_dev->channels = ad7150_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7150_channels);
+	/* Establish that the iio_dev is a child of the i2c device */
 	indio_dev->dev.parent = &client->dev;
 
 	indio_dev->info = &ad7150_info;
@@ -757,8 +695,8 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 	if (ret)
 		goto error_free_irq;
 
-
-	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
+	dev_info(&client->dev, "%s capacitive sensor registered,irq: %d\n",
+		 id->name, client->irq);
 
 	return 0;
 error_free_irq:
-- 
1.7.3.4

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

* [PATCH 03/16] staging:iio:adc:ad7150: remove conversion mode handling.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 01/16] staging:iio:dac:ad5791 chan spec conversion Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 02/16] staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 04/16] staging:iio:adc:ad7150: Add support for the second interrupt strobe Jonathan Cameron
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

The AD7150 family of devices power up in continues conversion mode.
We can stay in this mode, unless power consumption becomes a real issue.
Actually the event generation as well as the running average
relies on continues conversion mode, so we better stay there.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7150.c |   94 --------------------------------------
 1 files changed, 0 insertions(+), 94 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 0eb1992..deb0339 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -88,93 +88,10 @@ struct ad7150_chip_info {
 	struct mutex state_lock;
 };
 
-struct ad7150_conversion_mode {
-	char *name;
-	u8 reg_cfg;
-};
-
-static struct ad7150_conversion_mode
-ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
-	{ "idle", 0 },
-	{ "continuous-conversion", 1 },
-	{ "single-conversion", 2 },
-	{ "power-down", 3 },
-};
-
 /*
  * sysfs nodes
  */
 
-#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)			\
-	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
-
-static ssize_t ad7150_show_conversion_modes(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int i;
-	int len = 0;
-
-	for (i = 0; i < AD7150_MAX_CONV_MODE; i++)
-		len += sprintf(buf + len, "%s\n",
-			       ad7150_conv_mode_table[i].name);
-
-	return len;
-}
-
-static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7150_show_conversion_modes);
-
-static ssize_t ad7150_show_conversion_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%s\n", chip->conversion_mode);
-}
-
-static ssize_t ad7150_store_conversion_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 cfg;
-	int i, ret;
-
-	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
-	if (ret < 0)
-		return ret;
-	cfg = ret;
-
-	for (i = 0; i < AD7150_MAX_CONV_MODE; i++) {
-		if (strncmp(buf, ad7150_conv_mode_table[i].name,
-				strlen(ad7150_conv_mode_table[i].name) - 1) ==
-		    0) {
-			chip->conversion_mode = ad7150_conv_mode_table[i].name;
-			cfg |= 0x18 | ad7150_conv_mode_table[i].reg_cfg;
-			ret = i2c_smbus_write_byte_data(chip->client,
-							AD7150_CFG,
-							cfg);
-			if (ret < 0)
-				return ret;
-			return len;
-		}
-	}
-
-	dev_err(dev, "not supported conversion mode\n");
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
-		ad7150_show_conversion_mode,
-		ad7150_store_conversion_mode);
-
 static const u8 ad7150_addresses[][6] = {
 	{ AD7150_CH1_DATA_HIGH, AD7150_CH1_AVG_HIGH,
 	  AD7150_CH1_SETUP, AD7150_CH1_THR_HOLD_H,
@@ -542,16 +459,6 @@ static const struct iio_chan_spec ad7150_channels[] = {
 	},
 };
 
-static struct attribute *ad7150_attributes[] = {
-	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
-	&iio_dev_attr_conversion_mode.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7150_attribute_group = {
-	.attrs = ad7150_attributes,
-};
-
 /*
  * threshold events
  */
@@ -636,7 +543,6 @@ static struct attribute_group ad7150_event_attribute_group = {
 };
 
 static const struct iio_info ad7150_info = {
-	.attrs = &ad7150_attribute_group,
 	.event_attrs = &ad7150_event_attribute_group,
 	.driver_module = THIS_MODULE,
 	.read_raw = &ad7150_read_raw,
-- 
1.7.3.4

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

* [PATCH 04/16] staging:iio:adc:ad7150: Add support for the second interrupt strobe.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (2 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 03/16] staging:iio:adc:ad7150: remove conversion mode handling Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 05/16] staging:iio:adc:ad7152 use smbus read / write functions + checkpatch fixes Jonathan Cameron
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

The AD7150 features two outputs that can be used as interrupt strobes
to the host processor. In order to receive all events independently,
both need to utilized.

Update copyright notice.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7150.c |   38 +++++++++++++++++++++++++-------------
 1 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index deb0339..25f354c 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -1,7 +1,7 @@
 /*
  * AD7150 capacitive sensor driver supporting AD7150/1/6
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -45,14 +45,6 @@
 #define AD7150_SN0                 22
 #define AD7150_ID                  23
 
-#define AD7150_MAX_CONV_MODE       4
-
-/**
- * Todo list:
- * - Review whether old_state usage makes sense.
- * - get rid of explicit control of conversion mode
- */
-
 /**
  * struct ad7150_chip_info - instance specific chip data
  * @client: i2c client for this device
@@ -591,24 +583,40 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 					   &ad7150_event_handler,
 					   IRQF_TRIGGER_RISING |
 					   IRQF_TRIGGER_FALLING,
-					   "ad7150",
+					   "ad7150_irq1",
 					   indio_dev);
 		if (ret)
 			goto error_free_dev;
 	}
 
+	if (client->dev.platform_data) {
+		ret = request_threaded_irq(*(unsigned int *)
+					   client->dev.platform_data,
+					   NULL,
+					   &ad7150_event_handler,
+					   IRQF_TRIGGER_RISING |
+					   IRQF_TRIGGER_FALLING,
+					   "ad7150_irq2",
+					   indio_dev);
+		if (ret)
+			goto error_free_irq;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_free_irq;
+		goto error_free_irq2;
 
 	dev_info(&client->dev, "%s capacitive sensor registered,irq: %d\n",
 		 id->name, client->irq);
 
 	return 0;
+error_free_irq2:
+	if (client->dev.platform_data)
+		free_irq(*(unsigned int *)client->dev.platform_data,
+			 indio_dev);
 error_free_irq:
 	if (client->irq)
 		free_irq(client->irq, indio_dev);
-
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
@@ -621,6 +629,10 @@ static int __devexit ad7150_remove(struct i2c_client *client)
 
 	if (client->irq)
 		free_irq(client->irq, indio_dev);
+
+	if (client->dev.platform_data)
+		free_irq(*(unsigned int *)client->dev.platform_data, indio_dev);
+
 	iio_device_unregister(indio_dev);
 
 	return 0;
@@ -655,7 +667,7 @@ static __exit void ad7150_exit(void)
 }
 
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ad7150/1/6 capacitive sensor driver");
+MODULE_DESCRIPTION("Analog Devices AD7150/1/6 capacitive sensor driver");
 MODULE_LICENSE("GPL v2");
 
 module_init(ad7150_init);
-- 
1.7.3.4

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

* [PATCH 05/16] staging:iio:adc:ad7152 use smbus read / write functions + checkpatch fixes
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (3 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 04/16] staging:iio:adc:ad7150: Add support for the second interrupt strobe Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 06/16] staging:iio:adc:ad7152 set correct number of channels for ad7153 Jonathan Cameron
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

This is fine IF I  have read the data sheet correctly.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |  418 +++++++++++++------------------------
 1 files changed, 147 insertions(+), 271 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 21f5f38..8dbc00c 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -17,6 +17,9 @@
 #include "../sysfs.h"
 
 /*
+ * TODO: Check compliance of calibscale and calibbias with abi (units)
+ */
+/*
  * AD7152 registers definition
  */
 
@@ -24,18 +27,12 @@
 #define AD7152_STATUS_RDY1         (1 << 0)
 #define AD7152_STATUS_RDY2         (1 << 1)
 #define AD7152_CH1_DATA_HIGH       1
-#define AD7152_CH1_DATA_LOW        2
 #define AD7152_CH2_DATA_HIGH       3
-#define AD7152_CH2_DATA_LOW        4
 #define AD7152_CH1_OFFS_HIGH       5
-#define AD7152_CH1_OFFS_LOW        6
 #define AD7152_CH2_OFFS_HIGH       7
-#define AD7152_CH2_OFFS_LOW        8
 #define AD7152_CH1_GAIN_HIGH       9
-#define AD7152_CH1_GAIN_LOW        10
 #define AD7152_CH1_SETUP           11
 #define AD7152_CH2_GAIN_HIGH       12
-#define AD7152_CH2_GAIN_LOW        13
 #define AD7152_CH2_SETUP           14
 #define AD7152_CFG                 15
 #define AD7152_RESEVERD            16
@@ -51,13 +48,13 @@
 
 struct ad7152_chip_info {
 	struct i2c_client *client;
-	u16 ch1_offset;     /* Channel 1 offset calibration coefficient */
-	u16 ch1_gain;       /* Channel 1 gain coefficient */
 	u8  ch1_setup;
-	u16 ch2_offset;     /* Channel 2 offset calibration coefficient */
-	u16 ch2_gain;       /* Channel 1 gain coefficient */
 	u8  ch2_setup;
-	u8  filter_rate_setup; /* Capacitive channel digital filter setup; conversion time/update rate setup per channel */
+	/*
+	 * Capacitive channel digital filter setup;
+	 * conversion time/update rate setup per channel
+	 */
+	u8  filter_rate_setup;
 	char *conversion_mode;
 };
 
@@ -77,65 +74,13 @@ ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
 };
 
 /*
- * ad7152 register access by I2C
- */
-
-static int ad7152_i2c_read(struct ad7152_chip_info *chip, u8 reg, u8 *data, int len)
-{
-	struct i2c_client *client = chip->client;
-	int ret;
-
-	ret = i2c_master_send(client, &reg, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C write error\n");
-		return ret;
-	}
-
-	ret = i2c_master_recv(client, data, len);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C read error\n");
-	}
-
-	return ret;
-}
-
-static int ad7152_i2c_write(struct ad7152_chip_info *chip, u8 reg, u8 data)
-{
-	struct i2c_client *client = chip->client;
-	int ret;
-
-	u8 tx[2] = {
-		reg,
-		data,
-	};
-
-	ret = i2c_master_send(client, tx, 2);
-	if (ret < 0)
-		dev_err(&client->dev, "I2C write error\n");
-
-	return ret;
-}
-
-/*
  * sysfs nodes
  */
 
-#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)				\
+#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)			\
 	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
 #define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
 	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_OFFSET(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_offset, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_OFFSET(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch2_offset, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_GAIN(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_gain, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_GAIN(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch2_gain, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_VALUE(_show)		\
-	IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_CH2_VALUE(_show)		\
-	IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0)
 #define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store)		\
 	IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0)
 #define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store)              \
@@ -151,7 +96,8 @@ static ssize_t ad7152_show_conversion_modes(struct device *dev,
 	int len = 0;
 
 	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
-		len += sprintf(buf + len, "%s ", ad7152_conv_mode_table[i].name);
+		len += sprintf(buf + len, "%s ",
+			       ad7152_conv_mode_table[i].name);
 
 	len += sprintf(buf + len, "\n");
 
@@ -160,34 +106,6 @@ static ssize_t ad7152_show_conversion_modes(struct device *dev,
 
 static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7152_show_conversion_modes);
 
-static ssize_t ad7152_show_ch1_value(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
-
-	ad7152_i2c_read(chip, AD7152_CH1_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]);
-}
-
-static IIO_DEV_ATTR_CH1_VALUE(ad7152_show_ch1_value);
-
-static ssize_t ad7152_show_ch2_value(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
-
-	ad7152_i2c_read(chip, AD7152_CH2_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]);
-}
-
-static IIO_DEV_ATTR_CH2_VALUE(ad7152_show_ch2_value);
-
 static ssize_t ad7152_show_conversion_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -206,16 +124,23 @@ static ssize_t ad7152_store_conversion_mode(struct device *dev,
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
 	u8 cfg;
-	int i;
+	int i, ret;
 
-	ad7152_i2c_read(chip, AD7152_CFG, &cfg, 1);
+	ret = i2c_smbus_read_byte_data(chip->client, AD7152_CFG);
+	if (ret < 0)
+		return ret;
+	cfg = ret;
 
 	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
 		if (strncmp(buf, ad7152_conv_mode_table[i].name,
-				strlen(ad7152_conv_mode_table[i].name) - 1) == 0) {
+				strlen(ad7152_conv_mode_table[i].name) - 1) ==
+		    0) {
 			chip->conversion_mode = ad7152_conv_mode_table[i].name;
 			cfg |= 0x18 | ad7152_conv_mode_table[i].reg_cfg;
-			ad7152_i2c_write(chip, AD7152_CFG, cfg);
+			ret = i2c_smbus_write_byte_data(chip->client,
+							AD7152_CFG, cfg);
+			if (ret < 0)
+				return ret;
 			return len;
 		}
 
@@ -228,150 +153,6 @@ static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
 		ad7152_show_conversion_mode,
 		ad7152_store_conversion_mode);
 
-static ssize_t ad7152_show_ch1_offset(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch1_offset);
-}
-
-static ssize_t ad7152_store_ch1_offset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7152_i2c_write(chip, AD7152_CH1_OFFS_HIGH, data >> 8);
-		ad7152_i2c_write(chip, AD7152_CH1_OFFS_LOW, data);
-		chip->ch1_offset = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH1_OFFSET(S_IRUGO | S_IWUSR,
-		ad7152_show_ch1_offset,
-		ad7152_store_ch1_offset);
-
-static ssize_t ad7152_show_ch2_offset(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch2_offset);
-}
-
-static ssize_t ad7152_store_ch2_offset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7152_i2c_write(chip, AD7152_CH2_OFFS_HIGH, data >> 8);
-		ad7152_i2c_write(chip, AD7152_CH2_OFFS_LOW, data);
-		chip->ch2_offset = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH2_OFFSET(S_IRUGO | S_IWUSR,
-		ad7152_show_ch2_offset,
-		ad7152_store_ch2_offset);
-
-static ssize_t ad7152_show_ch1_gain(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch1_gain);
-}
-
-static ssize_t ad7152_store_ch1_gain(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7152_i2c_write(chip, AD7152_CH1_GAIN_HIGH, data >> 8);
-		ad7152_i2c_write(chip, AD7152_CH1_GAIN_LOW, data);
-		chip->ch1_gain = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH1_GAIN(S_IRUGO | S_IWUSR,
-		ad7152_show_ch1_gain,
-		ad7152_store_ch1_gain);
-
-static ssize_t ad7152_show_ch2_gain(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", chip->ch2_gain);
-}
-
-static ssize_t ad7152_store_ch2_gain(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x10000)) {
-		ad7152_i2c_write(chip, AD7152_CH2_GAIN_HIGH, data >> 8);
-		ad7152_i2c_write(chip, AD7152_CH2_GAIN_LOW, data);
-		chip->ch2_gain = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CH2_GAIN(S_IRUGO | S_IWUSR,
-		ad7152_show_ch2_gain,
-		ad7152_store_ch2_gain);
-
 static ssize_t ad7152_show_ch1_setup(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -389,18 +170,20 @@ static ssize_t ad7152_store_ch1_setup(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u8 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtou8(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
-	if ((!ret) && (data < 0x100)) {
-		ad7152_i2c_write(chip, AD7152_CH1_SETUP, data);
-		chip->ch1_setup = data;
-		return len;
-	}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CH1_SETUP, data);
+	if (ret < 0)
+		return ret;
 
-	return -EINVAL;
+	chip->ch1_setup = data;
+
+	return len;
 }
 
 static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
@@ -424,18 +207,20 @@ static ssize_t ad7152_store_ch2_setup(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u8 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtou8(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
-	if ((!ret) && (data < 0x100)) {
-		ad7152_i2c_write(chip, AD7152_CH2_SETUP, data);
-		chip->ch2_setup = data;
-		return len;
-	}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CH2_SETUP, data);
+	if (ret < 0)
+		return ret;
 
-	return -EINVAL;
+	chip->ch2_setup = data;
+
+	return len;
 }
 
 static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
@@ -459,18 +244,20 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u8 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtou8(buf, 10, &data);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CFG2, data);
+	if (ret < 0)
+		return ret;
 
-	if ((!ret) && (data < 0x100)) {
-		ad7152_i2c_write(chip, AD7152_CFG2, data);
-		chip->filter_rate_setup = data;
-		return len;
-	}
+	chip->filter_rate_setup = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
@@ -480,12 +267,6 @@ static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
 static struct attribute *ad7152_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
-	&iio_dev_attr_ch1_gain.dev_attr.attr,
-	&iio_dev_attr_ch2_gain.dev_attr.attr,
-	&iio_dev_attr_ch1_offset.dev_attr.attr,
-	&iio_dev_attr_ch2_offset.dev_attr.attr,
-	&iio_dev_attr_ch1_value.dev_attr.attr,
-	&iio_dev_attr_ch2_value.dev_attr.attr,
 	&iio_dev_attr_ch1_setup.dev_attr.attr,
 	&iio_dev_attr_ch2_setup.dev_attr.attr,
 	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
@@ -496,10 +277,103 @@ static const struct attribute_group ad7152_attribute_group = {
 	.attrs = ad7152_attributes,
 };
 
+static const u8 ad7152_addresses[][3] = {
+	{ AD7152_CH1_DATA_HIGH, AD7152_CH1_OFFS_HIGH, AD7152_CH1_GAIN_HIGH },
+	{ AD7152_CH2_DATA_HIGH, AD7152_CH2_OFFS_HIGH, AD7152_CH2_GAIN_HIGH },
+};
+static int ad7152_write_raw(struct iio_dev *dev_info,
+			    struct iio_chan_spec const *chan,
+			    int val,
+			    int val2,
+			    long mask)
+{
+	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	int ret;
+
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		if ((val < 0) | (val > 0xFFFF))
+			return -EINVAL;
+		ret = i2c_smbus_write_word_data(chip->client,
+					ad7152_addresses[chan->channel][2],
+					val);
+		if (ret < 0)
+			return ret;
+
+		return 0;
+
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		if ((val < 0) | (val > 0xFFFF))
+			return -EINVAL;
+		ret = i2c_smbus_write_word_data(chip->client,
+					ad7152_addresses[chan->channel][1],
+					val);
+		if (ret < 0)
+			return ret;
+
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+static int ad7152_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val, int *val2,
+			   long mask)
+{
+	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	int ret;
+
+	switch (mask) {
+	case 0:
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7152_addresses[chan->channel][0]);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		/* FIXME: Hmm. very small. it's 1+ 1/(2^16 *val) */
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7152_addresses[chan->channel][2]);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7152_addresses[chan->channel][1]);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	};
+}
 static const struct iio_info ad7152_info = {
 	.attrs = &ad7152_attribute_group,
+	.read_raw = &ad7152_read_raw,
+	.write_raw = &ad7152_write_raw,
 	.driver_module = THIS_MODULE,
 };
+
+static const struct iio_chan_spec ad7152_channels[] = {
+	{
+		.type = IIO_CAPACITANCE,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+	}, {
+		.type = IIO_CAPACITANCE,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+	}
+};
 /*
  * device probe and remove
  */
@@ -526,6 +400,8 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	indio_dev->name = id->name;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->info = &ad7152_info;
+	indio_dev->channels = ad7152_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(indio_dev);
-- 
1.7.3.4

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

* [PATCH 06/16] staging:iio:adc:ad7152 set correct number of channels for ad7153.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (4 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 05/16] staging:iio:adc:ad7152 use smbus read / write functions + checkpatch fixes Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 07/16] staging:iio:adc:ad7152 bring more into line with abi Jonathan Cameron
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Has been broken for some time.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 8dbc00c..5acaf8a 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -401,6 +401,10 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->info = &ad7152_info;
 	indio_dev->channels = ad7152_channels;
+	if (id->driver_data == 0)
+		indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
+	else
+		indio_dev->num_channels = 1;
 	indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
@@ -429,7 +433,7 @@ static int __devexit ad7152_remove(struct i2c_client *client)
 
 static const struct i2c_device_id ad7152_id[] = {
 	{ "ad7152", 0 },
-	{ "ad7153", 0 },
+	{ "ad7153", 1 },
 	{}
 };
 
-- 
1.7.3.4


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

* [PATCH 07/16] staging:iio:adc:ad7152 bring more into line with abi.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (5 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 06/16] staging:iio:adc:ad7152 set correct number of channels for ad7153 Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 08/16] staging:iio:adc:ad7152: increase readability by introducing proper bit defines Jonathan Cameron
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Get rid of explicit writes to registers and conversion mode
control.

Couple of bits I'm unsure about.
* Do calibration modes self reset when done?  How do you tell they are
done?

* Should we poll the status register just to be sure we have a new conversion?

All done sans hardware.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |  294 +++++++++++++++++---------------------
 1 files changed, 129 insertions(+), 165 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 5acaf8a..debcea5 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/i2c.h>
+#include <linux/delay.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -48,184 +49,71 @@
 
 struct ad7152_chip_info {
 	struct i2c_client *client;
-	u8  ch1_setup;
-	u8  ch2_setup;
 	/*
 	 * Capacitive channel digital filter setup;
 	 * conversion time/update rate setup per channel
 	 */
 	u8  filter_rate_setup;
-	char *conversion_mode;
 };
 
-struct ad7152_conversion_mode {
-	char *name;
-	u8 reg_cfg;
-};
-
-static struct ad7152_conversion_mode
-ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
-	{ "idle", 0 },
-	{ "continuous-conversion", 1 },
-	{ "single-conversion", 2 },
-	{ "power-down", 3 },
-	{ "offset-calibration", 5 },
-	{ "gain-calibration", 6 },
-};
-
-/*
- * sysfs nodes
- */
-
-#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)			\
-	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
-#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store)		\
-	IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0)
-#define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0)
-
-static ssize_t ad7152_show_conversion_modes(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int i;
-	int len = 0;
-
-	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
-		len += sprintf(buf + len, "%s ",
-			       ad7152_conv_mode_table[i].name);
-
-	len += sprintf(buf + len, "\n");
-
-	return len;
-}
-
-static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7152_show_conversion_modes);
-
-static ssize_t ad7152_show_conversion_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static inline ssize_t ad7152_start_calib(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf,
+					 size_t len,
+					 u8 regval)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	bool doit;
+	int ret;
 
-	return sprintf(buf, "%s\n", chip->conversion_mode);
-}
-
-static ssize_t ad7152_store_conversion_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	u8 cfg;
-	int i, ret;
-
-	ret = i2c_smbus_read_byte_data(chip->client, AD7152_CFG);
+	ret = strtobool(buf, &doit);
 	if (ret < 0)
 		return ret;
-	cfg = ret;
-
-	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
-		if (strncmp(buf, ad7152_conv_mode_table[i].name,
-				strlen(ad7152_conv_mode_table[i].name) - 1) ==
-		    0) {
-			chip->conversion_mode = ad7152_conv_mode_table[i].name;
-			cfg |= 0x18 | ad7152_conv_mode_table[i].reg_cfg;
-			ret = i2c_smbus_write_byte_data(chip->client,
-							AD7152_CFG, cfg);
-			if (ret < 0)
-				return ret;
-			return len;
-		}
-
-	dev_err(dev, "not supported conversion mode\n");
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
-		ad7152_show_conversion_mode,
-		ad7152_store_conversion_mode);
-
-static ssize_t ad7152_show_ch1_setup(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "0x%02x\n", chip->ch1_setup);
-}
 
-static ssize_t ad7152_store_ch1_setup(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	u8 data;
-	int ret;
+	if (!doit)
+		return 0;
 
-	ret = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return ret;
+	if (this_attr->address == 0)
+		regval |= (1 << 4);
+	else
+		regval |= (1 << 3);
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CH1_SETUP, data);
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CFG, regval);
 	if (ret < 0)
 		return ret;
-
-	chip->ch1_setup = data;
-
+	/* Unclear on period this should be set for or whether it flips back
+	 * to idle automatically */
 	return len;
 }
-
-static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
-		ad7152_show_ch1_setup,
-		ad7152_store_ch1_setup);
-
-static ssize_t ad7152_show_ch2_setup(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static ssize_t ad7152_start_offset_calib(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf,
+					 size_t len)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
 
-	return sprintf(buf, "0x%02x\n", chip->ch2_setup);
+	return ad7152_start_calib(dev, attr, buf, len, 5);
 }
-
-static ssize_t ad7152_store_ch2_setup(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static ssize_t ad7152_start_gain_calib(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf,
+				       size_t len)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	u8 data;
-	int ret;
-
-	ret = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CH2_SETUP, data);
-	if (ret < 0)
-		return ret;
-
-	chip->ch2_setup = data;
-
-	return len;
+	return ad7152_start_calib(dev, attr, buf, len, 6);
 }
 
-static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
-		ad7152_show_ch2_setup,
-		ad7152_store_ch2_setup);
+static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
+		       S_IWUSR, NULL, ad7152_start_offset_calib, 0);
+static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
+		       S_IWUSR, NULL, ad7152_start_offset_calib, 1);
+static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
+		       S_IWUSR, NULL, ad7152_start_gain_calib, 0);
+static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
+		       S_IWUSR, NULL, ad7152_start_gain_calib, 1);
+
+#define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0)
 
 static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
 		struct device_attribute *attr,
@@ -265,11 +153,11 @@ static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
 		ad7152_store_filter_rate_setup);
 
 static struct attribute *ad7152_attributes[] = {
-	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
-	&iio_dev_attr_conversion_mode.dev_attr.attr,
-	&iio_dev_attr_ch1_setup.dev_attr.attr,
-	&iio_dev_attr_ch2_setup.dev_attr.attr,
 	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
+	&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
+	&iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
 	NULL,
 };
 
@@ -277,10 +165,18 @@ static const struct attribute_group ad7152_attribute_group = {
 	.attrs = ad7152_attributes,
 };
 
-static const u8 ad7152_addresses[][3] = {
-	{ AD7152_CH1_DATA_HIGH, AD7152_CH1_OFFS_HIGH, AD7152_CH1_GAIN_HIGH },
-	{ AD7152_CH2_DATA_HIGH, AD7152_CH2_OFFS_HIGH, AD7152_CH2_GAIN_HIGH },
+static const u8 ad7152_addresses[][4] = {
+	{ AD7152_CH1_DATA_HIGH, AD7152_CH1_OFFS_HIGH,
+	  AD7152_CH1_GAIN_HIGH, AD7152_CH1_SETUP },
+	{ AD7152_CH2_DATA_HIGH, AD7152_CH2_OFFS_HIGH,
+	  AD7152_CH2_GAIN_HIGH, AD7152_CH2_SETUP },
+};
+
+/* Values are micro relative to pf base. */
+static const int ad7152_scale_table[] = {
+	488, 244, 122, 61
 };
+
 static int ad7152_write_raw(struct iio_dev *dev_info,
 			    struct iio_chan_spec const *chan,
 			    int val,
@@ -288,7 +184,7 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 			    long mask)
 {
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
-	int ret;
+	int ret, i;
 
 	switch (mask) {
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
@@ -312,7 +208,24 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 			return ret;
 
 		return 0;
-
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		if (val != 0)
+			return -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
+			if (val2 <= ad7152_scale_table[i])
+				break;
+		ret = i2c_smbus_read_byte_data(chip->client,
+					ad7152_addresses[chan->channel][3]);
+		if (ret < 0)
+			return ret;
+		if ((ret & 0xC0) != i)
+			ret = i2c_smbus_write_byte_data(chip->client,
+					ad7152_addresses[chan->channel][3],
+					(ret & ~0xC0) | i);
+		if (ret < 0)
+			return ret;
+		else
+			return 0;
 	default:
 		return -EINVAL;
 	}
@@ -324,14 +237,34 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 {
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
 	int ret;
-
+	u8 regval = 0;
 	switch (mask) {
 	case 0:
+		/* First set whether in differential mode */
+		if (chan->differential)
+			regval = (1 << 5);
+
+		/* Make sure the channel is enabled */
+		if (chan->channel == 0)
+			regval |= (1 << 4);
+		else
+			regval |= (1 << 3);
+		/* Trigger a single read */
+		regval |= 0x02;
+		ret = i2c_smbus_write_byte_data(chip->client,
+					ad7152_addresses[chan->channel][3],
+					regval);
+		if (ret < 0)
+			return ret;
+
+		msleep(60); /* Slowest conversion time */
+		/* Now read the actual register */
 		ret = i2c_smbus_read_word_data(chip->client,
 					ad7152_addresses[chan->channel][0]);
 		if (ret < 0)
 			return ret;
 		*val = ret;
+
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 		/* FIXME: Hmm. very small. it's 1+ 1/(2^16 *val) */
@@ -340,6 +273,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		if (ret < 0)
 			return ret;
 		*val = ret;
+
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		ret = i2c_smbus_read_word_data(chip->client,
@@ -347,7 +281,17 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		if (ret < 0)
 			return ret;
 		*val = ret;
+
 		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		ret = i2c_smbus_read_byte_data(chip->client,
+					ad7152_addresses[chan->channel][3]);
+		if (ret < 0)
+			return ret;
+		*val = 0;
+		*val2 = ad7152_scale_table[ret >> 6];
+
+		return IIO_VAL_INT_PLUS_MICRO;
 	default:
 		return -EINVAL;
 	};
@@ -365,13 +309,33 @@ static const struct iio_chan_spec ad7152_channels[] = {
 		.indexed = 1,
 		.channel = 0,
 		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+	}, {
+		.type = IIO_CAPACITANCE,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+	}, {
+		.type = IIO_CAPACITANCE,
+		.differential = 1,
+		.indexed = 1,
+		.channel = 0,
+		.channel2 = 2,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
 	}, {
 		.type = IIO_CAPACITANCE,
+		.differential = 1,
 		.indexed = 1,
 		.channel = 1,
+		.channel2 = 3,
 		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
 	}
 };
 /*
@@ -404,7 +368,7 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 	if (id->driver_data == 0)
 		indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 	else
-		indio_dev->num_channels = 1;
+		indio_dev->num_channels = 2;
 	indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-- 
1.7.3.4

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

* [PATCH 08/16] staging:iio:adc:ad7152: increase readability by introducing proper bit defines
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (6 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 07/16] staging:iio:adc:ad7152 bring more into line with abi Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 09/16] staging:iio:adc:ad7152: Miscellaneous fixes and touch-up Jonathan Cameron
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Some other miscellaneous cleanup.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |  133 +++++++++++++++++++++++--------------
 1 files changed, 83 insertions(+), 50 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index debcea5..b0db745 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -1,7 +1,7 @@
 /*
  * AD7152 capacitive sensor driver supporting AD7152/3
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011a Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -24,24 +24,55 @@
  * AD7152 registers definition
  */
 
-#define AD7152_STATUS              0
-#define AD7152_STATUS_RDY1         (1 << 0)
-#define AD7152_STATUS_RDY2         (1 << 1)
-#define AD7152_CH1_DATA_HIGH       1
-#define AD7152_CH2_DATA_HIGH       3
-#define AD7152_CH1_OFFS_HIGH       5
-#define AD7152_CH2_OFFS_HIGH       7
-#define AD7152_CH1_GAIN_HIGH       9
-#define AD7152_CH1_SETUP           11
-#define AD7152_CH2_GAIN_HIGH       12
-#define AD7152_CH2_SETUP           14
-#define AD7152_CFG                 15
-#define AD7152_RESEVERD            16
-#define AD7152_CAPDAC_POS          17
-#define AD7152_CAPDAC_NEG          18
-#define AD7152_CFG2                26
-
-#define AD7152_MAX_CONV_MODE       6
+#define AD7152_REG_STATUS		0
+#define AD7152_REG_CH1_DATA_HIGH	1
+#define AD7152_REG_CH2_DATA_HIGH	3
+#define AD7152_REG_CH1_OFFS_HIGH	5
+#define AD7152_REG_CH2_OFFS_HIGH	7
+#define AD7152_REG_CH1_GAIN_HIGH	9
+#define AD7152_REG_CH1_SETUP		11
+#define AD7152_REG_CH2_GAIN_HIGH	12
+#define AD7152_REG_CH2_SETUP		14
+#define AD7152_REG_CFG			15
+#define AD7152_REG_RESEVERD		16
+#define AD7152_REG_CAPDAC_POS		17
+#define AD7152_REG_CAPDAC_NEG		18
+#define AD7152_REG_CFG2			26
+
+/* Status Register Bit Designations (AD7152_REG_STATUS) */
+#define AD7152_STATUS_RDY1		(1 << 0)
+#define AD7152_STATUS_RDY2		(1 << 1)
+#define AD7152_STATUS_C1C2		(1 << 2)
+#define AD7152_STATUS_PWDN		(1 << 7)
+
+/* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */
+#define AD7152_SETUP_CAPDIFF		(1 << 5)
+#define AD7152_SETUP_RANGE_2pF		(0 << 6)
+#define AD7152_SETUP_RANGE_0_5pF	(1 << 6)
+#define AD7152_SETUP_RANGE_1pF		(2 << 6)
+#define AD7152_SETUP_RANGE_4pF		(3 << 6)
+
+/* Config Register Bit Designations (AD7152_REG_CFG) */
+#define AD7152_CONF_CH2EN		(1 << 3)
+#define AD7152_CONF_CH1EN		(1 << 4)
+#define AD7152_CONF_MODE_IDLE		(0 << 0)
+#define AD7152_CONF_MODE_CONT_CONV	(1 << 0)
+#define AD7152_CONF_MODE_SINGLE_CONV	(2 << 0)
+#define AD7152_CONF_MODE_OFFS_CAL	(5 << 0)
+#define AD7152_CONF_MODE_GAIN_CAL	(6 << 0)
+
+/* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */
+#define AD7152_CAPDAC_DACEN		(1 << 7)
+#define AD7152_CAPDAC_DACP(x)		((x) & 0x1F)
+
+#define AD7152_MAX_CONV_MODE		6
+
+enum {
+	AD7152_DATA,
+	AD7152_OFFS,
+	AD7152_GAIN,
+	AD7152_SETUP
+};
 
 /*
  * struct ad7152_chip_info - chip specifc information
@@ -76,11 +107,11 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
 		return 0;
 
 	if (this_attr->address == 0)
-		regval |= (1 << 4);
+		regval |= AD7152_CONF_CH1EN;
 	else
-		regval |= (1 << 3);
+		regval |= AD7152_CONF_CH2EN;
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CFG, regval);
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
 	if (ret < 0)
 		return ret;
 	/* Unclear on period this should be set for or whether it flips back
@@ -93,14 +124,16 @@ static ssize_t ad7152_start_offset_calib(struct device *dev,
 					 size_t len)
 {
 
-	return ad7152_start_calib(dev, attr, buf, len, 5);
+	return ad7152_start_calib(dev, attr, buf, len,
+				  AD7152_CONF_MODE_OFFS_CAL);
 }
 static ssize_t ad7152_start_gain_calib(struct device *dev,
 				       struct device_attribute *attr,
 				       const char *buf,
 				       size_t len)
 {
-	return ad7152_start_calib(dev, attr, buf, len, 6);
+	return ad7152_start_calib(dev, attr, buf, len,
+				  AD7152_CONF_MODE_GAIN_CAL);
 }
 
 static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
@@ -139,7 +172,7 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
 	if (ret < 0)
 		return ret;
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7152_CFG2, data);
+	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG2, data);
 	if (ret < 0)
 		return ret;
 
@@ -166,10 +199,10 @@ static const struct attribute_group ad7152_attribute_group = {
 };
 
 static const u8 ad7152_addresses[][4] = {
-	{ AD7152_CH1_DATA_HIGH, AD7152_CH1_OFFS_HIGH,
-	  AD7152_CH1_GAIN_HIGH, AD7152_CH1_SETUP },
-	{ AD7152_CH2_DATA_HIGH, AD7152_CH2_OFFS_HIGH,
-	  AD7152_CH2_GAIN_HIGH, AD7152_CH2_SETUP },
+	{ AD7152_REG_CH1_DATA_HIGH, AD7152_REG_CH1_OFFS_HIGH,
+	  AD7152_REG_CH1_GAIN_HIGH, AD7152_REG_CH1_SETUP },
+	{ AD7152_REG_CH2_DATA_HIGH, AD7152_REG_CH2_OFFS_HIGH,
+	  AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP },
 };
 
 /* Values are micro relative to pf base. */
@@ -191,8 +224,8 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 		if ((val < 0) | (val > 0xFFFF))
 			return -EINVAL;
 		ret = i2c_smbus_write_word_data(chip->client,
-					ad7152_addresses[chan->channel][2],
-					val);
+				ad7152_addresses[chan->channel][AD7152_GAIN],
+				val);
 		if (ret < 0)
 			return ret;
 
@@ -202,8 +235,8 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 		if ((val < 0) | (val > 0xFFFF))
 			return -EINVAL;
 		ret = i2c_smbus_write_word_data(chip->client,
-					ad7152_addresses[chan->channel][1],
-					val);
+				ad7152_addresses[chan->channel][AD7152_OFFS],
+				val);
 		if (ret < 0)
 			return ret;
 
@@ -215,13 +248,13 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 			if (val2 <= ad7152_scale_table[i])
 				break;
 		ret = i2c_smbus_read_byte_data(chip->client,
-					ad7152_addresses[chan->channel][3]);
+				ad7152_addresses[chan->channel][AD7152_SETUP]);
 		if (ret < 0)
 			return ret;
 		if ((ret & 0xC0) != i)
 			ret = i2c_smbus_write_byte_data(chip->client,
-					ad7152_addresses[chan->channel][3],
-					(ret & ~0xC0) | i);
+				ad7152_addresses[chan->channel][AD7152_SETUP],
+				(ret & ~0xC0) | i);
 		if (ret < 0)
 			return ret;
 		else
@@ -242,25 +275,25 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 	case 0:
 		/* First set whether in differential mode */
 		if (chan->differential)
-			regval = (1 << 5);
+			regval = AD7152_SETUP_CAPDIFF;
 
 		/* Make sure the channel is enabled */
-		if (chan->channel == 0)
-			regval |= (1 << 4);
+		if (chan->address == 0)
+			regval |= AD7152_CONF_CH1EN;
 		else
-			regval |= (1 << 3);
+			regval |= AD7152_CONF_CH2EN;
 		/* Trigger a single read */
-		regval |= 0x02;
+		regval |= AD7152_CONF_MODE_SINGLE_CONV;
 		ret = i2c_smbus_write_byte_data(chip->client,
-					ad7152_addresses[chan->channel][3],
-					regval);
+				ad7152_addresses[chan->channel][AD7152_SETUP],
+				regval);
 		if (ret < 0)
 			return ret;
 
 		msleep(60); /* Slowest conversion time */
 		/* Now read the actual register */
 		ret = i2c_smbus_read_word_data(chip->client,
-					ad7152_addresses[chan->channel][0]);
+				ad7152_addresses[chan->channel][AD7152_DATA]);
 		if (ret < 0)
 			return ret;
 		*val = ret;
@@ -269,7 +302,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 		/* FIXME: Hmm. very small. it's 1+ 1/(2^16 *val) */
 		ret = i2c_smbus_read_word_data(chip->client,
-					ad7152_addresses[chan->channel][2]);
+				ad7152_addresses[chan->channel][AD7152_GAIN]);
 		if (ret < 0)
 			return ret;
 		*val = ret;
@@ -277,7 +310,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		ret = i2c_smbus_read_word_data(chip->client,
-					ad7152_addresses[chan->channel][1]);
+				ad7152_addresses[chan->channel][AD7152_OFFS]);
 		if (ret < 0)
 			return ret;
 		*val = ret;
@@ -285,7 +318,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
 		ret = i2c_smbus_read_byte_data(chip->client,
-					ad7152_addresses[chan->channel][3]);
+				ad7152_addresses[chan->channel][AD7152_SETUP]);
 		if (ret < 0)
 			return ret;
 		*val = 0;
@@ -360,7 +393,7 @@ static int __devinit ad7152_probe(struct i2c_client *client,
 
 	chip->client = client;
 
-	/* Echipabilish that the iio_dev is a child of the i2c device */
+	/* Establish that the iio_dev is a child of the i2c device */
 	indio_dev->name = id->name;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->info = &ad7152_info;
@@ -405,7 +438,7 @@ MODULE_DEVICE_TABLE(i2c, ad7152_id);
 
 static struct i2c_driver ad7152_driver = {
 	.driver = {
-		.name = "ad7152",
+		.name = KBUILD_MODNAME,
 	},
 	.probe = ad7152_probe,
 	.remove = __devexit_p(ad7152_remove),
@@ -423,7 +456,7 @@ static __exit void ad7152_exit(void)
 }
 
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ad7152/3 capacitive sensor driver");
+MODULE_DESCRIPTION("Analog Devices AD7152/3 capacitive sensor driver");
 MODULE_LICENSE("GPL v2");
 
 module_init(ad7152_init);
-- 
1.7.3.4

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

* [PATCH 09/16] staging:iio:adc:ad7152: Miscellaneous fixes and touch-up
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (7 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 08/16] staging:iio:adc:ad7152: increase readability by introducing proper bit defines Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 10/16] staging:iio:adc:ad7152: update scale handling Jonathan Cameron
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Remove unused define.
Introduce cached SETUP variables.
Wait until calibration finished. (Device returns to idle state)
IIO_CHAN_INFO_CALIBSCALE_SEPARATE use proper scales. (range 1.0 to 1.99999)
i2c_smbus word transactions expect low byte first, therefore swap bytes.
CAPDIFF is bit in SETUP not CFG.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |   77 ++++++++++++++++++++++++--------------
 1 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index b0db745..0f653f5 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -51,6 +51,7 @@
 #define AD7152_SETUP_RANGE_0_5pF	(1 << 6)
 #define AD7152_SETUP_RANGE_1pF		(2 << 6)
 #define AD7152_SETUP_RANGE_4pF		(3 << 6)
+#define AD7152_SETUP_RANGE(x)		((x) << 6)
 
 /* Config Register Bit Designations (AD7152_REG_CFG) */
 #define AD7152_CONF_CH2EN		(1 << 3)
@@ -65,8 +66,6 @@
 #define AD7152_CAPDAC_DACEN		(1 << 7)
 #define AD7152_CAPDAC_DACP(x)		((x) & 0x1F)
 
-#define AD7152_MAX_CONV_MODE		6
-
 enum {
 	AD7152_DATA,
 	AD7152_OFFS,
@@ -84,7 +83,8 @@ struct ad7152_chip_info {
 	 * Capacitive channel digital filter setup;
 	 * conversion time/update rate setup per channel
 	 */
-	u8  filter_rate_setup;
+	u8	filter_rate_setup;
+	u8	setup[2];
 };
 
 static inline ssize_t ad7152_start_calib(struct device *dev,
@@ -97,7 +97,7 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
 	struct ad7152_chip_info *chip = iio_priv(dev_info);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	bool doit;
-	int ret;
+	int ret, timeout = 10;
 
 	ret = strtobool(buf, &doit);
 	if (ret < 0)
@@ -114,8 +114,14 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
 	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
 	if (ret < 0)
 		return ret;
-	/* Unclear on period this should be set for or whether it flips back
-	 * to idle automatically */
+
+	do {
+		mdelay(20);
+		ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
+		if (ret < 0)
+			return ret;
+	} while ((ret == regval) && timeout--);
+
 	return len;
 }
 static ssize_t ad7152_start_offset_calib(struct device *dev,
@@ -123,7 +129,6 @@ static ssize_t ad7152_start_offset_calib(struct device *dev,
 					 const char *buf,
 					 size_t len)
 {
-
 	return ad7152_start_calib(dev, attr, buf, len,
 				  AD7152_CONF_MODE_OFFS_CAL);
 }
@@ -221,11 +226,14 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 
 	switch (mask) {
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
-		if ((val < 0) | (val > 0xFFFF))
+		if (val != 1)
 			return -EINVAL;
+
+		val = (val2 * 1024) / 15625;
+
 		ret = i2c_smbus_write_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_GAIN],
-				val);
+				swab16(val));
 		if (ret < 0)
 			return ret;
 
@@ -236,7 +244,7 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 			return -EINVAL;
 		ret = i2c_smbus_write_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_OFFS],
-				val);
+				swab16(val));
 		if (ret < 0)
 			return ret;
 
@@ -247,14 +255,13 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 		for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
 			if (val2 <= ad7152_scale_table[i])
 				break;
-		ret = i2c_smbus_read_byte_data(chip->client,
-				ad7152_addresses[chan->channel][AD7152_SETUP]);
-		if (ret < 0)
-			return ret;
-		if ((ret & 0xC0) != i)
-			ret = i2c_smbus_write_byte_data(chip->client,
+
+		chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF;
+		chip->setup[chan->channel] |= AD7152_SETUP_RANGE(i);
+
+		ret = i2c_smbus_write_byte_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_SETUP],
-				(ret & ~0xC0) | i);
+				chip->setup[chan->channel]);
 		if (ret < 0)
 			return ret;
 		else
@@ -274,18 +281,30 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 	switch (mask) {
 	case 0:
 		/* First set whether in differential mode */
+
+		regval = chip->setup[chan->channel];
+
 		if (chan->differential)
-			regval = AD7152_SETUP_CAPDIFF;
+			chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF;
+		else
+			chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF;
 
+		if (regval != chip->setup[chan->channel]) {
+			ret = i2c_smbus_write_byte_data(chip->client,
+				ad7152_addresses[chan->channel][AD7152_SETUP],
+				chip->setup[chan->channel]);
+			if (ret < 0)
+				return ret;
+		}
 		/* Make sure the channel is enabled */
-		if (chan->address == 0)
-			regval |= AD7152_CONF_CH1EN;
+		if (chan->channel == 0)
+			regval = AD7152_CONF_CH1EN;
 		else
-			regval |= AD7152_CONF_CH2EN;
+			regval = AD7152_CONF_CH2EN;
+
 		/* Trigger a single read */
 		regval |= AD7152_CONF_MODE_SINGLE_CONV;
-		ret = i2c_smbus_write_byte_data(chip->client,
-				ad7152_addresses[chan->channel][AD7152_SETUP],
+		ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
 				regval);
 		if (ret < 0)
 			return ret;
@@ -296,24 +315,26 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 				ad7152_addresses[chan->channel][AD7152_DATA]);
 		if (ret < 0)
 			return ret;
-		*val = ret;
+		*val = swab16(ret);
 
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
-		/* FIXME: Hmm. very small. it's 1+ 1/(2^16 *val) */
+
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_GAIN]);
 		if (ret < 0)
 			return ret;
-		*val = ret;
+		/* 1 + gain_val / 2^16 */
+		*val = 1;
+		*val2 = (15625 * swab16(ret)) / 1024;
 
-		return IIO_VAL_INT;
+		return IIO_VAL_INT_PLUS_MICRO;
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_OFFS]);
 		if (ret < 0)
 			return ret;
-		*val = ret;
+		*val = swab16(ret);
 
 		return IIO_VAL_INT;
 	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-- 
1.7.3.4

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

* [PATCH 10/16] staging:iio:adc:ad7152: update scale handling
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (8 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 09/16] staging:iio:adc:ad7152: Miscellaneous fixes and touch-up Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 11/16] staging:iio:adc:ad7152: Add proper locking Jonathan Cameron
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Add scale_available attribute.
fix ad7152_scale_table, values are not sorted descending.
Use IIO_VAL_INT_PLUS_NANO, to increase granularity.
Update scale handling accordingly.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |   26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 0f653f5..d3ffcdf 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -190,12 +190,16 @@ static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
 		ad7152_show_filter_rate_setup,
 		ad7152_store_filter_rate_setup);
 
+static IIO_CONST_ATTR(in_capacitance_scale_available,
+		      "0.000061050 0.000030525 0.000015263 0.000007631");
+
 static struct attribute *ad7152_attributes[] = {
 	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
 	&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
+	&iio_const_attr_in_capacitance_scale_available.dev_attr.attr,
 	NULL,
 };
 
@@ -210,9 +214,9 @@ static const u8 ad7152_addresses[][4] = {
 	  AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP },
 };
 
-/* Values are micro relative to pf base. */
+/* Values are nano relative to pf base. */
 static const int ad7152_scale_table[] = {
-	488, 244, 122, 61
+	30525, 7631, 15263, 61050
 };
 
 static int ad7152_write_raw(struct iio_dev *dev_info,
@@ -253,7 +257,7 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 		if (val != 0)
 			return -EINVAL;
 		for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
-			if (val2 <= ad7152_scale_table[i])
+			if (val2 == ad7152_scale_table[i])
 				break;
 
 		chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF;
@@ -345,15 +349,29 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		*val = 0;
 		*val2 = ad7152_scale_table[ret >> 6];
 
-		return IIO_VAL_INT_PLUS_MICRO;
+		return IIO_VAL_INT_PLUS_NANO;
 	default:
 		return -EINVAL;
 	};
 }
+
+static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       long mask)
+{
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		return IIO_VAL_INT_PLUS_NANO;
+	default:
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+}
+
 static const struct iio_info ad7152_info = {
 	.attrs = &ad7152_attribute_group,
 	.read_raw = &ad7152_read_raw,
 	.write_raw = &ad7152_write_raw,
+	.write_raw_get_fmt = &ad7152_write_raw_get_fmt,
 	.driver_module = THIS_MODULE,
 };
 
-- 
1.7.3.4

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

* [PATCH 11/16] staging:iio:adc:ad7152: Add proper locking
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (9 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 10/16] staging:iio:adc:ad7152: update scale handling Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 12/16] staging:iio:adc:ad7152: Update sample rate, conversion time, digital filter handling Jonathan Cameron
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Add proper locking.
Consistently use indio_dev.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |  109 ++++++++++++++++++++++++-------------
 1 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index d3ffcdf..bf26d38 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -18,7 +18,7 @@
 #include "../sysfs.h"
 
 /*
- * TODO: Check compliance of calibscale and calibbias with abi (units)
+ * TODO: Check compliance of calibbias with abi (units)
  */
 /*
  * AD7152 registers definition
@@ -93,8 +93,8 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
 					 size_t len,
 					 u8 regval)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	bool doit;
 	int ret, timeout = 10;
@@ -111,17 +111,23 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
 	else
 		regval |= AD7152_CONF_CH2EN;
 
+	mutex_lock(&indio_dev->mlock);
 	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
-	if (ret < 0)
+	if (ret < 0) {
+		mutex_unlock(&indio_dev->mlock);
 		return ret;
+	}
 
 	do {
 		mdelay(20);
 		ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
-		if (ret < 0)
+		if (ret < 0) {
+			mutex_unlock(&indio_dev->mlock);
 			return ret;
+		}
 	} while ((ret == regval) && timeout--);
 
+	mutex_unlock(&indio_dev->mlock);
 	return len;
 }
 static ssize_t ad7152_start_offset_calib(struct device *dev,
@@ -157,8 +163,8 @@ static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 
 	return sprintf(buf, "0x%02x\n", chip->filter_rate_setup);
 }
@@ -168,8 +174,8 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
 		const char *buf,
 		size_t len)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 	u8 data;
 	int ret;
 
@@ -177,11 +183,13 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
 	if (ret < 0)
 		return ret;
 
+	mutex_lock(&indio_dev->mlock);
 	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG2, data);
 	if (ret < 0)
 		return ret;
 
 	chip->filter_rate_setup = data;
+	mutex_unlock(&indio_dev->mlock);
 
 	return len;
 }
@@ -219,19 +227,23 @@ static const int ad7152_scale_table[] = {
 	30525, 7631, 15263, 61050
 };
 
-static int ad7152_write_raw(struct iio_dev *dev_info,
+static int ad7152_write_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int val,
 			    int val2,
 			    long mask)
 {
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 	int ret, i;
 
+	mutex_lock(&indio_dev->mlock);
+
 	switch (mask) {
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
-		if (val != 1)
-			return -EINVAL;
+		if (val != 1) {
+			ret = -EINVAL;
+			goto out;
+		}
 
 		val = (val2 * 1024) / 15625;
 
@@ -239,23 +251,29 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 				ad7152_addresses[chan->channel][AD7152_GAIN],
 				swab16(val));
 		if (ret < 0)
-			return ret;
+			goto out;
 
-		return 0;
+		ret = 0;
+		break;
 
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
-		if ((val < 0) | (val > 0xFFFF))
-			return -EINVAL;
+		if ((val < 0) | (val > 0xFFFF)) {
+			ret = -EINVAL;
+			goto out;
+		}
 		ret = i2c_smbus_write_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_OFFS],
 				swab16(val));
 		if (ret < 0)
-			return ret;
+			goto out;
 
-		return 0;
+		ret = 0;
+		break;
 	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-		if (val != 0)
-			return -EINVAL;
+		if (val != 0) {
+			ret = -EINVAL;
+			goto out;
+		}
 		for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
 			if (val2 == ad7152_scale_table[i])
 				break;
@@ -267,21 +285,29 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
 				ad7152_addresses[chan->channel][AD7152_SETUP],
 				chip->setup[chan->channel]);
 		if (ret < 0)
-			return ret;
-		else
-			return 0;
+			goto out;
+
+		ret = 0;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
 }
-static int ad7152_read_raw(struct iio_dev *dev_info,
+static int ad7152_read_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan,
 			   int *val, int *val2,
 			   long mask)
 {
-	struct ad7152_chip_info *chip = iio_priv(dev_info);
+	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 	int ret;
 	u8 regval = 0;
+
+	mutex_lock(&indio_dev->mlock);
+
 	switch (mask) {
 	case 0:
 		/* First set whether in differential mode */
@@ -298,7 +324,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 				ad7152_addresses[chan->channel][AD7152_SETUP],
 				chip->setup[chan->channel]);
 			if (ret < 0)
-				return ret;
+				goto out;
 		}
 		/* Make sure the channel is enabled */
 		if (chan->channel == 0)
@@ -311,48 +337,55 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
 		ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
 				regval);
 		if (ret < 0)
-			return ret;
+			goto out;
 
 		msleep(60); /* Slowest conversion time */
 		/* Now read the actual register */
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_DATA]);
 		if (ret < 0)
-			return ret;
+			goto out;
 		*val = swab16(ret);
 
-		return IIO_VAL_INT;
+		ret = IIO_VAL_INT;
+		break;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_GAIN]);
 		if (ret < 0)
-			return ret;
+			goto out;
 		/* 1 + gain_val / 2^16 */
 		*val = 1;
 		*val2 = (15625 * swab16(ret)) / 1024;
 
-		return IIO_VAL_INT_PLUS_MICRO;
+		ret = IIO_VAL_INT_PLUS_MICRO;
+		break;
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_OFFS]);
 		if (ret < 0)
-			return ret;
+			goto out;
 		*val = swab16(ret);
 
-		return IIO_VAL_INT;
+		ret = IIO_VAL_INT;
+		break;
 	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
 		ret = i2c_smbus_read_byte_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_SETUP]);
 		if (ret < 0)
-			return ret;
+			goto out;
 		*val = 0;
 		*val2 = ad7152_scale_table[ret >> 6];
 
-		return IIO_VAL_INT_PLUS_NANO;
+		ret = IIO_VAL_INT_PLUS_NANO;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	};
+out:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
 }
 
 static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
-- 
1.7.3.4


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

* [PATCH 12/16] staging:iio:adc:ad7152: Update sample rate, conversion time, digital filter handling
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (10 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 11/16] staging:iio:adc:ad7152: Add proper locking Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 13/16] staging:iio:adc:ad7152: Fix differential channel return value and increase delay Jonathan Cameron
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

Rename attribute, use sampling_frequency instead.
Attribute now accepts values in Hz.
Delay readout accordingly.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |   39 ++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index bf26d38..41c3102 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -66,6 +66,9 @@
 #define AD7152_CAPDAC_DACEN		(1 << 7)
 #define AD7152_CAPDAC_DACP(x)		((x) & 0x1F)
 
+/* CFG2 Register Bit Designations (AD7152_REG_CFG2) */
+#define AD7152_CFG2_OSR(x)		(((x) & 0x3) << 4)
+
 enum {
 	AD7152_DATA,
 	AD7152_OFFS,
@@ -156,8 +159,10 @@ static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
 static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
 		       S_IWUSR, NULL, ad7152_start_gain_calib, 1);
 
-#define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store)              \
-	IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0)
+/* Values are Update Rate (Hz), Conversion Time (ms) */
+static const unsigned char ad7152_filter_rate_table[][2] = {
+	{200, 5}, {50, 20}, {20, 50}, {17, 60},
+};
 
 static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
 		struct device_attribute *attr,
@@ -166,7 +171,8 @@ static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 
-	return sprintf(buf, "0x%02x\n", chip->filter_rate_setup);
+	return sprintf(buf, "%d\n",
+		       ad7152_filter_rate_table[chip->filter_rate_setup][0]);
 }
 
 static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
@@ -177,37 +183,50 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7152_chip_info *chip = iio_priv(indio_dev);
 	u8 data;
-	int ret;
+	int ret, i;
 
 	ret = kstrtou8(buf, 10, &data);
 	if (ret < 0)
 		return ret;
 
+	for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++)
+		if (data >= ad7152_filter_rate_table[i][0])
+			break;
+
+	if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
+		i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
+
 	mutex_lock(&indio_dev->mlock);
-	ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG2, data);
-	if (ret < 0)
+	ret = i2c_smbus_write_byte_data(chip->client,
+			AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
+	if (ret < 0) {
+		mutex_unlock(&indio_dev->mlock);
 		return ret;
+	}
 
-	chip->filter_rate_setup = data;
+	chip->filter_rate_setup = i;
 	mutex_unlock(&indio_dev->mlock);
 
 	return len;
 }
 
-static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
+static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
 		ad7152_show_filter_rate_setup,
 		ad7152_store_filter_rate_setup);
 
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17");
+
 static IIO_CONST_ATTR(in_capacitance_scale_available,
 		      "0.000061050 0.000030525 0.000015263 0.000007631");
 
 static struct attribute *ad7152_attributes[] = {
-	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
 	&iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
 	&iio_const_attr_in_capacitance_scale_available.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
 };
 
@@ -339,7 +358,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev,
 		if (ret < 0)
 			goto out;
 
-		msleep(60); /* Slowest conversion time */
+		msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]);
 		/* Now read the actual register */
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_DATA]);
-- 
1.7.3.4

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

* [PATCH 13/16] staging:iio:adc:ad7152: Fix differential channel return value and increase delay.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (11 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 12/16] staging:iio:adc:ad7152: Update sample rate, conversion time, digital filter handling Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 14/16] staging:iio:adc:ad7291 bring into line with current abi + chan_spec conversion Jonathan Cameron
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich, Jonathan Cameron

From: Michael Hennerich <michael.hennerich@analog.com>

In differential mode zero scale equals to 0x8000.
Increase readout delay by 1ms.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7152.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
index 41c3102..42efc37 100644
--- a/drivers/staging/iio/adc/ad7152.c
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -159,9 +159,9 @@ static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
 static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
 		       S_IWUSR, NULL, ad7152_start_gain_calib, 1);
 
-/* Values are Update Rate (Hz), Conversion Time (ms) */
+/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
 static const unsigned char ad7152_filter_rate_table[][2] = {
-	{200, 5}, {50, 20}, {20, 50}, {17, 60},
+	{200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1},
 };
 
 static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
@@ -366,6 +366,9 @@ static int ad7152_read_raw(struct iio_dev *indio_dev,
 			goto out;
 		*val = swab16(ret);
 
+		if (chan->differential)
+			*val -= 0x8000;
+
 		ret = IIO_VAL_INT;
 		break;
 	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
-- 
1.7.3.4


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

* [PATCH 14/16] staging:iio:adc:ad7291 bring into line with current abi + chan_spec conversion.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (12 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 13/16] staging:iio:adc:ad7152: Fix differential channel return value and increase delay Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 15/16] staging:iio:imu:adis16400 cleanups Jonathan Cameron
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

Also add some locking.

Some major changes to how this driver works.

For voltage channels it is currently either in single read mode or in
a monitor mode (events only). Could be much cleverer and allow
reading of any channels that happend to be monitored, but haven't
done that yet.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/adc/ad7291.c |  892 ++++++++++++++------------------------
 1 files changed, 315 insertions(+), 577 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 52e0311..b6be672 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -7,18 +7,28 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
+#include <linux/mutex.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
 
 /*
+ * Simplified handling
+ *
+ * If no events enabled - single polled channel read
+ * If event enabled direct reads disable unless channel
+ * is in the read mask.
+ *
+ * The noise-delayed bit as per datasheet suggestion is always enabled.
+ *
+ * Extref control should be based on regulator provision - not handled.
+ */
+/*
  * AD7291 registers definition
  */
 #define AD7291_COMMAND			0
@@ -55,29 +65,13 @@
 #define AD7291_T_VALUE_FLOAT_OFFSET	2
 #define AD7291_T_VALUE_FLOAT_MASK	0x2
 
-/*
- * struct ad7291_chip_info - chip specifc information
- */
-
 struct ad7291_chip_info {
 	struct i2c_client *client;
 	u16 command;
-	u8  channels;	/* Active voltage channels */
+	u8 c_mask;	/* Active voltage channels for events */
+	struct mutex state_lock;
 };
 
-/*
- * struct ad7291_chip_info - chip specifc information
- */
-
-struct ad7291_limit_regs {
-	u16	data_high;
-	u16	data_low;
-	u16	hysteresis;
-};
-
-/*
- * ad7291 register access by I2C
- */
 static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
 {
 	struct i2c_client *client = chip->client;
@@ -96,111 +90,9 @@ static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
 
 static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
 {
-	struct i2c_client *client = chip->client;
-	int ret = 0;
-
-	ret = i2c_smbus_write_word_data(client, reg, swab16(data));
-	if (ret < 0)
-		dev_err(&client->dev, "I2C write error\n");
-
-	return ret;
-}
-
-/* Returns negative errno, or else the number of words read. */
-static int ad7291_i2c_read_data(struct ad7291_chip_info *chip, u8 reg, u16 *data)
-{
-	struct i2c_client *client = chip->client;
-	u8 commands[4];
-	int ret = 0;
-	int i, count;
-
-	if (reg == AD7291_T_SENSE || reg == AD7291_T_AVERAGE)
-		count = 2;
-	else if (reg == AD7291_VOLTAGE) {
-		if (!chip->channels) {
-			dev_err(&client->dev, "No voltage channel is selected.\n");
-			return -EINVAL;
-		}
-		count = 2 + chip->channels * 2;
-	} else {
-		dev_err(&client->dev, "I2C wrong data register\n");
-		return -EINVAL;
-	}
-
-	commands[0] = 0;
-	commands[1] = (chip->command >> 8) & 0xff;
-	commands[2] = chip->command & 0xff;
-	commands[3] = reg;
-
-	ret = i2c_master_send(client, commands, 4);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C master send error\n");
-		return ret;
-	}
-
-	ret = i2c_master_recv(client, (u8 *)data, count);
-	if (ret < 0) {
-		dev_err(&client->dev, "I2C master receive error\n");
-		return ret;
-	}
-	ret >>= 2;
-
-	for (i = 0; i < ret; i++)
-		data[i] = swab16(data[i]);
-
-	return ret;
-}
-
-static ssize_t ad7291_show_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-
-	if (chip->command & AD7291_AUTOCYCLE)
-		return sprintf(buf, "autocycle\n");
-	else
-		return sprintf(buf, "command\n");
+	return i2c_smbus_write_word_data(chip->client, reg, swab16(data));
 }
 
-static ssize_t ad7291_store_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 command;
-	int ret;
-
-	command = chip->command & (~AD7291_AUTOCYCLE);
-	if (strcmp(buf, "autocycle"))
-		command |= AD7291_AUTOCYCLE;
-
-	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
-	if (ret)
-		return -EIO;
-
-	chip->command = command;
-
-	return ret;
-}
-
-static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
-		ad7291_show_mode,
-		ad7291_store_mode,
-		0);
-
-static ssize_t ad7291_show_available_modes(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return sprintf(buf, "command\nautocycle\n");
-}
-
-static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7291_show_available_modes, NULL, 0);
-
 static ssize_t ad7291_store_reset(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
@@ -208,240 +100,15 @@ static ssize_t ad7291_store_reset(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 command;
-	int ret;
-
-	command = chip->command | AD7291_RESET;
-
-	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
-	if (ret)
-		return -EIO;
-
-	return ret;
-}
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR,
-		NULL,
-		ad7291_store_reset,
-		0);
-
-static ssize_t ad7291_show_ext_ref(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", !!(chip->command & AD7291_EXT_REF));
-}
-
-static ssize_t ad7291_store_ext_ref(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 command;
-	int ret;
-
-	command = chip->command & (~AD7291_EXT_REF);
-	if (strcmp(buf, "1"))
-		command |= AD7291_EXT_REF;
-
-	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
-	if (ret)
-		return -EIO;
-
-	chip->command = command;
-
-	return ret;
-}
-
-static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR,
-		ad7291_show_ext_ref,
-		ad7291_store_ext_ref,
-		0);
-
-static ssize_t ad7291_show_noise_delay(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "%d\n", !!(chip->command & AD7291_NOISE_DELAY));
-}
-
-static ssize_t ad7291_store_noise_delay(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 command;
-	int ret;
-
-	command = chip->command & (~AD7291_NOISE_DELAY);
-	if (strcmp(buf, "1"))
-		command |= AD7291_NOISE_DELAY;
-
-	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
-	if (ret)
-		return -EIO;
-
-	chip->command = command;
 
-	return ret;
+	return ad7291_i2c_write(chip, AD7291_COMMAND,
+				chip->command | AD7291_RESET);
 }
 
-static IIO_DEVICE_ATTR(noise_delay, S_IRUGO | S_IWUSR,
-		ad7291_show_noise_delay,
-		ad7291_store_noise_delay,
-		0);
-
-static ssize_t ad7291_show_t_sense(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 data;
-	char sign = ' ';
-	int ret;
-
-	ret = ad7291_i2c_read_data(chip, AD7291_T_SENSE, &data);
-	if (ret)
-		return -EIO;
-
-	if (data & AD7291_T_VALUE_SIGN) {
-		/* convert supplement to positive value */
-		data = (AD7291_T_VALUE_SIGN << 1) - data;
-		sign = '-';
-	}
-
-	return sprintf(buf, "%c%d.%.2d\n", sign,
-		(data >> AD7291_T_VALUE_FLOAT_OFFSET),
-		(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
-}
-
-static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7291_show_t_sense, NULL, 0);
-
-static ssize_t ad7291_show_t_average(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 data;
-	char sign = ' ';
-	int ret;
-
-	ret = ad7291_i2c_read_data(chip, AD7291_T_AVERAGE, &data);
-	if (ret)
-		return -EIO;
-
-	if (data & AD7291_T_VALUE_SIGN) {
-		/* convert supplement to positive value */
-		data = (AD7291_T_VALUE_SIGN << 1) - data;
-		sign = '-';
-	}
-
-	return sprintf(buf, "%c%d.%.2d\n", sign,
-		(data >> AD7291_T_VALUE_FLOAT_OFFSET),
-		(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
-}
-
-static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7291_show_t_average, NULL, 0);
-
-static ssize_t ad7291_show_voltage(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 data[AD7291_VOLTAGE_LIMIT_COUNT];
-	int i, size, ret;
-
-	ret = ad7291_i2c_read_data(chip, AD7291_VOLTAGE, data);
-	if (ret)
-		return -EIO;
-
-	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
-		if (chip->command & (AD7291_T_SENSE_MASK << i)) {
-			ret = sprintf(buf, "channel[%d]=%d\n", i,
-					data[i] & AD7291_VALUE_MASK);
-			if (ret < 0)
-				break;
-			buf += ret;
-			size += ret;
-		}
-	}
-
-	return size;
-}
-
-static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7291_show_voltage, NULL, 0);
-
-static ssize_t ad7291_show_channel_mask(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-
-	return sprintf(buf, "0x%x\n", (chip->command & AD7291_VOLTAGE_MASK) >>
-			AD7291_VOLTAGE_OFFSET);
-}
-
-static ssize_t ad7291_store_channel_mask(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 command;
-	unsigned long data;
-	int i, ret;
-
-	ret = strict_strtoul(buf, 16, &data);
-	if (ret || data > 0xff)
-		return -EINVAL;
-
-	command = chip->command & (~AD7291_VOLTAGE_MASK);
-	command |= data << AD7291_VOLTAGE_OFFSET;
-
-	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
-	if (ret)
-		return -EIO;
-
-	chip->command = command;
-
-	for (i = 0, chip->channels = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
-		if (chip->command & (AD7291_T_SENSE_MASK << i))
-			chip->channels++;
-	}
-
-	return ret;
-}
-
-static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
-		ad7291_show_channel_mask,
-		ad7291_store_channel_mask,
-		0);
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, ad7291_store_reset, 0);
 
 static struct attribute *ad7291_attributes[] = {
-	&iio_dev_attr_available_modes.dev_attr.attr,
-	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_dev_attr_ext_ref.dev_attr.attr,
-	&iio_dev_attr_noise_delay.dev_attr.attr,
-	&iio_dev_attr_t_sense.dev_attr.attr,
-	&iio_dev_attr_t_average.dev_attr.attr,
-	&iio_dev_attr_voltage.dev_attr.attr,
-	&iio_dev_attr_channel_mask.dev_attr.attr,
 	NULL,
 };
 
@@ -449,10 +116,6 @@ static const struct attribute_group ad7291_attribute_group = {
 	.attrs = ad7291_attributes,
 };
 
-/*
- * temperature bound events
- */
-
 static irqreturn_t ad7291_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -477,28 +140,15 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
 	command = chip->command & ~AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
 
-	if (t_status & (1 << 0))
+	/* For now treat t_sense and t_sense_average the same */
+	if ((t_status & (1 << 0)) || (t_status & (1 << 2)))
 		iio_push_event(indio_dev,
 			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
 						    0,
 						    IIO_EV_TYPE_THRESH,
 						    IIO_EV_DIR_FALLING),
 			       timestamp);
-	if (t_status & (1 << 1))
-		iio_push_event(indio_dev,
-			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
-						    0,
-						    IIO_EV_TYPE_THRESH,
-						    IIO_EV_DIR_RISING),
-			       timestamp);
-	if (t_status & (1 << 2))
-		iio_push_event(indio_dev,
-			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
-						    0,
-						    IIO_EV_TYPE_THRESH,
-						    IIO_EV_DIR_FALLING),
-			       timestamp);
-	if (t_status & (1 << 3))
+	if ((t_status & (1 << 1)) || (t_status & (1 << 3)))
 		iio_push_event(indio_dev,
 			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
 						    0,
@@ -526,7 +176,7 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
-static inline ssize_t ad7291_show_t_bound(struct device *dev,
+static inline ssize_t ad7291_show_hyst(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
@@ -534,243 +184,324 @@ static inline ssize_t ad7291_show_t_bound(struct device *dev,
 	struct ad7291_chip_info *chip = iio_priv(dev_info);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	u16 data;
-	char sign = ' ';
 	int ret;
 
 	ret = ad7291_i2c_read(chip, this_attr->address, &data);
-	if (ret)
-		return -EIO;
-
-	data &= AD7291_VALUE_MASK;
-	if (data & AD7291_T_VALUE_SIGN) {
-		/* convert supplement to positive value */
-		data = (AD7291_T_VALUE_SIGN << 1) - data;
-		sign = '-';
-	}
+	if (ret < 0)
+		return ret;
 
-	return sprintf(buf, "%c%d.%.2d\n", sign,
-			data >> AD7291_T_VALUE_FLOAT_OFFSET,
-			(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
+	return sprintf(buf, "%d\n", data & 0x0FFF);
 }
 
-static inline ssize_t ad7291_set_t_bound(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
+static inline ssize_t ad7291_set_hyst(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = iio_priv(dev_info);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long tmp1, tmp2;
 	u16 data;
-	char *pos;
 	int ret;
 
-	pos = strchr(buf, '.');
+	ret = kstrtou16(buf, 10, &data);
 
-	ret = strict_strtol(buf, 10, &tmp1);
-
-	if (ret || tmp1 > 127 || tmp1 < -128)
+	if (ret < 0)
+		return ret;
+	if (data < 4096)
 		return -EINVAL;
 
-	if (pos) {
-		len = strlen(pos);
-		if (len > AD7291_T_VALUE_FLOAT_OFFSET)
-			len = AD7291_T_VALUE_FLOAT_OFFSET;
-		pos[len] = 0;
-		ret = strict_strtol(pos, 10, &tmp2);
+	return ad7291_i2c_write(chip, this_attr->address, data);
+}
 
-		if (!ret)
-			tmp2 = (tmp2 / 25) * 25;
-	}
+static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst,
+		       AD7291_T_SENSE_HYST);
+static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x06);
+static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x09);
+static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x0C);
+static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x0F);
+static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x12);
+static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x15);
+static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x18);
+static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_hyst, ad7291_set_hyst, 0x1B);
 
-	if (tmp1 < 0)
-		data = (u16)(-tmp1);
-	else
-		data = (u16)tmp1;
-	data = (data << AD7291_T_VALUE_FLOAT_OFFSET) |
-		(tmp2 & AD7291_T_VALUE_FLOAT_MASK);
-	if (tmp1 < 0)
-		/* convert positive value to supplyment */
-		data = (AD7291_T_VALUE_SIGN << 1) - data;
-
-	ret = ad7291_i2c_write(chip, this_attr->address, data);
-	if (ret)
-		return -EIO;
+static struct attribute *ad7291_event_attributes[] = {
+	&iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
+	NULL,
+};
 
-	return ret;
-}
+/* high / low */
+static u8 ad7291_limit_regs[9][2] = {
+	{ 0x04, 0x05 },
+	{ 0x07, 0x08 },
+	{ 0x0A, 0x0B },
+	{ 0x0E, 0x0D }, /* note reversed order */
+	{ 0x10, 0x11 },
+	{ 0x13, 0x14 },
+	{ 0x16, 0x17 },
+	{ 0x19, 0x1A },
+	/* temp */
+	{ 0x1C, 0x1D },
+};
 
-static inline ssize_t ad7291_show_v_bound(struct device *dev,
-		struct device_attribute *attr,
-		u8 bound_reg,
-		char *buf)
+static int ad7291_read_event_value(struct iio_dev *indio_dev,
+				   u64 event_code,
+				   int *val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	u16 data;
-	int ret;
+	struct ad7291_chip_info *chip = iio_priv(indio_dev);
 
-	if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE ||
-		bound_reg >= AD7291_VOLTAGE_LIMIT_BASE +
-		AD7291_VOLTAGE_LIMIT_COUNT)
+	int ret;
+	u8 reg;
+	u16 uval;
+	s16 signval;
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_VOLTAGE:
+		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
+			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			   IIO_EV_DIR_RISING)];
+
+		ret = ad7291_i2c_read(chip, reg, &uval);
+		if (ret < 0)
+			return ret;
+		*val = swab16(uval) & 0x0FFF;
+		return 0;
+
+	case IIO_TEMP:
+		reg = ad7291_limit_regs[8]
+			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			   IIO_EV_DIR_RISING)];
+
+		ret = ad7291_i2c_read(chip, reg, &signval);
+		if (ret < 0)
+			return ret;
+		signval = (s16)((swab16(signval) & 0x0FFF) << 4) >> 4;
+		*val = signval;
+		return 0;
+	default:
 		return -EINVAL;
+	};
+}
 
-	ret = ad7291_i2c_read(chip, bound_reg, &data);
-	if (ret)
-		return -EIO;
+static int ad7291_write_event_value(struct iio_dev *indio_dev,
+				    u64 event_code,
+				    int val)
+{
+	struct ad7291_chip_info *chip = iio_priv(indio_dev);
+	u8 reg;
+	s16 signval;
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_VOLTAGE:
+		if (val > 0xFFF || val < 0)
+			return -EINVAL;
+		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
+			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			   IIO_EV_DIR_RISING)];
 
-	data &= AD7291_VALUE_MASK;
+		return ad7291_i2c_write(chip, reg, val);
 
-	return sprintf(buf, "%d\n", data);
+	case IIO_TEMP:
+		if (val > 2047 || val < -2048)
+			return -EINVAL;
+		reg = ad7291_limit_regs[8]
+			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			   IIO_EV_DIR_RISING)];
+		signval = val;
+		return ad7291_i2c_write(chip, reg, *(u16 *)&signval);
+	default:
+		return -EINVAL;
+	};
 }
 
-static inline ssize_t ad7291_set_v_bound(struct device *dev,
-		struct device_attribute *attr,
-		u8 bound_reg,
-		const char *buf,
-		size_t len)
+static int ad7291_read_event_config(struct iio_dev *indio_dev,
+				    u64 event_code)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = iio_priv(dev_info);
-	unsigned long value;
-	u16 data;
-	int ret;
-
-	if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE ||
-		bound_reg >= AD7291_VOLTAGE_LIMIT_BASE +
-		AD7291_VOLTAGE_LIMIT_COUNT)
+	struct ad7291_chip_info *chip = iio_priv(indio_dev);
+	/* To be enabled the channel must simply be on. If any are enabled
+	   we are in continuous sampling mode */
+
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_VOLTAGE:
+		if (chip->c_mask &
+		    (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code)))
+			return 1;
+		else
+			return 0;
+	case IIO_TEMP:
+		/* always on */
+		return 1;
+	default:
 		return -EINVAL;
+	}
 
-	ret = strict_strtoul(buf, 10, &value);
-
-	if (ret || value >= 4096)
-		return -EINVAL;
+}
 
-	data = (u16)value;
-	ret = ad7291_i2c_write(chip, bound_reg, data);
-	if (ret)
-		return -EIO;
+static int ad7291_write_event_config(struct iio_dev *indio_dev,
+				     u64 event_code,
+				     int state)
+{
+	int ret = 0;
+	struct ad7291_chip_info *chip = iio_priv(indio_dev);
+	u16 regval;
+
+	mutex_lock(&chip->state_lock);
+	regval = chip->command;
+	/*
+	 * To be enabled the channel must simply be on. If any are enabled
+	 * use continuous sampling mode.
+	 * Possible to disable temp as well but that makes single read tricky.
+	 */
+	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+	case IIO_VOLTAGE:
+		if ((!state) && (chip->c_mask &
+			       (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code))))
+			chip->c_mask &=
+				~(1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code));
+		else if (state && (!(chip->c_mask &
+				(1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code)))))
+			chip->c_mask &=
+				(1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code));
+		else
+			break;
+
+		regval &= 0xFFFE;
+		regval |= ((u16)chip->c_mask << 8);
+		if (chip->c_mask) /* Enable autocycle? */
+			regval |= AD7291_AUTOCYCLE;
+
+		ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
+		if (ret < 0)
+			goto error_ret;
+
+		chip->command = regval;
+		break;
+	default:
+		ret = -EINVAL;
+	}
 
+error_ret:
+	mutex_unlock(&chip->state_lock);
 	return ret;
 }
 
-static IIO_DEVICE_ATTR(t_sense_high_value,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound,
-		       AD7291_T_SENSE_HIGH);
-static IIO_DEVICE_ATTR(t_sense_low_value,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound,
-		       AD7291_T_SENSE_LOW);
-static IIO_DEVICE_ATTR(t_sense_hyst_value,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound,
-		       AD7291_T_SENSE_HYST);
-static IIO_DEVICE_ATTR(v0_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x04);
-static IIO_DEVICE_ATTR(v0_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x05);
-static IIO_DEVICE_ATTR(v0_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x06);
-static IIO_DEVICE_ATTR(v1_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x07);
-static IIO_DEVICE_ATTR(v1_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x08);
-static IIO_DEVICE_ATTR(v1_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x09);
-static IIO_DEVICE_ATTR(v2_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0A);
-static IIO_DEVICE_ATTR(v2_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0B);
-static IIO_DEVICE_ATTR(v2_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0C);
-static IIO_DEVICE_ATTR(v3_high,
-		       S_IRUGO | S_IWUSR,
-		       /* Datasheet suggests this one and this one only
-			  has the registers in different order */
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0E);
-static IIO_DEVICE_ATTR(v3_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0D);
-static IIO_DEVICE_ATTR(v3_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0F);
-static IIO_DEVICE_ATTR(v4_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x10);
-static IIO_DEVICE_ATTR(v4_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x11);
-static IIO_DEVICE_ATTR(v4_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x12);
-static IIO_DEVICE_ATTR(v5_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x13);
-static IIO_DEVICE_ATTR(v5_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x14);
-static IIO_DEVICE_ATTR(v5_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x15);
-static IIO_DEVICE_ATTR(v6_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x16);
-static IIO_DEVICE_ATTR(v6_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x17);
-static IIO_DEVICE_ATTR(v6_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x18);
-static IIO_DEVICE_ATTR(v7_high,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x19);
-static IIO_DEVICE_ATTR(v7_low,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1A);
-static IIO_DEVICE_ATTR(v7_hyst,
-		       S_IRUGO | S_IWUSR,
-		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1B);
+static int ad7291_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long mask)
+{
+	int ret;
+	struct ad7291_chip_info *chip = iio_priv(indio_dev);
+	u16 regval;
+	s16 signval;
+
+	switch (mask) {
+	case 0:
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			mutex_lock(&chip->state_lock);
+			/* If in autocycle mode drop through */
+			if (chip->command & 0x1) {
+				mutex_unlock(&chip->state_lock);
+				return -EBUSY;
+			}
+			/* Enable this channel alone */
+			regval = chip->command & (~AD7291_VOLTAGE_MASK);
+			regval |= 1 << (chan->channel + 8);
+			ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
+			if (ret < 0) {
+				mutex_unlock(&chip->state_lock);
+				return ret;
+			}
+			/* Read voltage */
+			ret = i2c_smbus_read_word_data(chip->client,
+						       AD7291_VOLTAGE);
+			if (ret < 0) {
+				mutex_unlock(&chip->state_lock);
+				return ret;
+			}
+			*val = swab16((u16)ret) & 0x0FFF;
+			mutex_unlock(&chip->state_lock);
+			return IIO_VAL_INT;
+		case IIO_TEMP:
+			/* Assumes tsense bit of command register always set */
+			ret = i2c_smbus_read_word_data(chip->client,
+						       AD7291_T_SENSE);
+			if (ret < 0)
+				return ret;
+			signval = (s16)((swab16((u16)ret) & 0x0FFF) << 4) >> 4;
+			*val = signval;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE):
+		ret = i2c_smbus_read_word_data(chip->client,
+					       AD7291_T_AVERAGE);
+			if (ret < 0)
+				return ret;
+			signval = (s16)((swab16((u16)ret) & 0x0FFF) << 4) >> 4;
+			*val = signval;
+			return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
 
-static struct attribute *ad7291_event_attributes[] = {
-	&iio_dev_attr_t_sense_high_value.dev_attr.attr,
-	&iio_dev_attr_t_sense_low_value.dev_attr.attr,
-	&iio_dev_attr_t_sense_hyst_value.dev_attr.attr,
-	&iio_dev_attr_v0_high.dev_attr.attr,
-	&iio_dev_attr_v0_low.dev_attr.attr,
-	&iio_dev_attr_v0_hyst.dev_attr.attr,
-	&iio_dev_attr_v1_high.dev_attr.attr,
-	&iio_dev_attr_v1_low.dev_attr.attr,
-	&iio_dev_attr_v1_hyst.dev_attr.attr,
-	&iio_dev_attr_v2_high.dev_attr.attr,
-	&iio_dev_attr_v2_low.dev_attr.attr,
-	&iio_dev_attr_v2_hyst.dev_attr.attr,
-	&iio_dev_attr_v3_high.dev_attr.attr,
-	&iio_dev_attr_v3_low.dev_attr.attr,
-	&iio_dev_attr_v3_hyst.dev_attr.attr,
-	&iio_dev_attr_v4_high.dev_attr.attr,
-	&iio_dev_attr_v4_low.dev_attr.attr,
-	&iio_dev_attr_v4_hyst.dev_attr.attr,
-	&iio_dev_attr_v5_high.dev_attr.attr,
-	&iio_dev_attr_v5_low.dev_attr.attr,
-	&iio_dev_attr_v5_hyst.dev_attr.attr,
-	&iio_dev_attr_v6_high.dev_attr.attr,
-	&iio_dev_attr_v6_low.dev_attr.attr,
-	&iio_dev_attr_v6_hyst.dev_attr.attr,
-	&iio_dev_attr_v7_high.dev_attr.attr,
-	&iio_dev_attr_v7_low.dev_attr.attr,
-	&iio_dev_attr_v7_hyst.dev_attr.attr,
-	NULL,
+#define AD7291_VOLTAGE_CHAN(_chan)					\
+{									\
+	.type = IIO_VOLTAGE,						\
+	.indexed = 1,							\
+	.channel = _chan,						\
+	.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
+	IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)		\
+}
+
+static const struct iio_chan_spec ad7291_channels[] = {
+	AD7291_VOLTAGE_CHAN(0),
+	AD7291_VOLTAGE_CHAN(1),
+	AD7291_VOLTAGE_CHAN(2),
+	AD7291_VOLTAGE_CHAN(3),
+	AD7291_VOLTAGE_CHAN(4),
+	AD7291_VOLTAGE_CHAN(5),
+	AD7291_VOLTAGE_CHAN(6),
+	AD7291_VOLTAGE_CHAN(7),
+	{
+		.type = IIO_TEMP,
+		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
+		.indexed = 1,
+		.channel = 0,
+		.event_mask =
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
+		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
+	}
 };
 
 static struct attribute_group ad7291_event_attribute_group = {
@@ -779,13 +510,14 @@ static struct attribute_group ad7291_event_attribute_group = {
 
 static const struct iio_info ad7291_info = {
 	.attrs = &ad7291_attribute_group,
+	.read_raw = &ad7291_read_raw,
+	.read_event_config = &ad7291_read_event_config,
+	.write_event_config = &ad7291_write_event_config,
+	.read_event_value = &ad7291_read_event_value,
+	.write_event_value = &ad7291_write_event_value,
 	.event_attrs = &ad7291_event_attribute_group,
 };
 
-/*
- * device probe and remove
- */
-
 static int __devinit ad7291_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -799,13 +531,18 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 		goto error_ret;
 	}
 	chip = iio_priv(indio_dev);
+	mutex_init(&chip->state_lock);
 	/* this is only used for device removal purposes */
 	i2c_set_clientdata(client, indio_dev);
 
 	chip->client = client;
+	/* Tsense always enabled */
 	chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK;
 
 	indio_dev->name = id->name;
+	indio_dev->channels = ad7291_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7291_channels);
+
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->info = &ad7291_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
@@ -840,7 +577,8 @@ static int __devinit ad7291_probe(struct i2c_client *client,
 	return 0;
 
 error_unreg_irq:
-	free_irq(client->irq, indio_dev);
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
-- 
1.7.3.4


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

* [PATCH 15/16] staging:iio:imu:adis16400 cleanups
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (13 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 14/16] staging:iio:adc:ad7291 bring into line with current abi + chan_spec conversion Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-08-26 10:19 ` [PATCH 16/16] iio: imu: adis16400: Avoid using printk facility Jonathan Cameron
  2011-09-02 16:24 ` [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron

a) remove irq is gpio requirement - No reason this needs to be true.
b) use actual part name in info message rather than adis16400 in all cases.
c) scrap use of IIO_CHAN to simplify move out of staging.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/imu/adis16400_core.c    |  607 ++++++++++++++++++---------
 drivers/staging/iio/imu/adis16400_trigger.c |    2 +-
 2 files changed, 403 insertions(+), 206 deletions(-)

diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 02ba9be..c1ed832 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -16,7 +16,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -31,8 +30,6 @@
 #include "../ring_generic.h"
 #include "adis16400.h"
 
-#define DRIVER_NAME		"adis16400"
-
 enum adis16400_chip_variant {
 	ADIS16300,
 	ADIS16344,
@@ -44,19 +41,12 @@ enum adis16400_chip_variant {
 	ADIS16400,
 };
 
-static int adis16400_check_status(struct iio_dev *indio_dev);
-
-/* At the moment the spi framework doesn't allow global setting of cs_change.
- * It's in the likely to be added comment at the top of spi.h.
- * This means that use cannot be made of spi_write etc.
- */
-
 /**
  * adis16400_spi_write_reg_8() - write single byte to a register
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @reg_address: the address of the register to be written
  * @val: the value to write
- **/
+ */
 static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
 				     u8 reg_address,
 				     u8 val)
@@ -80,7 +70,10 @@ static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
- **/
+ *
+ * At the moment the spi framework doesn't allow global setting of cs_change.
+ * This means that use cannot be made of spi_write.
+ */
 static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
@@ -122,6 +115,9 @@ static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
+ *
+ * At the moment the spi framework doesn't allow global setting of cs_change.
+ * This means that use cannot be made of spi_read.
  **/
 static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
@@ -240,10 +236,11 @@ static ssize_t adis16400_write_reset(struct device *dev,
 	ret = strtobool(buf, &val);
 	if (ret < 0)
 		return ret;
-	if (val)
+	if (val) {
 		ret = adis16400_reset(dev_get_drvdata(dev));
-	if (ret < 0)
-		return ret;
+		if (ret < 0)
+			return ret;
+	}
 
 	return len;
 }
@@ -252,6 +249,7 @@ int adis16400_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret;
 	u16 msc;
+
 	ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
@@ -284,24 +282,6 @@ static int adis16400_stop_device(struct iio_dev *indio_dev)
 	return ret;
 }
 
-static int adis16400_self_test(struct iio_dev *indio_dev)
-{
-	int ret;
-	ret = adis16400_spi_write_reg_16(indio_dev,
-			ADIS16400_MSC_CTRL,
-			ADIS16400_MSC_CTRL_MEM_TEST);
-	if (ret) {
-		dev_err(&indio_dev->dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	msleep(ADIS16400_MTEST_DELAY);
-	adis16400_check_status(indio_dev);
-
-err_ret:
-	return ret;
-}
-
 static int adis16400_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
@@ -351,11 +331,28 @@ error_ret:
 	return ret;
 }
 
+static int adis16400_self_test(struct iio_dev *indio_dev)
+{
+	int ret;
+	ret = adis16400_spi_write_reg_16(indio_dev,
+			ADIS16400_MSC_CTRL,
+			ADIS16400_MSC_CTRL_MEM_TEST);
+	if (ret) {
+		dev_err(&indio_dev->dev, "problem starting self test");
+		goto err_ret;
+	}
+
+	msleep(ADIS16400_MTEST_DELAY);
+	adis16400_check_status(indio_dev);
+
+err_ret:
+	return ret;
+}
+
 static int adis16400_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 prod_id, smp_prd;
-	struct device *dev = &indio_dev->dev;
 	struct adis16400_state *st = iio_priv(indio_dev);
 
 	/* use low spi speed for init */
@@ -363,29 +360,26 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
 	st->us->mode = SPI_MODE_3;
 	spi_setup(st->us);
 
-	/* Disable IRQ */
 	ret = adis16400_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
-	/* Do self test */
 	ret = adis16400_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
-	/* Read status register to check the result */
 	ret = adis16400_check_status(indio_dev);
 	if (ret) {
 		adis16400_reset(indio_dev);
-		dev_err(dev, "device not playing ball -> reset");
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16400_STARTUP_DELAY);
 		ret = adis16400_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
@@ -396,10 +390,11 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
 			goto err_ret;
 
 		if ((prod_id & 0xF000) != st->variant->product_id)
-			dev_warn(dev, "incorrect id");
+			dev_warn(&indio_dev->dev, "incorrect id");
 
-		printk(KERN_INFO DRIVER_NAME ": prod_id 0x%04x at CS%d (irq %d)\n",
-		       prod_id, st->us->chip_select, st->us->irq);
+		printk(KERN_INFO "%s: prod_id 0x%04x at CS%d (irq %d)\n",
+		       indio_dev->name, prod_id,
+		       st->us->chip_select, st->us->irq);
 	}
 	/* use high spi speed if possible */
 	ret = adis16400_spi_read_reg_16(indio_dev,
@@ -409,15 +404,13 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
 		spi_setup(st->us);
 	}
 
-
 err_ret:
-
 	return ret;
 }
 
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		adis16400_read_frequency,
-		adis16400_write_frequency);
+			      adis16400_read_frequency,
+			      adis16400_write_frequency);
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
 
@@ -442,23 +435,23 @@ enum adis16400_chan {
 };
 
 static u8 adis16400_addresses[17][2] = {
-	[in_supply] = { ADIS16400_SUPPLY_OUT, 0 },
+	[in_supply] = { ADIS16400_SUPPLY_OUT },
 	[gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF },
 	[gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF },
 	[gyro_z] = { ADIS16400_ZGYRO_OUT, ADIS16400_ZGYRO_OFF },
 	[accel_x] = { ADIS16400_XACCL_OUT, ADIS16400_XACCL_OFF },
 	[accel_y] = { ADIS16400_YACCL_OUT, ADIS16400_YACCL_OFF },
 	[accel_z] = { ADIS16400_ZACCL_OUT, ADIS16400_ZACCL_OFF },
-	[magn_x] = { ADIS16400_XMAGN_OUT, 0 },
-	[magn_y] = { ADIS16400_YMAGN_OUT, 0 },
-	[magn_z] = { ADIS16400_ZMAGN_OUT, 0 },
-	[temp] = { ADIS16400_TEMP_OUT, 0 },
+	[magn_x] = { ADIS16400_XMAGN_OUT },
+	[magn_y] = { ADIS16400_YMAGN_OUT },
+	[magn_z] = { ADIS16400_ZMAGN_OUT },
+	[temp] = { ADIS16400_TEMP_OUT },
 	[temp0] = { ADIS16350_XTEMP_OUT },
 	[temp1] = { ADIS16350_YTEMP_OUT },
 	[temp2] = { ADIS16350_ZTEMP_OUT },
-	[in1] = { ADIS16400_AUX_ADC, 0 },
-	[incli_x] = { ADIS16300_PITCH_OUT, 0 },
-	[incli_y] = { ADIS16300_ROLL_OUT, 0 }
+	[in1] = { ADIS16400_AUX_ADC },
+	[incli_x] = { ADIS16300_PITCH_OUT },
+	[incli_y] = { ADIS16300_ROLL_OUT }
 };
 
 static int adis16400_write_raw(struct iio_dev *indio_dev,
@@ -468,6 +461,7 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
 			       long mask)
 {
 	int ret;
+
 	switch (mask) {
 	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
 		mutex_lock(&indio_dev->mlock);
@@ -488,9 +482,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 			      long mask)
 {
 	struct adis16400_state *st = iio_priv(indio_dev);
-	int ret;
+	int ret, shift;
 	s16 val16;
-	int shift;
 
 	switch (mask) {
 	case 0:
@@ -561,164 +554,368 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
 }
 
 static struct iio_chan_spec adis16400_channels[] = {
-	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in_supply, ADIS16400_SCAN_SUPPLY,
-		 IIO_ST('u', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 magn_x, ADIS16400_SCAN_MAGN_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 magn_y, ADIS16400_SCAN_MAGN_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 magn_z, ADIS16400_SCAN_MAGN_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in1, ADIS16400_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	{
+		.type = IIO_VOLTAGE,
+		.indexed = 1,
+		.channel = 0,
+		.extend_name = "supply",
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in_supply,
+		.scan_index = ADIS16400_SCAN_SUPPLY,
+		.scan_type = IIO_ST('u', 14, 16, 0)
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_x,
+		.scan_index = ADIS16400_SCAN_GYRO_X,
+		.scan_type = IIO_ST('s', 14, 16, 0)
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_y,
+		.scan_index = ADIS16400_SCAN_GYRO_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_z,
+		.scan_index = ADIS16400_SCAN_GYRO_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_x,
+		.scan_index = ADIS16400_SCAN_ACC_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_y,
+		.scan_index = ADIS16400_SCAN_ACC_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_z,
+		.scan_index = ADIS16400_SCAN_ACC_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_MAGN,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = magn_x,
+		.scan_index = ADIS16400_SCAN_MAGN_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_MAGN,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = magn_y,
+		.scan_index = ADIS16400_SCAN_MAGN_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_MAGN,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = magn_z,
+		.scan_index = ADIS16400_SCAN_MAGN_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = temp,
+		.scan_index = ADIS16400_SCAN_TEMP,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_IN,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in1,
+		.scan_index = ADIS16400_SCAN_ADC_0,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	},
 	IIO_CHAN_SOFT_TIMESTAMP(12)
 };
 
 static struct iio_chan_spec adis16350_channels[] = {
-	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, "x", 0, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, "y", 1, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp1, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, "z", 2, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp2, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	{
+		.type = IIO_VOLTAGE,
+		.indexed = 1,
+		.channel = 0,
+		.extend_name = "supply",
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in_supply,
+		.scan_index = ADIS16400_SCAN_SUPPLY,
+		.scan_type = IIO_ST('u', 12, 16, 0)
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_x,
+		.scan_index = ADIS16400_SCAN_GYRO_X,
+		.scan_type = IIO_ST('s', 14, 16, 0)
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_y,
+		.scan_index = ADIS16400_SCAN_GYRO_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_z,
+		.scan_index = ADIS16400_SCAN_GYRO_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+	.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_x,
+		.scan_index = ADIS16400_SCAN_ACC_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_y,
+		.scan_index = ADIS16400_SCAN_ACC_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_z,
+		.scan_index = ADIS16400_SCAN_ACC_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 0,
+		.extend_name = "x",
+		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = temp0,
+		.scan_index = ADIS16350_SCAN_TEMP_X,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 1,
+		.extend_name = "y",
+		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = temp1,
+		.scan_index = ADIS16350_SCAN_TEMP_Y,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 2,
+		.extend_name = "z",
+		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = temp2,
+		.scan_index = ADIS16350_SCAN_TEMP_Z,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_IN,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in1,
+		.scan_index = ADIS16350_SCAN_ADC_0,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	},
 	IIO_CHAN_SOFT_TIMESTAMP(11)
 };
 
 static struct iio_chan_spec adis16300_channels[] = {
-	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
-	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 incli_x, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0),
-	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 incli_y, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0),
+	{
+		.type = IIO_VOLTAGE,
+		.indexed = 1,
+		.channel = 0,
+		.extend_name = "supply",
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in_supply,
+		.scan_index = ADIS16400_SCAN_SUPPLY,
+		.scan_type = IIO_ST('u', 12, 16, 0)
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_x,
+		.scan_index = ADIS16400_SCAN_GYRO_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_x,
+		.scan_index = ADIS16400_SCAN_ACC_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_y,
+		.scan_index = ADIS16400_SCAN_ACC_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_z,
+		.scan_index = ADIS16400_SCAN_ACC_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = temp,
+		.scan_index = ADIS16400_SCAN_TEMP,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_IN,
+		.indexed = 1,
+		.channel = 1,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.address = in1,
+		.scan_index = ADIS16350_SCAN_ADC_0,
+		.scan_type = IIO_ST('s', 12, 16, 0),
+	}, {
+		.type = IIO_INCLI,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = incli_x,
+		.scan_index = ADIS16300_SCAN_INCLI_X,
+		.scan_type = IIO_ST('s', 13, 16, 0),
+	}, {
+		.type = IIO_INCLI,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = incli_y,
+		.scan_index = ADIS16300_SCAN_INCLI_Y,
+		.scan_type = IIO_ST('s', 13, 16, 0),
+	},
 	IIO_CHAN_SOFT_TIMESTAMP(14)
 };
 
 static const struct iio_chan_spec adis16344_channels[] = {
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
-		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
-	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
-		 temp0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0),
+	{
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_x,
+		.scan_index = ADIS16400_SCAN_GYRO_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_y,
+		.scan_index = ADIS16400_SCAN_GYRO_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_GYRO,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = gyro_z,
+		.scan_index = ADIS16400_SCAN_GYRO_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_x,
+		.scan_index = ADIS16400_SCAN_ACC_X,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_y,
+		.scan_index = ADIS16400_SCAN_ACC_Y,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_z,
+		.scan_index = ADIS16400_SCAN_ACC_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.address = accel_z,
+		.scan_index = ADIS16400_SCAN_ACC_Z,
+		.scan_type = IIO_ST('s', 14, 16, 0),
+	},
 	IIO_CHAN_SOFT_TIMESTAMP(12)
 };
 
@@ -855,7 +1052,7 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	}
 
-	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+	if (spi->irq) {
 		ret = adis16400_probe_trigger(indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index 3860d92..bf99153 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -29,7 +29,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev)
 	struct adis16400_state *st = iio_priv(indio_dev);
 
 	st->trig = iio_allocate_trigger("%s-dev%d",
-					spi_get_device_id(st->us)->name,
+					indio_dev->name,
 					indio_dev->id);
 	if (st->trig == NULL) {
 		ret = -ENOMEM;
-- 
1.7.3.4

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

* [PATCH 16/16] iio: imu: adis16400: Avoid using printk facility
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (14 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 15/16] staging:iio:imu:adis16400 cleanups Jonathan Cameron
@ 2011-08-26 10:19 ` Jonathan Cameron
  2011-09-02 16:24 ` [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-08-26 10:19 UTC (permalink / raw)
  To: linux-iio; +Cc: Michael Hennerich

From: Michael Hennerich <michael.hennerich@analog.com>

use dev_info() instead.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
---
 drivers/staging/iio/imu/adis16400_core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index c1ed832..2f0d221 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -392,7 +392,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
 		if ((prod_id & 0xF000) != st->variant->product_id)
 			dev_warn(&indio_dev->dev, "incorrect id");
 
-		printk(KERN_INFO "%s: prod_id 0x%04x at CS%d (irq %d)\n",
+		dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
 		       indio_dev->name, prod_id,
 		       st->us->chip_select, st->us->irq);
 	}
-- 
1.7.3.4


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

* Re: [PATCH 00/16] staging:iio: CDC and other driver updates.
  2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
                   ` (15 preceding siblings ...)
  2011-08-26 10:19 ` [PATCH 16/16] iio: imu: adis16400: Avoid using printk facility Jonathan Cameron
@ 2011-09-02 16:24 ` Jonathan Cameron
  16 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2011-09-02 16:24 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio

I've sent these and all Michaels more recent fixes on to Greg
(weird operating without hera) - if anyone needs the current tree
I can do a full patch set.
> Hi All,
> 
> Straight forward series - as you can see I've rolled in Michael's
> recent posting so you can see where they fit.
> 
> This lot sits on top of
> staging:iio: New stuff and reworks.
> 
> Nothing terribly interesting.  Mostly bringing a few drivers into
> line with the abi.  Thanks particularly to Michael for testing my
> hardware free changes and chasing down all the bugs!
> 
> Jonathan
> 
> Jonathan Cameron (7):
>   staging:iio:dac:ad5791 chan spec conversion.
>   staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop
>     unused poweroff timeout control.
>   staging:iio:adc:ad7152 use smbus read / write functions + checkpatch
>     fixes
>   staging:iio:adc:ad7152 set correct number of channels for ad7153.
>   staging:iio:adc:ad7152 bring more into line with abi.
>   staging:iio:adc:ad7291 bring into line with current abi + chan_spec
>     conversion.
>   staging:iio:imu:adis16400 cleanups
> 
> Michael Hennerich (9):
>   staging:iio:adc:ad7150: remove conversion mode handling.
>   staging:iio:adc:ad7150: Add support for the second interrupt strobe.
>   staging:iio:adc:ad7152: increase readability by introducing proper
>     bit defines
>   staging:iio:adc:ad7152: Miscellaneous fixes and touch-up
>   staging:iio:adc:ad7152: update scale handling
>   staging:iio:adc:ad7152: Add proper locking
>   staging:iio:adc:ad7152: Update sample rate, conversion time, digital
>     filter handling
>   staging:iio:adc:ad7152: Fix differential channel return value and
>     increase delay.
>   iio: imu: adis16400: Avoid using printk facility
> 
>  drivers/staging/iio/adc/ad7150.c            |  930 +++++++++++----------------
>  drivers/staging/iio/adc/ad7152.c            |  783 +++++++++++------------
>  drivers/staging/iio/adc/ad7291.c            |  892 +++++++++-----------------
>  drivers/staging/iio/dac/ad5791.c            |  158 ++---
>  drivers/staging/iio/dac/ad5791.h            |    4 -
>  drivers/staging/iio/imu/adis16400_core.c    |  607 ++++++++++++------
>  drivers/staging/iio/imu/adis16400_trigger.c |    2 +-
>  7 files changed, 1560 insertions(+), 1816 deletions(-)
> 

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

end of thread, other threads:[~2011-09-02 16:24 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-26 10:19 [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron
2011-08-26 10:19 ` [PATCH 01/16] staging:iio:dac:ad5791 chan spec conversion Jonathan Cameron
2011-08-26 10:19 ` [PATCH 02/16] staging:iio:adc:ad7150: chan_spec conv + i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
2011-08-26 10:19 ` [PATCH 03/16] staging:iio:adc:ad7150: remove conversion mode handling Jonathan Cameron
2011-08-26 10:19 ` [PATCH 04/16] staging:iio:adc:ad7150: Add support for the second interrupt strobe Jonathan Cameron
2011-08-26 10:19 ` [PATCH 05/16] staging:iio:adc:ad7152 use smbus read / write functions + checkpatch fixes Jonathan Cameron
2011-08-26 10:19 ` [PATCH 06/16] staging:iio:adc:ad7152 set correct number of channels for ad7153 Jonathan Cameron
2011-08-26 10:19 ` [PATCH 07/16] staging:iio:adc:ad7152 bring more into line with abi Jonathan Cameron
2011-08-26 10:19 ` [PATCH 08/16] staging:iio:adc:ad7152: increase readability by introducing proper bit defines Jonathan Cameron
2011-08-26 10:19 ` [PATCH 09/16] staging:iio:adc:ad7152: Miscellaneous fixes and touch-up Jonathan Cameron
2011-08-26 10:19 ` [PATCH 10/16] staging:iio:adc:ad7152: update scale handling Jonathan Cameron
2011-08-26 10:19 ` [PATCH 11/16] staging:iio:adc:ad7152: Add proper locking Jonathan Cameron
2011-08-26 10:19 ` [PATCH 12/16] staging:iio:adc:ad7152: Update sample rate, conversion time, digital filter handling Jonathan Cameron
2011-08-26 10:19 ` [PATCH 13/16] staging:iio:adc:ad7152: Fix differential channel return value and increase delay Jonathan Cameron
2011-08-26 10:19 ` [PATCH 14/16] staging:iio:adc:ad7291 bring into line with current abi + chan_spec conversion Jonathan Cameron
2011-08-26 10:19 ` [PATCH 15/16] staging:iio:imu:adis16400 cleanups Jonathan Cameron
2011-08-26 10:19 ` [PATCH 16/16] iio: imu: adis16400: Avoid using printk facility Jonathan Cameron
2011-09-02 16:24 ` [PATCH 00/16] staging:iio: CDC and other driver updates Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.