All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150)
@ 2011-08-17  8:42 Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 1/6] staging:iio: Add capacitance type and average_raw chan info Jonathan Cameron
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

Hi All,

Couple of bits in here that I'll push out into next set of main cleanups.

Controversial bits (hence RFC) are the introduction of IIO_EV_TYPE_MAG_ADAPTIVE
and IIO_EV_TYPE_THRESH_ADAPTIVE, to handle the 'mean' shifted thresholds
of this device.  I'm far from convinced these are the right way to go,
but best I have come up with just yet.

Note this series is completely untested.  I haven't even verified that the
new chan spec related bits work right yet (can do that with a dummy driver).

Jonathan

Jonathan Cameron (6):
  staging:iio: Add capacitance type and average_raw chan info.
  staging:iio:attrs - make address a u64 to allow event codes to be
    used.
  staging:iio:add adaptive event types and missing extract_type macro.
  staging:iio:naming in the EV_BIT macro fix.
  staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff
    timeout control.
  staging:iio:adc:ad7150 initial chan_spec conversion

 drivers/staging/iio/adc/ad7150.c        |  837 ++++++++++++++-----------------
 drivers/staging/iio/iio.h               |    3 +
 drivers/staging/iio/industrialio-core.c |   26 +-
 drivers/staging/iio/sysfs.h             |    9 +-
 4 files changed, 411 insertions(+), 464 deletions(-)

-- 
1.7.3.4


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

* [PATCH 1/6] staging:iio: Add capacitance type and average_raw chan info.
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 2/6] staging:iio:attrs - make address a u64 to allow event codes to be used Jonathan Cameron
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

These are both needed for CAPADCs

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    3 +++
 drivers/staging/iio/industrialio-core.c |    2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 5f72d97..0f7df90 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -44,6 +44,7 @@ enum iio_chan_type {
 	IIO_ROT,
 	IIO_ANGL,
 	IIO_TIMESTAMP,
+	IIO_CAPACITANCE,
 };
 
 /* Nasty hack to avoid massive churn */
@@ -84,6 +85,8 @@ enum iio_chan_info_enum {
 	IIO_CHAN_INFO_PEAK_SCALE_SEPARATE,
 	IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED,
 	IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE,
+	IIO_CHAN_INFO_AVERAGE_RAW_SHARED,
+	IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE,
 };
 
 enum iio_endian {
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 534cde8..e1e6f07 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -63,6 +63,7 @@ static const char * const iio_chan_type_name_spec_shared[] = {
 	[IIO_ROT] = "rot",
 	[IIO_ANGL] = "angl",
 	[IIO_TIMESTAMP] = "timestamp",
+	[IIO_CAPACITANCE] = "capacitance",
 };
 
 static const char * const iio_chan_type_name_spec_complex[] = {
@@ -87,6 +88,7 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale",
 	[IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED/2]
 	= "quadrature_correction_raw",
+	[IIO_CHAN_INFO_AVERAGE_RAW_SHARED/2] = "mean_raw",
 };
 
 /**
-- 
1.7.3.4


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

* [PATCH 2/6] staging:iio:attrs - make address a u64 to allow event codes to be used.
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 1/6] staging:iio: Add capacitance type and average_raw chan info Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 3/6] staging:iio:add adaptive event types and missing extract_type macro Jonathan Cameron
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

Makes unusual event related attributes look a lot more like the core ones.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/sysfs.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 30f9a4d..dcb413d 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -22,7 +22,7 @@ struct iio_chan_spec;
  */
 struct iio_dev_attr {
 	struct device_attribute dev_attr;
-	int address;
+	u64 address;
 	struct list_head l;
 	struct iio_chan_spec const *c;
 };
-- 
1.7.3.4


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

* [PATCH 3/6] staging:iio:add adaptive event types and missing extract_type macro.
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 1/6] staging:iio: Add capacitance type and average_raw chan info Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 2/6] staging:iio:attrs - make address a u64 to allow event codes to be used Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 4/6] staging:iio:naming in the EV_BIT macro fix Jonathan Cameron
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

