* [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines
@ 2011-08-24 12:45 michael.hennerich
2011-08-24 12:45 ` [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up michael.hennerich
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: michael.hennerich @ 2011-08-24 12:45 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, device-drivers-devel, drivers, Michael Hennerich
From: Michael Hennerich <michael.hennerich@analog.com>
Some other miscellaneous cleanup.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
---
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.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
@ 2011-08-24 12:45 ` michael.hennerich
2011-08-24 14:13 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 3/5] iio: ad7152: update scale handling michael.hennerich
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: michael.hennerich @ 2011-08-24 12:45 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, device-drivers-devel, drivers, Michael Hennerich
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>
---
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.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/5] iio: ad7152: update scale handling
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
2011-08-24 12:45 ` [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up michael.hennerich
@ 2011-08-24 12:45 ` michael.hennerich
2011-08-24 14:14 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 4/5] iio: ad7152: Add proper locking michael.hennerich
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: michael.hennerich @ 2011-08-24 12:45 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, device-drivers-devel, drivers, Michael Hennerich
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>
---
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.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/5] iio: ad7152: Add proper locking
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
2011-08-24 12:45 ` [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up michael.hennerich
2011-08-24 12:45 ` [PATCH 3/5] iio: ad7152: update scale handling michael.hennerich
@ 2011-08-24 12:45 ` michael.hennerich
2011-08-24 14:15 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling michael.hennerich
2011-08-24 14:11 ` [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines Jonathan Cameron
4 siblings, 1 reply; 10+ messages in thread
From: michael.hennerich @ 2011-08-24 12:45 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, device-drivers-devel, drivers, Michael Hennerich
From: Michael Hennerich <michael.hennerich@analog.com>
Add proper locking.
Consistently use indio_dev.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
---
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.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
` (2 preceding siblings ...)
2011-08-24 12:45 ` [PATCH 4/5] iio: ad7152: Add proper locking michael.hennerich
@ 2011-08-24 12:45 ` michael.hennerich
2011-08-24 14:18 ` Jonathan Cameron
2011-08-24 14:11 ` [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines Jonathan Cameron
4 siblings, 1 reply; 10+ messages in thread
From: michael.hennerich @ 2011-08-24 12:45 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, device-drivers-devel, drivers, Michael Hennerich
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>
---
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.0.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
` (3 preceding siblings ...)
2011-08-24 12:45 ` [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling michael.hennerich
@ 2011-08-24 14:11 ` Jonathan Cameron
4 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2011-08-24 14:11 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-iio, device-drivers-devel, drivers
On 08/24/11 13:45, michael.hennerich@analog.com wrote:
> 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>
merged into iio-blue.git
> ---
> 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);
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up
2011-08-24 12:45 ` [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up michael.hennerich
@ 2011-08-24 14:13 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2011-08-24 14:13 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-iio, device-drivers-devel, drivers
On 08/24/11 13:45, michael.hennerich@analog.com wrote:
> 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>
merged into iio-blue.git
Thanks,
> ---
> 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):
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/5] iio: ad7152: update scale handling
2011-08-24 12:45 ` [PATCH 3/5] iio: ad7152: update scale handling michael.hennerich
@ 2011-08-24 14:14 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2011-08-24 14:14 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-iio, device-drivers-devel, drivers
On 08/24/11 13:45, michael.hennerich@analog.com wrote:
> 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>
merged into iio-blue.git
> ---
> 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,
> };
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 4/5] iio: ad7152: Add proper locking
2011-08-24 12:45 ` [PATCH 4/5] iio: ad7152: Add proper locking michael.hennerich
@ 2011-08-24 14:15 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2011-08-24 14:15 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-iio, device-drivers-devel, drivers
On 08/24/11 13:45, michael.hennerich@analog.com wrote:
> 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>
merged into iio-blue.git
> ---
> 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,
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling
2011-08-24 12:45 ` [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling michael.hennerich
@ 2011-08-24 14:18 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2011-08-24 14:18 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-iio, device-drivers-devel, drivers
On 08/24/11 13:45, michael.hennerich@analog.com wrote:
> From: Michael Hennerich <michael.hennerich@analog.com>
>
> Rename attribute, use sampling_frequency instead.
> Attribute now accepts values in Hz.
> Delay readout accordingly.
Thanks for this excellent series. Another driver we can add to our
list of 'good' ones :)
>
> 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]);
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-08-24 14:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-24 12:45 [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines michael.hennerich
2011-08-24 12:45 ` [PATCH 2/5] iio: ad7152: Miscellaneous fixes and touch-up michael.hennerich
2011-08-24 14:13 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 3/5] iio: ad7152: update scale handling michael.hennerich
2011-08-24 14:14 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 4/5] iio: ad7152: Add proper locking michael.hennerich
2011-08-24 14:15 ` Jonathan Cameron
2011-08-24 12:45 ` [PATCH 5/5] iio: ad7152: Update sample rate, conversion time, digital filter handling michael.hennerich
2011-08-24 14:18 ` Jonathan Cameron
2011-08-24 14:11 ` [PATCH 1/5] iio: ad7152: increase readability by introducing proper bit defines 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.