I'm not entirely sure this is the right way to go. Suggestions of other
options welcome!

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-core.c |    4 +++-
 drivers/staging/iio/sysfs.h             |    3 +++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index e1e6f07..a14f8fb 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -705,7 +705,9 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 static const char * const iio_ev_type_text[] = {
 	[IIO_EV_TYPE_THRESH] = "thresh",
 	[IIO_EV_TYPE_MAG] = "mag",
-	[IIO_EV_TYPE_ROC] = "roc"
+	[IIO_EV_TYPE_ROC] = "roc",
+	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
+	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
 };
 
 static const char * const iio_ev_dir_text[] = {
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index dcb413d..78f1a2a 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -118,6 +118,8 @@ enum iio_event_type {
 	IIO_EV_TYPE_THRESH,
 	IIO_EV_TYPE_MAG,
 	IIO_EV_TYPE_ROC,
+	IIO_EV_TYPE_THRESH_ADAPTIVE,
+	IIO_EV_TYPE_MAG_ADAPTIVE,
 };
 
 enum iio_event_direction {
@@ -142,6 +144,7 @@ enum iio_event_direction {
 #define IIO_UNMOD_EVENT_CODE(channelclass, number, type, direction)	\
 	IIO_EVENT_CODE(channelclass, 0, direction, type, number, 0, 0)
 
+#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
 #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xFF)
 
 /* Event code number extraction depends on which type of event we have.
-- 
1.7.3.4


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

* [PATCH 4/6] staging:iio:naming in the EV_BIT macro fix.
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
                   ` (2 preceding siblings ...)
  2011-08-17  8:42 ` [PATCH 3/6] staging:iio:add adaptive event types and missing extract_type macro Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  8:42 ` [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

Should always have been IIO_EV_DIR_MAX as that's what it actually controls.
Also reduced the number to 4 as not yet seen a case needing more and this
is not userspace visible anyway.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-core.c |   20 ++++++++++----------
 drivers/staging/iio/sysfs.h             |    4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index a14f8fb..5c81034 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -799,27 +799,27 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 
 	for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
-				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
-				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
+				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
 		if (postfix == NULL) {
 			ret = -ENOMEM;
 			goto error_ret;
 		}
 		if (chan->modified)
 			mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
-						  i/IIO_EV_TYPE_MAX,
-						  i%IIO_EV_TYPE_MAX);
+						  i/IIO_EV_DIR_MAX,
+						  i%IIO_EV_DIR_MAX);
 		else if (chan->type == IIO_VOLTAGE_DIFF)
 			mask = IIO_MOD_EVENT_CODE(chan->type,
 						  chan->channel,
 						  chan->channel2,
-						  i/IIO_EV_TYPE_MAX,
-						  i%IIO_EV_TYPE_MAX);
+						  i/IIO_EV_DIR_MAX,
+						  i%IIO_EV_DIR_MAX);
 		else
 			mask = IIO_UNMOD_EVENT_CODE(chan->type,
 						    chan->channel,
-						    i/IIO_EV_TYPE_MAX,
-						    i%IIO_EV_TYPE_MAX);
+						    i/IIO_EV_DIR_MAX,
+						    i%IIO_EV_DIR_MAX);
 
 		ret = __iio_add_chan_devattr(postfix,
 					     "events",
@@ -836,8 +836,8 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 			goto error_ret;
 
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
-				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
-				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
+				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
 		if (postfix == NULL) {
 			ret = -ENOMEM;
 			goto error_ret;
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 78f1a2a..3388b8c 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -133,9 +133,9 @@ enum iio_event_direction {
 	(((u64)type << 56) | ((u64)direction << 48) | ((u64)modifier << 40) | \
 	 ((u64)chan_type << 32) | (chan2 << 16) | chan1 | chan)
 
-#define IIO_EV_TYPE_MAX 8
+#define IIO_EV_DIR_MAX 4
 #define IIO_EV_BIT(type, direction)			\
-	(1 << (type*IIO_EV_TYPE_MAX + direction))
+	(1 << (type*IIO_EV_DIR_MAX + direction))
 
 #define IIO_MOD_EVENT_CODE(channelclass, number, modifier,		\
 			   type, direction)				\
-- 
1.7.3.4


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

* [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control.
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
                   ` (3 preceding siblings ...)
  2011-08-17  8:42 ` [PATCH 4/6] staging:iio:naming in the EV_BIT macro fix Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  9:04   ` Michael Hennerich
  2011-08-17  8:42 ` [PATCH 6/6] staging:iio:adc:ad7150 initial chan_spec conversion Jonathan Cameron
  2011-08-17  9:11 ` [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Michael Hennerich
  6 siblings, 1 reply; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, 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 |  279 +++++++++++++++++---------------------
 1 files changed, 122 insertions(+), 157 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 973fcea..2bea6fe 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -88,47 +88,6 @@ 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
  */
 
@@ -196,16 +155,23 @@ 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) {
 			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;
 		}
 	}
@@ -234,10 +200,13 @@ static ssize_t ad7150_show_ch1_value(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
+	int ret;
+
+	ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
+	if (ret < 0)
+		return ret;
 
-	ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
+	return sprintf(buf, "%d\n", ret);
 }
 
 static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value);
@@ -248,10 +217,13 @@ static ssize_t ad7150_show_ch2_value(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u8 data[2];
+	int ret;
+
+	ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
+	if (ret < 0)
+		return ret;
 
-	ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2);
-	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
+	return sprintf(buf, "%d\n", ret);
 }
 
 static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value);
@@ -273,21 +245,28 @@ static ssize_t ad7150_store_threshold_mode(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
+	int ret;
 	u8 cfg;
 
-	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;
 
 	if (strncmp(buf, "fixed", 5) == 0) {
 		strcpy(chip->threshold_mode, "fixed");
 		cfg |= AD7150_CFG_FIX;
-		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;
 	} else if (strncmp(buf, "adaptive", 8) == 0) {
 		strcpy(chip->threshold_mode, "adaptive");
 		cfg &= ~AD7150_CFG_FIX;
-		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;
 	}
 
@@ -316,19 +295,22 @@ static ssize_t ad7150_store_ch1_threshold(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u16 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtou16(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
-	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;
-	}
+	ret = i2c_smbus_write_word_data(chip->client,
+					AD7150_CH1_THR_HOLD_H,
+					data);
+	if (ret < 0)
+		return ret;
 
-	return -EINVAL;
+	chip->ch1_threshold = data;
+
+	return len;
 }
 
 static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR,
@@ -352,19 +334,22 @@ static ssize_t ad7150_store_ch2_threshold(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u16 data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtou16(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
-	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_write_word_data(chip->client,
+					AD7150_CH2_THR_HOLD_H,
+					data);
+	if (ret < 0)
+		return ret;
 
-	return -EINVAL;
+	chip->ch2_threshold = data;
+
+	return len;
 }
 
 static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR,
@@ -388,18 +373,21 @@ static ssize_t ad7150_store_ch1_sensitivity(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_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,
+					AD7150_CH1_SENSITIVITY,
+					data);
+	if (ret < 0)
+		return ret;
 
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data);
-		chip->ch1_sensitivity = data;
-		return len;
-	}
+	chip->ch1_sensitivity = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR,
@@ -423,18 +411,21 @@ static ssize_t ad7150_store_ch2_sensitivity(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_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,
+					AD7150_CH2_SENSITIVITY,
+					data);
+	if (ret < 0)
+		return ret;
 
-	if ((!ret) && (data < 0x100)) {
-		ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data);
-		chip->ch2_sensitivity = data;
-		return len;
-	}
+	chip->ch2_sensitivity = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR,
@@ -458,18 +449,19 @@ static ssize_t ad7150_store_ch1_timeout(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_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)) {
-		ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data);
-		chip->ch1_timeout = data;
-		return len;
-	}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_TIMEOUT, data);
+	if (ret < 0)
+		return ret;
+	chip->ch1_timeout = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR,
@@ -493,18 +485,19 @@ static ssize_t ad7150_store_ch2_timeout(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_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)) {
-		ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data);
-		chip->ch2_timeout = data;
-		return len;
-	}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_TIMEOUT, data);
+	if (ret < 0)
+		return ret;
+	chip->ch2_timeout = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR,
@@ -528,19 +521,19 @@ static ssize_t ad7150_store_ch1_setup(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	unsigned long data;
+	u8 data;
 	int 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;
-	}
+	ret = kstrtou8(buf, 10, &data);
+	if (ret < 0)
+		return ret;
 
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_SETUP, data);
+	if (ret < 0)
+		return ret;
+	chip->ch1_setup = data;
 
-	return -EINVAL;
+	return len;
 }
 
 static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
@@ -564,58 +557,25 @@ static ssize_t ad7150_store_ch2_setup(struct device *dev,
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7150_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)) {
-		ad7150_i2c_write(chip, AD7150_CH2_SETUP, data);
-		chip->ch2_setup = data;
-		return len;
-	}
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_SETUP, data);
+	if (ret < 0)
+		return ret;
+	chip->ch2_setup = data;
 
-	return -EINVAL;
+	return len;
 }
 
 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);
-}
-
-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;
-
-	ret = strict_strtoul(buf, 10, &data);
-
-	if ((!ret) && (data < 0x40)) {
-		chip->powerdown_timer = data;
-		return len;
-	}
-
-	return -EINVAL;
-}
-
-static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR,
-		ad7150_show_powerdown_timer,
-		ad7150_store_powerdown_timer);
-
 static struct attribute *ad7150_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
@@ -629,7 +589,6 @@ static struct attribute *ad7150_attributes[] = {
 	&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 +608,14 @@ 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;
+
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_STATUS);
+
+	if (ret < 0)
+		return IRQ_HANDLED;
 
-	ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1);
+	int_status = ret;
 
 	if ((int_status & AD7150_STATUS_OUT1) &&
 	    !(chip->old_state & AD7150_STATUS_OUT1))
-- 
1.7.3.4

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

* [PATCH 6/6] staging:iio:adc:ad7150 initial chan_spec conversion
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
                   ` (4 preceding siblings ...)
  2011-08-17  8:42 ` [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
@ 2011-08-17  8:42 ` Jonathan Cameron
  2011-08-17  9:11 ` [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Michael Hennerich
  6 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  8:42 UTC (permalink / raw)
  To: linux-iio; +Cc: device-drivers-devel, Jonathan Cameron

Adds access to the average values.

I have left the ugly conversion modes stuff there as I don't have
a test part to confirm any changes are correct.  This will have
to be automated in the final version.

Also added a todo list and some documentation.

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

diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index 2bea6fe..6afba92 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 {
@@ -91,36 +105,10 @@ ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
  * 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,
@@ -130,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;
 }
@@ -164,7 +153,8 @@ static ssize_t ad7150_store_conversion_mode(struct device *dev,
 
 	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;
 			ret = i2c_smbus_write_byte_data(chip->client,
@@ -185,378 +175,295 @@ 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);
-	int ret;
-
-	ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", ret);
-}
-
-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);
-	int ret;
-
-	ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", ret);
-}
-
-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 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_threshold_mode(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);
 	int ret;
-	u8 cfg;
-
-	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
-	if (ret < 0)
-		return ret;
-	cfg = ret;
+	struct ad7150_chip_info *chip = iio_priv(indio_dev);
 
-	if (strncmp(buf, "fixed", 5) == 0) {
-		strcpy(chip->threshold_mode, "fixed");
-		cfg |= AD7150_CFG_FIX;
-		ret = i2c_smbus_write_byte_data(chip->client, AD7150_CFG, cfg);
+	switch (mask) {
+	case 0:
+		ret = i2c_smbus_read_word_data(chip->client,
+					ad7150_addresses[chan->channel][0]);
 		if (ret < 0)
 			return ret;
-
-		return len;
-	} else if (strncmp(buf, "adaptive", 8) == 0) {
-		strcpy(chip->threshold_mode, "adaptive");
-		cfg &= ~AD7150_CFG_FIX;
-		ret = i2c_smbus_write_byte_data(chip->client, AD7150_CFG, cfg);
+		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;
-		return len;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
 	}
-
-	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)
+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);
-
-	return sprintf(buf, "%d\n", chip->ch1_threshold);
-}
-
-static ssize_t ad7150_store_ch1_threshold(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);
-	u16 data;
-	int ret;
-
-	ret = kstrtou16(buf, 10, &data);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_word_data(chip->client,
-					AD7150_CH1_THR_HOLD_H,
-					data);
-	if (ret < 0)
-		return ret;
-
-	chip->ch1_threshold = data;
-
-	return len;
-}
-
-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)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = iio_priv(dev_info);
-	u16 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 = kstrtou16(buf, 10, &data);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_word_data(chip->client,
-					AD7150_CH2_THR_HOLD_H,
-					data);
+	ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
 	if (ret < 0)
 		return ret;
 
-	chip->ch2_threshold = data;
-
-	return len;
-}
-
-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);
+	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 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);
-	u8 data;
 	int ret;
-
-	ret = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return 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],
+						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_CH1_SENSITIVITY,
-					data);
+					ad7150_addresses[chan][4],
+					sens);
 	if (ret < 0)
 		return ret;
 
-	chip->ch1_sensitivity = data;
-
-	return len;
-}
-
-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);
-
-	return sprintf(buf, "%d\n", chip->ch2_sensitivity);
-}
-
-static ssize_t ad7150_store_ch2_sensitivity(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 data;
-	int ret;
-
-	ret = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return ret;
 	ret = i2c_smbus_write_byte_data(chip->client,
-					AD7150_CH2_SENSITIVITY,
-					data);
+					ad7150_addresses[chan][5],
+					timeout);
 	if (ret < 0)
 		return ret;
 
-	chip->ch2_sensitivity = data;
-
-	return len;
-}
-
-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);
+	return 0;
 }
 
-static ssize_t ad7150_store_ch1_timeout(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);
-	u8 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 = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return ret;
+	/* Something must always be turned on */
+	if (state == 0)
+		return -EINVAL;
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_TIMEOUT, data);
+	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)
-		return ret;
-	chip->ch1_timeout = data;
-
-	return len;
-}
-
-static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR,
-		ad7150_show_ch1_timeout,
-		ad7150_store_ch1_timeout);
-
-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);
+		goto error_ret;
 
-	return sprintf(buf, "%d\n", chip->ch2_timeout);
-}
+	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;
+	};
 
-static ssize_t ad7150_store_ch2_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);
-	u8 data;
-	int ret;
+	cfg |= (adaptive << 7) | (thresh_type << 5);
 
-	ret = kstrtou8(buf, 10, &data);
+	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CFG, cfg);
 	if (ret < 0)
-		return ret;
+		goto error_ret;
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_TIMEOUT, data);
-	if (ret < 0)
-		return ret;
-	chip->ch2_timeout = data;
+	chip->current_event = event_code;
 
-	return len;
-}
+	/* update control attributes */
+	ret = ad7150_write_event_params(indio_dev, event_code);
+error_ret:
+	mutex_unlock(&chip->state_lock);
 
-static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_timeout,
-		ad7150_store_ch2_timeout);
+	return 0;
+}
 
-static ssize_t ad7150_show_ch1_setup(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+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);
-
-	return sprintf(buf, "0x%02x\n", chip->ch1_setup);
+	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);
+
+	/* 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;
+
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+		*val = chip->thresh_sensitivity[rising][chan];
+		return 0;
+
+	case IIO_EV_TYPE_THRESH:
+		*val = chip->threshold[rising][chan];
+		return 0;
+
+	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);
-	u8 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 = kstrtou8(buf, 10, &data);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_SETUP, data);
-	if (ret < 0)
-		return ret;
-	chip->ch1_setup = data;
+	/* write back if active */
+	ret = ad7150_write_event_params(indio_dev, event_code);
 
-	return len;
+	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);
-
-	return sprintf(buf, "0x%02x\n", chip->ch2_setup);
+	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, "%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);
+	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;
 
@@ -564,33 +471,78 @@ static ssize_t ad7150_store_ch2_setup(struct device *dev,
 	if (ret < 0)
 		return ret;
 
-	ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_SETUP, data);
+	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 = ad7150_write_event_params(indio_dev, this_attr->address);
+error_ret:
+	mutex_unlock(&chip->state_lock);
+
 	if (ret < 0)
 		return ret;
-	chip->ch2_setup = data;
 
 	return len;
 }
 
-static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
-		ad7150_show_ch2_setup,
-		ad7150_store_ch2_setup);
+#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_ch1_value.dev_attr.attr,
-	&iio_dev_attr_ch2_value.dev_attr.attr,
 	NULL,
 };
 
@@ -611,7 +563,6 @@ static irqreturn_t ad7150_event_handler(int irq, void *private)
 	int ret;
 
 	ret = i2c_smbus_read_byte_data(chip->client, AD7150_STATUS);
-
 	if (ret < 0)
 		return IRQ_HANDLED;
 
@@ -650,19 +601,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,
 };
 
@@ -675,7 +637,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
  */
@@ -693,13 +661,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;
@@ -723,7 +694,8 @@ static int __devinit ad7150_probe(struct i2c_client *client,
 			goto error_free_dev;
 	}
 
-	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;
 
-- 
1.7.3.4


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

* Re: [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control.
  2011-08-17  8:42 ` [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
@ 2011-08-17  9:04   ` Michael Hennerich
  2011-08-17  9:29     ` Jonathan Cameron
  0 siblings, 1 reply; 13+ messages in thread
From: Michael Hennerich @ 2011-08-17  9:04 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
> 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 |  279 +++++++++++++++++---------------------
>   1 files changed, 122 insertions(+), 157 deletions(-)
>
> diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
> index 973fcea..2bea6fe 100644
> --- a/drivers/staging/iio/adc/ad7150.c
> +++ b/drivers/staging/iio/adc/ad7150.c
> @@ -88,47 +88,6 @@ 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
>    */
>
> @@ -196,16 +155,23 @@ 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) {
>                          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;
>                  }
>          }
> @@ -234,10 +200,13 @@ static ssize_t ad7150_show_ch1_value(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> -       u8 data[2];
> +       int ret;
> +
> +       ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);

Hi Jonathan,

Byte ordering issue here-

SMBus Read Word:  i2c_smbus_read_word_data()
============================================

This operation is very like Read Byte; again, data is read from a
device, from a designated register that is specified through the Comm
byte. But this time, the data is a complete word (16 bits).

S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA

i2c_smbus_read_word_data() and i2c_smbus_write_word_data() assumes the
Low byte first - however the AD7150 transmits and expects the High-byte 
first.

Therefore we need an unconditional swab16() for all smbus word transactions.

return sprintf(buf, "%d\n", swab16(ret));


-Michael

> +       if (ret<  0)
> +               return ret;
>
> -       ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2);
> -       return sprintf(buf, "%d\n", ((int) data[0]<<  8) | data[1]);
> +       return sprintf(buf, "%d\n", ret);
>   }
>
>   static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value);
> @@ -248,10 +217,13 @@ static ssize_t ad7150_show_ch2_value(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> -       u8 data[2];
> +       int ret;
> +
> +       ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
> +       if (ret<  0)
> +               return ret;
>
> -       ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2);
> -       return sprintf(buf, "%d\n", ((int) data[0]<<  8) | data[1]);
> +       return sprintf(buf, "%d\n", ret);
>   }
>
>   static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value);
> @@ -273,21 +245,28 @@ static ssize_t ad7150_store_threshold_mode(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> +       int ret;
>          u8 cfg;
>
> -       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;
>
>          if (strncmp(buf, "fixed", 5) == 0) {
>                  strcpy(chip->threshold_mode, "fixed");
>                  cfg |= AD7150_CFG_FIX;
> -               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;
>          } else if (strncmp(buf, "adaptive", 8) == 0) {
>                  strcpy(chip->threshold_mode, "adaptive");
>                  cfg&= ~AD7150_CFG_FIX;
> -               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;
>          }
>
> @@ -316,19 +295,22 @@ static ssize_t ad7150_store_ch1_threshold(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> -       unsigned long data;
> +       u16 data;
>          int ret;
>
> -       ret = strict_strtoul(buf, 10,&data);
> +       ret = kstrtou16(buf, 10,&data);
> +       if (ret<  0)
> +               return ret;
>
> -       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;
> -       }
> +       ret = i2c_smbus_write_word_data(chip->client,
> +                                       AD7150_CH1_THR_HOLD_H,
> +                                       data);
> +       if (ret<  0)
> +               return ret;
>
> -       return -EINVAL;
> +       chip->ch1_threshold = data;
> +
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR,
> @@ -352,19 +334,22 @@ static ssize_t ad7150_store_ch2_threshold(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> -       unsigned long data;
> +       u16 data;
>          int ret;
>
> -       ret = strict_strtoul(buf, 10,&data);
> +       ret = kstrtou16(buf, 10,&data);
> +       if (ret<  0)
> +               return ret;
>
> -       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_write_word_data(chip->client,
> +                                       AD7150_CH2_THR_HOLD_H,
> +                                       data);
> +       if (ret<  0)
> +               return ret;
>
> -       return -EINVAL;
> +       chip->ch2_threshold = data;
> +
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR,
> @@ -388,18 +373,21 @@ static ssize_t ad7150_store_ch1_sensitivity(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_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,
> +                                       AD7150_CH1_SENSITIVITY,
> +                                       data);
> +       if (ret<  0)
> +               return ret;
>
> -       if ((!ret)&&  (data<  0x100)) {
> -               ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data);
> -               chip->ch1_sensitivity = data;
> -               return len;
> -       }
> +       chip->ch1_sensitivity = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR,
> @@ -423,18 +411,21 @@ static ssize_t ad7150_store_ch2_sensitivity(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_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,
> +                                       AD7150_CH2_SENSITIVITY,
> +                                       data);
> +       if (ret<  0)
> +               return ret;
>
> -       if ((!ret)&&  (data<  0x100)) {
> -               ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data);
> -               chip->ch2_sensitivity = data;
> -               return len;
> -       }
> +       chip->ch2_sensitivity = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR,
> @@ -458,18 +449,19 @@ static ssize_t ad7150_store_ch1_timeout(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_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)) {
> -               ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data);
> -               chip->ch1_timeout = data;
> -               return len;
> -       }
> +       ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_TIMEOUT, data);
> +       if (ret<  0)
> +               return ret;
> +       chip->ch1_timeout = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR,
> @@ -493,18 +485,19 @@ static ssize_t ad7150_store_ch2_timeout(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_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)) {
> -               ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data);
> -               chip->ch2_timeout = data;
> -               return len;
> -       }
> +       ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_TIMEOUT, data);
> +       if (ret<  0)
> +               return ret;
> +       chip->ch2_timeout = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR,
> @@ -528,19 +521,19 @@ static ssize_t ad7150_store_ch1_setup(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_chip_info *chip = iio_priv(dev_info);
> -       unsigned long data;
> +       u8 data;
>          int 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;
> -       }
> +       ret = kstrtou8(buf, 10,&data);
> +       if (ret<  0)
> +               return ret;
>
> +       ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH1_SETUP, data);
> +       if (ret<  0)
> +               return ret;
> +       chip->ch1_setup = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
> @@ -564,58 +557,25 @@ static ssize_t ad7150_store_ch2_setup(struct device *dev,
>   {
>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>          struct ad7150_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)) {
> -               ad7150_i2c_write(chip, AD7150_CH2_SETUP, data);
> -               chip->ch2_setup = data;
> -               return len;
> -       }
> +       ret = i2c_smbus_write_byte_data(chip->client, AD7150_CH2_SETUP, data);
> +       if (ret<  0)
> +               return ret;
> +       chip->ch2_setup = data;
>
> -       return -EINVAL;
> +       return len;
>   }
>
>   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);
> -}
> -
> -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;
> -
> -       ret = strict_strtoul(buf, 10,&data);
> -
> -       if ((!ret)&&  (data<  0x40)) {
> -               chip->powerdown_timer = data;
> -               return len;
> -       }
> -
> -       return -EINVAL;
> -}
> -
> -static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR,
> -               ad7150_show_powerdown_timer,
> -               ad7150_store_powerdown_timer);
> -
>   static struct attribute *ad7150_attributes[] = {
>          &iio_dev_attr_available_conversion_modes.dev_attr.attr,
>          &iio_dev_attr_conversion_mode.dev_attr.attr,
> @@ -629,7 +589,6 @@ static struct attribute *ad7150_attributes[] = {
>          &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 +608,14 @@ 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;
> +
> +       ret = i2c_smbus_read_byte_data(chip->client, AD7150_STATUS);
> +
> +       if (ret<  0)
> +               return IRQ_HANDLED;
>
> -       ad7150_i2c_read(chip, AD7150_STATUS,&int_status, 1);
> +       int_status = ret;
>
>          if ((int_status&  AD7150_STATUS_OUT1)&&
>              !(chip->old_state&  AD7150_STATUS_OUT1))
> --
> 1.7.3.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif

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

* Re: [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150)
  2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
                   ` (5 preceding siblings ...)
  2011-08-17  8:42 ` [PATCH 6/6] staging:iio:adc:ad7150 initial chan_spec conversion Jonathan Cameron
@ 2011-08-17  9:11 ` Michael Hennerich
  2011-08-17  9:57   ` Jonathan Cameron
  6 siblings, 1 reply; 13+ messages in thread
From: Michael Hennerich @ 2011-08-17  9:11 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
> Hi All,
>
> Couple of bits in here that I'll push out into next set of main cleanups.
>
> Controversial bits (hence RFC) are the introduction of IIO_EV_TYPE_MAG_ADAPTIVE
> and IIO_EV_TYPE_THRESH_ADAPTIVE, to handle the 'mean' shifted thresholds
> of this device.  I'm far from convinced these are the right way to go,
> but best I have come up with just yet.
>
> Note this series is completely untested.  I haven't even verified that the
> new chan spec related bits work right yet (can do that with a dummy driver).
Hi Jonathan,

I have a EVAL-AD7156EBZ board, so I should be able to test the driver.
Can you please push these patches onto your iio-blue git?

Regards,
Michael

> Jonathan
>
> Jonathan Cameron (6):
>    staging:iio: Add capacitance type and average_raw chan info.
>    staging:iio:attrs - make address a u64 to allow event codes to be
>      used.
>    staging:iio:add adaptive event types and missing extract_type macro.
>    staging:iio:naming in the EV_BIT macro fix.
>    staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff
>      timeout control.
>    staging:iio:adc:ad7150 initial chan_spec conversion
>
>   drivers/staging/iio/adc/ad7150.c        |  837 ++++++++++++++-----------------
>   drivers/staging/iio/iio.h               |    3 +
>   drivers/staging/iio/industrialio-core.c |   26 +-
>   drivers/staging/iio/sysfs.h             |    9 +-
>   4 files changed, 411 insertions(+), 464 deletions(-)
>
> --
> 1.7.3.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif

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

* Re: [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control.
  2011-08-17  9:04   ` Michael Hennerich
@ 2011-08-17  9:29     ` Jonathan Cameron
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  9:29 UTC (permalink / raw)
  To: michael.hennerich
  Cc: linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

On 08/17/11 10:04, Michael Hennerich wrote:
> On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
>> 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 |  279 +++++++++++++++++---------------------
>>   1 files changed, 122 insertions(+), 157 deletions(-)
>>
>> diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
>> index 973fcea..2bea6fe 100644
>> --- a/drivers/staging/iio/adc/ad7150.c
>> +++ b/drivers/staging/iio/adc/ad7150.c
>> @@ -88,47 +88,6 @@ 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
>>    */
>>
>> @@ -196,16 +155,23 @@ 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) {
>>                          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;
>>                  }
>>          }
>> @@ -234,10 +200,13 @@ static ssize_t ad7150_show_ch1_value(struct device *dev,
>>   {
>>          struct iio_dev *dev_info = dev_get_drvdata(dev);
>>          struct ad7150_chip_info *chip = iio_priv(dev_info);
>> -       u8 data[2];
>> +       int ret;
>> +
>> +       ret = i2c_smbus_read_word_data(chip->client, AD7150_CH1_DATA_HIGH);
> 
> Hi Jonathan,
> 
> Byte ordering issue here-
> 
> SMBus Read Word:  i2c_smbus_read_word_data()
> ============================================
> 
> This operation is very like Read Byte; again, data is read from a
> device, from a designated register that is specified through the Comm
> byte. But this time, the data is a complete word (16 bits).
> 
> S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA
> 
> i2c_smbus_read_word_data() and i2c_smbus_write_word_data() assumes the
> Low byte first - however the AD7150 transmits and expects the High-byte first.
> 
> Therefore we need an unconditional swab16() for all smbus word transactions.
> 
> return sprintf(buf, "%d\n", swab16(ret));
> 
> 
> -Michael

Good catch. Thanks - will update through the series.


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

* Re: [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150)
  2011-08-17  9:11 ` [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Michael Hennerich
@ 2011-08-17  9:57   ` Jonathan Cameron
  2011-08-17 11:37     ` Jonathan Cameron
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17  9:57 UTC (permalink / raw)
  To: michael.hennerich
  Cc: linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

On 08/17/11 10:11, Michael Hennerich wrote:
> On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
>> Hi All,
>>
>> Couple of bits in here that I'll push out into next set of main cleanups.
>>
>> Controversial bits (hence RFC) are the introduction of IIO_EV_TYPE_MAG_ADAPTIVE
>> and IIO_EV_TYPE_THRESH_ADAPTIVE, to handle the 'mean' shifted thresholds
>> of this device.  I'm far from convinced these are the right way to go,
>> but best I have come up with just yet.
>>
>> Note this series is completely untested.  I haven't even verified that the
>> new chan spec related bits work right yet (can do that with a dummy driver).
> Hi Jonathan,
> 
> I have a EVAL-AD7156EBZ board, so I should be able to test the driver.
> Can you please push these patches onto your iio-blue git?
> 
Will do. Have fixed the swab16 requirements I think.

Branch is capfun. The push included a few other minor bits and bobs
in the master branch but nothing interesting..




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

* RE: [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150)
  2011-08-17 11:37     ` Jonathan Cameron
@ 2011-08-17 11:32       ` Hennerich, Michael
  0 siblings, 0 replies; 13+ messages in thread
From: Hennerich, Michael @ 2011-08-17 11:32 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

Jonathan Cameron wrote on 2011-08-17:
> On 08/17/11 10:57, Jonathan Cameron wrote:
>> On 08/17/11 10:11, Michael Hennerich wrote:
>>> On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
>>>> Hi All,
>>>>
>>>> Couple of bits in here that I'll push out into next set of main
>>>> cleanups.
>>>>
>>>> Controversial bits (hence RFC) are the introduction of
>>>> IIO_EV_TYPE_MAG_ADAPTIVE and IIO_EV_TYPE_THRESH_ADAPTIVE, to handle
>>>> the 'mean' shifted thresholds of this device.  I'm far from convinced
>>>> these are the right way to go, but best I have come up with just yet.
>>>>
>>>> Note this series is completely untested.  I haven't even verified
>>>> that the new chan spec related bits work right yet (can do that
> with a dummy driver).
>>> Hi Jonathan,
>>>
>>> I have a EVAL-AD7156EBZ board, so I should be able to test the driver.
>>> Can you please push these patches onto your iio-blue git?
>>>
>> Will do. Have fixed the swab16 requirements I think.
>>
>> Branch is capfun. The push included a few other minor bits and bobs in
>> the master branch but nothing interesting..
> Also, some ad7152 changes in there, but currently non compiling. oops.

Also have a EVAL-AD7152, so I'll test it as well.

Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368; Gesch=
aeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin, Margaret=
 Seif

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

* Re: [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150)
  2011-08-17  9:57   ` Jonathan Cameron
@ 2011-08-17 11:37     ` Jonathan Cameron
  2011-08-17 11:32       ` Hennerich, Michael
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Cameron @ 2011-08-17 11:37 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: michael.hennerich, linux-iio@vger.kernel.org,
	device-drivers-devel@blackfin.uclinux.org

On 08/17/11 10:57, Jonathan Cameron wrote:
> On 08/17/11 10:11, Michael Hennerich wrote:
>> On 08/17/2011 10:42 AM, Jonathan Cameron wrote:
>>> Hi All,
>>>
>>> Couple of bits in here that I'll push out into next set of main cleanups.
>>>
>>> Controversial bits (hence RFC) are the introduction of IIO_EV_TYPE_MAG_ADAPTIVE
>>> and IIO_EV_TYPE_THRESH_ADAPTIVE, to handle the 'mean' shifted thresholds
>>> of this device.  I'm far from convinced these are the right way to go,
>>> but best I have come up with just yet.
>>>
>>> Note this series is completely untested.  I haven't even verified that the
>>> new chan spec related bits work right yet (can do that with a dummy driver).
>> Hi Jonathan,
>>
>> I have a EVAL-AD7156EBZ board, so I should be able to test the driver.
>> Can you please push these patches onto your iio-blue git?
>>
> Will do. Have fixed the swab16 requirements I think.
> 
> Branch is capfun. The push included a few other minor bits and bobs
> in the master branch but nothing interesting..
Also, some ad7152 changes in there, but currently non compiling. oops.

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

end of thread, other threads:[~2011-08-17 11:37 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-17  8:42 [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Jonathan Cameron
2011-08-17  8:42 ` [PATCH 1/6] staging:iio: Add capacitance type and average_raw chan info Jonathan Cameron
2011-08-17  8:42 ` [PATCH 2/6] staging:iio:attrs - make address a u64 to allow event codes to be used Jonathan Cameron
2011-08-17  8:42 ` [PATCH 3/6] staging:iio:add adaptive event types and missing extract_type macro Jonathan Cameron
2011-08-17  8:42 ` [PATCH 4/6] staging:iio:naming in the EV_BIT macro fix Jonathan Cameron
2011-08-17  8:42 ` [PATCH 5/6] staging:iio:adc:ad7150: use i2c_smbus commands + drop unused poweroff timeout control Jonathan Cameron
2011-08-17  9:04   ` Michael Hennerich
2011-08-17  9:29     ` Jonathan Cameron
2011-08-17  8:42 ` [PATCH 6/6] staging:iio:adc:ad7150 initial chan_spec conversion Jonathan Cameron
2011-08-17  9:11 ` [RFC PATCH 0/6] IIO: capacitance ADC cleanup (ad7150) Michael Hennerich
2011-08-17  9:57   ` Jonathan Cameron
2011-08-17 11:37     ` Jonathan Cameron
2011-08-17 11:32       ` Hennerich, Michael

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.