summaryrefslogtreecommitdiff
path: root/drivers/staging/iio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 19:11:39 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 19:11:39 (GMT)
commitdef7cb8cd4e3258db88050eaaca5438bcc3dafca (patch)
tree23fcf90ddc98acec07bb115c2f7740c21cf44a84 /drivers/staging/iio
parent06d2fe153b9b35e57221e35831a26918f462db68 (diff)
parente1878957b4676a17cf398f7f5723b365e9a2ca48 (diff)
downloadlinux-fsl-qoriq-def7cb8cd4e3258db88050eaaca5438bcc3dafca.tar.xz
Merge tag 'staging-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree update from Greg Kroah-Hartman: "Here is the big staging tree update for the 3.7-rc1 merge window. There are a few patches in here that are outside of the staging area, namely HID and IIO patches, but all of them have been acked by the relevant subsystem maintainers. The IIO stuff is still coming in through this tree as it hasn't entirely moved out of the staging tree, but is almost there. Other than that, there wa a ton of work on the comedi drivers to make them more readable and the correct style. Doing that removed a lot of code, but we added a new driver to the staging tree, so we didn't end up with a net reduction this time around: 662 files changed, 51649 insertions(+), 26582 deletions(-) All of these patches have been in the linux-next tree already. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'staging-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1094 commits) staging: comedi: jr3_pci: fix iomem dereference staging: comedi: drivers: use comedi_fc.h cmdtest helpers Staging: winbond: usb_free_urb(NULL) is safe Staging: winbond: checkpatch cleanup Staging: winbond: Removed undesired spaces, lines and tabs Staging: winbond: Typo corrections in comments Staging: winbond: Changed c99 comments to c89 comments staging: r8712u: Do not queue cloned skb staging: comedi: ni_mio_common: always lock in ni_ai_poll() staging: comedi: s626: add FIXME comment staging: comedi: s626: don't dereference insn->data staging: comedi: s526: fix if() check in s526_gpct_winsn() staging: comedi: s626: cleanup comments in s626_initialize() staging: comedi: s626: remove clear of kzalloc'ed data staging: comedi: s626: remove 'WDInterval' from private data staging: comedi: s626: remove 'ChargeEnabled' from private data staging: comedi: s626: remove 'IsBoardRevA' comment staging: comedi: s626: #if 0 out the "SAA7146 BUG WORKAROUND" staging: comedi: s626: remove 'allocatedBuf' from private data staging: comedi: s626: add final attach message ...
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/generic_buffer.c10
-rw-r--r--drivers/staging/iio/Documentation/inkernel.txt6
-rw-r--r--drivers/staging/iio/Kconfig2
-rw-r--r--drivers/staging/iio/TODO2
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16201_ring.c3
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16203_ring.c5
-rw-r--r--drivers/staging/iio/accel/adis16204_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16204_ring.c3
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16209_ring.c3
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c11
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16240_ring.c3
-rw-r--r--drivers/staging/iio/accel/kxsd9.c6
-rw-r--r--drivers/staging/iio/accel/lis3l02dq.h14
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c26
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c31
-rw-r--r--drivers/staging/iio/accel/sca3000.h2
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c14
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c2
-rw-r--r--drivers/staging/iio/adc/Kconfig43
-rw-r--r--drivers/staging/iio/adc/Makefile5
-rw-r--r--drivers/staging/iio/adc/ad7192.c523
-rw-r--r--drivers/staging/iio/adc/ad7298_core.c2
-rw-r--r--drivers/staging/iio/adc/ad7298_ring.c3
-rw-r--r--drivers/staging/iio/adc/ad7476.h66
-rw-r--r--drivers/staging/iio/adc/ad7476_core.c244
-rw-r--r--drivers/staging/iio/adc/ad7476_ring.c64
-rw-r--r--drivers/staging/iio/adc/ad7606.h2
-rw-r--r--drivers/staging/iio/adc/ad7606_core.c6
-rw-r--r--drivers/staging/iio/adc/ad7606_ring.c3
-rw-r--r--drivers/staging/iio/adc/ad7780.c237
-rw-r--r--drivers/staging/iio/adc/ad7793.c688
-rw-r--r--drivers/staging/iio/adc/ad7793.h10
-rw-r--r--drivers/staging/iio/adc/ad7887_core.c2
-rw-r--r--drivers/staging/iio/adc/ad7887_ring.c2
-rw-r--r--drivers/staging/iio/adc/ad799x_ring.c3
-rw-r--r--drivers/staging/iio/adc/lpc32xx_adc.c2
-rw-r--r--drivers/staging/iio/adc/max1363.h2
-rw-r--r--drivers/staging/iio/adc/max1363_core.c32
-rw-r--r--drivers/staging/iio/adc/max1363_ring.c2
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c590
-rw-r--r--drivers/staging/iio/adc/spear_adc.c27
-rw-r--r--drivers/staging/iio/gyro/adis16060_core.c4
-rw-r--r--drivers/staging/iio/gyro/adis16080_core.c2
-rw-r--r--drivers/staging/iio/gyro/adis16130_core.c2
-rw-r--r--drivers/staging/iio/gyro/adis16260_core.c12
-rw-r--r--drivers/staging/iio/gyro/adis16260_ring.c3
-rw-r--r--drivers/staging/iio/gyro/adxrs450_core.c2
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.c2
-rw-r--r--drivers/staging/iio/iio_hwmon.c47
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c24
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h6
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c13
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c4
-rw-r--r--drivers/staging/iio/imu/adis16400.h2
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c18
-rw-r--r--drivers/staging/iio/imu/adis16400_ring.c2
-rw-r--r--drivers/staging/iio/light/isl29018.c17
-rw-r--r--drivers/staging/iio/light/tsl2563.c2
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c2
-rw-r--r--drivers/staging/iio/meter/ade7753.c13
-rw-r--r--drivers/staging/iio/meter/ade7754.c12
-rw-r--r--drivers/staging/iio/meter/ade7758.h2
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c13
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c3
-rw-r--r--drivers/staging/iio/meter/ade7759.c11
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c2
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c2
-rw-r--r--drivers/staging/iio/ring_hw.h2
-rw-r--r--drivers/staging/iio/ring_sw.c7
-rw-r--r--drivers/staging/iio/trigger/Kconfig2
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c109
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.h24
-rw-r--r--drivers/staging/iio/trigger/iio-trig-gpio.c8
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c8
-rw-r--r--drivers/staging/iio/trigger/iio-trig-sysfs.c17
79 files changed, 1260 insertions, 1860 deletions
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index 827e92d..40d0eca 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -104,6 +104,16 @@ void process_scan(char *data,
print2byte(*(uint16_t *)(data + channels[k].location),
&channels[k]);
break;
+ case 4:
+ if (!channels[k].is_signed) {
+ uint32_t val = *(uint32_t *)
+ (data + channels[k].location);
+ printf("%05f ", ((float)val +
+ channels[k].offset)*
+ channels[k].scale);
+
+ }
+ break;
case 8:
if (channels[k].is_signed) {
int64_t val = *(int64_t *)
diff --git a/drivers/staging/iio/Documentation/inkernel.txt b/drivers/staging/iio/Documentation/inkernel.txt
index a05823e..ab528409 100644
--- a/drivers/staging/iio/Documentation/inkernel.txt
+++ b/drivers/staging/iio/Documentation/inkernel.txt
@@ -48,11 +48,11 @@ There are then a number of functions that can be used to get information
about this channel such as it's current reading.
e.g.
-iio_st_read_channel_raw() - get a reading
-iio_st_read_channel_type() - get the type of channel
+iio_read_channel_raw() - get a reading
+iio_get_channel_type() - get the type of channel
There is also provision for retrieving all of the channels associated
with a given consumer. This is useful for generic drivers such as
iio_hwmon where the number and naming of channels is not known by the
-consumer driver. To do this, use iio_st_channel_get_all.
+consumer driver. To do this, use iio_channel_get_all.
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 04cd6ec..ca56c75 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -1,5 +1,5 @@
#
-# Industrial I/O subsytem configuration
+# Industrial I/O subsystem configuration
#
menu "IIO staging drivers"
depends on IIO
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index cf3f948..04c2326 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -69,5 +69,5 @@ Documentation
1) Lots of cleanup and expansion.
2) Some device require individual docs.
-Contact: Jonathan Cameron <jic23@cam.ac.uk>.
+Contact: Jonathan Cameron <jic23@kernel.org>.
Mailing list: linux-iio@vger.kernel.org
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 204106b..8e37d6e 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -390,7 +390,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_chan_spec adis16201_channels[] = {
+static const struct iio_chan_spec adis16201_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -565,7 +565,7 @@ error_ret:
return ret;
}
-static int adis16201_remove(struct spi_device *spi)
+static int __devexit adis16201_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 03fcf6e..97c09f0 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -62,7 +62,6 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16201_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -83,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 22085e9..002fa9d 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -355,7 +355,7 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
}
}
-static struct iio_chan_spec adis16203_channels[] = {
+static const struct iio_chan_spec adis16203_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -500,7 +500,7 @@ error_ret:
return ret;
}
-static int adis16203_remove(struct spi_device *spi)
+static int __devexit adis16203_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index c16b2b7..7507e1a 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -61,7 +61,6 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16203_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -82,9 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring,
- (u8 *)data,
- pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 5f2e5f1..05bdb7c 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -397,7 +397,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_chan_spec adis16204_channels[] = {
+static const struct iio_chan_spec adis16204_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1, /* Note was not previously indexed */
@@ -558,7 +558,7 @@ error_ret:
return ret;
}
-static int adis16204_remove(struct spi_device *spi)
+static int __devexit adis16204_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 1d2b31c..4c976be 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -59,7 +59,6 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16204_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -79,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 4945705..b7333bf 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -390,7 +390,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_chan_spec adis16209_channels[] = {
+static const struct iio_chan_spec adis16209_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -573,7 +573,7 @@ error_ret:
return ret;
}
-static int adis16209_remove(struct spi_device *spi)
+static int __devexit adis16209_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 1a4a55c..f939e29 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -59,7 +59,6 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16209_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -79,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 575f1af..c755089 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -372,8 +372,7 @@ static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj,
loff_t off,
size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
return adis16220_capture_buffer_read(indio_dev, buf,
off, count,
@@ -394,8 +393,7 @@ static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj,
char *buf, loff_t off,
size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
return adis16220_capture_buffer_read(indio_dev, buf,
off, count,
@@ -416,8 +414,7 @@ static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj,
char *buf, loff_t off,
size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
return adis16220_capture_buffer_read(indio_dev, buf,
off, count,
@@ -666,7 +663,7 @@ error_ret:
return ret;
}
-static int adis16220_remove(struct spi_device *spi)
+static int __devexit adis16220_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index b30b787..0fc26a49 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -448,7 +448,7 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_chan_spec adis16240_channels[] = {
+static const struct iio_chan_spec adis16240_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -619,7 +619,7 @@ error_ret:
return ret;
}
-static int adis16240_remove(struct spi_device *spi)
+static int __devexit adis16240_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 360dfed..caff8e2 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -56,7 +56,6 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16240_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -77,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
index 8cf7cd9..fdd5fbd 100644
--- a/drivers/staging/iio/accel/kxsd9.c
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -2,7 +2,7 @@
* kxsd9.c simple support for the Kionix KXSD9 3D
* accelerometer.
*
- * Copyright (c) 2008-2009 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -186,7 +186,7 @@ error_ret:
.address = KXSD9_REG_##axis, \
}
-static struct iio_chan_spec kxsd9_channels[] = {
+static const struct iio_chan_spec kxsd9_channels[] = {
KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z),
{
.type = IIO_VOLTAGE,
@@ -286,6 +286,6 @@ static struct spi_driver kxsd9_driver = {
};
module_spi_driver(kxsd9_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index ae5f225..f9bcd41 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -2,7 +2,7 @@
* LISL02DQ.h -- support STMicroelectronics LISD02DQ
* 3d 2g Linear Accelerometers via SPI
*
- * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
*
* Loosely based upon tle62x0.c
*
@@ -28,7 +28,7 @@
/* Control Register (1 of 2) */
#define LIS3L02DQ_REG_CTRL_1_ADDR 0x20
/* Power ctrl - either bit set corresponds to on*/
-#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0
+#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0
/* Decimation Factor */
#define LIS3L02DQ_DEC_MASK 0x30
@@ -73,14 +73,14 @@
/* Interrupt related stuff */
#define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR 0x23
-/* Switch from or combination fo conditions to and */
+/* Switch from or combination of conditions to and */
#define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND 0x80
/* Latch interrupt request,
* if on ack must be given by reading the ack register */
#define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40
-/* Z Interrupt on High (above threshold)*/
+/* Z Interrupt on High (above threshold) */
#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20
/* Z Interrupt on Low */
#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10
@@ -117,13 +117,13 @@
#define LIS3L02DQ_REG_STATUS_Y_OVERRUN 0x20
#define LIS3L02DQ_REG_STATUS_X_OVERRUN 0x10
/* XYZ new data available - first is all 3 available? */
-#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08
+#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08
#define LIS3L02DQ_REG_STATUS_Z_NEW_DATA 0x04
#define LIS3L02DQ_REG_STATUS_Y_NEW_DATA 0x02
#define LIS3L02DQ_REG_STATUS_X_NEW_DATA 0x01
/* The accelerometer readings - low and high bytes.
-Form of high byte dependent on justification set in ctrl reg */
+ * Form of high byte dependent on justification set in ctrl reg */
#define LIS3L02DQ_REG_OUT_X_L_ADDR 0x28
#define LIS3L02DQ_REG_OUT_X_H_ADDR 0x29
#define LIS3L02DQ_REG_OUT_Y_L_ADDR 0x2A
@@ -150,9 +150,9 @@ Form of high byte dependent on justification set in ctrl reg */
* struct lis3l02dq_state - device instance specific data
* @us: actual spi_device
* @trig: data ready trigger registered with iio
+ * @buf_lock: mutex to protect tx and rx
* @tx: transmit buffer
* @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
**/
struct lis3l02dq_state {
struct spi_device *us;
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 9d26348..21b0469 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -2,7 +2,7 @@
* lis3l02dq.c support STMicroelectronics LISD02DQ
* 3d 2g Linear Accelerometers via SPI
*
- * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -392,7 +392,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
dev_err(&st->us->dev, "problem with setup control register 1");
goto err_ret;
}
- /* Repeat as sometimes doesn't work first time?*/
+ /* Repeat as sometimes doesn't work first time? */
ret = lis3l02dq_spi_write_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_1_ADDR,
val);
@@ -538,7 +538,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
.event_mask = LIS3L02DQ_EVENT_MASK, \
}
-static struct iio_chan_spec lis3l02dq_channels[] = {
+static const struct iio_chan_spec lis3l02dq_channels[] = {
LIS3L02DQ_CHAN(0, IIO_MOD_X),
LIS3L02DQ_CHAN(1, IIO_MOD_Y),
LIS3L02DQ_CHAN(2, IIO_MOD_Z),
@@ -686,7 +686,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
goto error_ret;
}
st = iio_priv(indio_dev);
- /* this is only used tor removal purposes */
+ /* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
st->us = spi;
@@ -780,21 +780,15 @@ err_ret:
}
/* fixme, confirm ordering in this function */
-static int lis3l02dq_remove(struct spi_device *spi)
+static int __devexit lis3l02dq_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct lis3l02dq_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ret = lis3l02dq_disable_all_events(indio_dev);
- if (ret)
- goto err_ret;
-
- ret = lis3l02dq_stop_device(indio_dev);
- if (ret)
- goto err_ret;
+ lis3l02dq_disable_all_events(indio_dev);
+ lis3l02dq_stop_device(indio_dev);
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
free_irq(st->us->irq, indio_dev);
@@ -804,8 +798,8 @@ static int lis3l02dq_remove(struct spi_device *spi)
lis3l02dq_unconfigure_buffer(indio_dev);
iio_device_free(indio_dev);
-err_ret:
- return ret;
+
+ return 0;
}
static struct spi_driver lis3l02dq_driver = {
@@ -818,7 +812,7 @@ static struct spi_driver lis3l02dq_driver = {
};
module_spi_driver(lis3l02dq_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:lis3l02dq");
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index f3da590..fa4190d 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -14,7 +14,7 @@
#include "lis3l02dq.h"
/**
- * combine_8_to_16() utility function to munge to u8s into u16
+ * combine_8_to_16() utility function to munge two u8s into u16
**/
static inline u16 combine_8_to_16(u8 lower, u8 upper)
{
@@ -49,7 +49,7 @@ static const u8 read_all_tx_array[] = {
/**
* lis3l02dq_read_all() Reads all channels currently selected
- * @st: device specific state
+ * @indio_dev: IIO device state
* @rx_array: (dma capable) receive array, must be at least
* 4*number of channels
**/
@@ -137,7 +137,6 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *buffer = indio_dev->buffer;
int len = 0;
char *data;
@@ -155,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= pf->timestamp;
- buffer->access->store_to(buffer, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
@@ -172,22 +171,22 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state)
bool currentlyset;
struct lis3l02dq_state *st = iio_priv(indio_dev);
-/* Get the current event mask register */
+ /* Get the current event mask register */
ret = lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_2_ADDR,
&valold);
if (ret)
goto error_ret;
-/* Find out if data ready is already on */
+ /* Find out if data ready is already on */
currentlyset
= valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
-/* Disable requested */
+ /* Disable requested */
if (!state && currentlyset) {
- /* disable the data ready signal */
+ /* Disable the data ready signal */
valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
- /* The double write is to overcome a hardware bug?*/
+ /* The double write is to overcome a hardware bug? */
ret = lis3l02dq_spi_write_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_2_ADDR,
valold);
@@ -199,10 +198,10 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state)
if (ret)
goto error_ret;
st->trigger_on = false;
-/* Enable requested */
+ /* Enable requested */
} else if (state && !currentlyset) {
- /* if not set, enable requested */
- /* first disable all events */
+ /* If not set, enable requested
+ * first disable all events */
ret = lis3l02dq_disable_all_events(indio_dev);
if (ret < 0)
goto error_ret;
@@ -241,7 +240,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
if (state == false) {
/*
* A possible quirk with the handler is currently worked around
- * by ensuring outstanding read events are cleared.
+ * by ensuring outstanding read events are cleared.
*/
ret = lis3l02dq_read_all(indio_dev, NULL);
}
@@ -252,7 +251,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
}
/**
- * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
+ * lis3l02dq_trig_try_reen() try reenabling irq for data rdy trigger
* @trig: the datardy trigger
*/
static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
@@ -261,8 +260,8 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
struct lis3l02dq_state *st = iio_priv(indio_dev);
int i;
- /* If gpio still high (or high again) */
- /* In theory possible we will need to do this several times */
+ /* If gpio still high (or high again)
+ * In theory possible we will need to do this several times */
for (i = 0; i < 5; i++)
if (gpio_get_value(irq_to_gpio(st->us->irq)))
lis3l02dq_read_all(indio_dev, NULL);
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index 131daac..c1016c5 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -2,7 +2,7 @@
* sca3000.c -- support VTI sca3000 series accelerometers
* via SPI
*
- * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
*
* Partly based upon tle62x0.c
*
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index c218d71..ffd1697 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -5,7 +5,7 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
- * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
*
* See industrialio/accels/sca3000.h for comments.
*/
@@ -450,7 +450,7 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
.event_mask = SCA3000_EVENT_MASK, \
}
-static struct iio_chan_spec sca3000_channels[] = {
+static const struct iio_chan_spec sca3000_channels[] = {
SCA3000_CHAN(0, IIO_MOD_X),
SCA3000_CHAN(1, IIO_MOD_Y),
SCA3000_CHAN(2, IIO_MOD_Z),
@@ -1233,15 +1233,13 @@ error_ret:
return ret;
}
-static int sca3000_remove(struct spi_device *spi)
+static int __devexit sca3000_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
+
/* Must ensure no interrupts can be generated after this!*/
- ret = sca3000_stop_all_interrupts(st);
- if (ret)
- return ret;
+ sca3000_stop_all_interrupts(st);
if (spi->irq)
free_irq(spi->irq, indio_dev);
iio_device_unregister(indio_dev);
@@ -1272,6 +1270,6 @@ static struct spi_driver sca3000_driver = {
};
module_spi_driver(sca3000_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index b7e1a00..cbec2f1 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -5,7 +5,7 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
- * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
*
*/
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 67711b7..a525143 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -68,20 +68,6 @@ config AD799X_RING_BUFFER
Say yes here to include ring buffer support in the AD799X
ADC driver.
-config AD7476
- tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver"
- depends on SPI
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to build support for Analog Devices
- AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495
- SPI analog to digital converters (ADC).
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad7476.
-
config AD7887
tristate "Analog Devices AD7887 ADC driver"
depends on SPI
@@ -96,11 +82,12 @@ config AD7887
module will be called ad7887.
config AD7780
- tristate "Analog Devices AD7780 AD7781 ADC driver"
+ tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI
depends on GPIOLIB
+ select AD_SIGMA_DELTA
help
- Say yes here to build support for Analog Devices
+ Say yes here to build support for Analog Devices AD7170, AD7171,
AD7780 and AD7781 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
@@ -108,13 +95,12 @@ config AD7780
module will be called ad7780.
config AD7793
- tristate "Analog Devices AD7792 AD7793 ADC driver"
+ tristate "Analog Devices AD7793 and similar ADCs driver"
depends on SPI
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
+ select AD_SIGMA_DELTA
help
- Say yes here to build support for Analog Devices
- AD7792 and AD7793 SPI analog to digital converters (ADC).
+ Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
+ AD7794 and AD7795 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
@@ -131,8 +117,7 @@ config AD7816
config AD7192
tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver"
depends on SPI
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
+ select AD_SIGMA_DELTA
help
Say yes here to build support for Analog Devices AD7190,
AD7192 or AD7195 SPI analog to digital converters (ADC).
@@ -200,6 +185,18 @@ config LPC32XX_ADC
activate only one via device tree selection. Provides direct access
via sysfs.
+config MXS_LRADC
+ tristate "Freescale i.MX28 LRADC"
+ depends on ARCH_MXS
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for i.MX28 LRADC convertor
+ built into these chips.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mxs-lradc.
+
config SPEAR_ADC
tristate "ST SPEAr ADC"
depends on PLAT_SPEAR
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 14e98b6..62ee02e 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -17,10 +17,6 @@ ad799x-y := ad799x_core.o
ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
obj-$(CONFIG_AD799X) += ad799x.o
-ad7476-y := ad7476_core.o
-ad7476-$(CONFIG_IIO_BUFFER) += ad7476_ring.o
-obj-$(CONFIG_AD7476) += ad7476.o
-
ad7887-y := ad7887_core.o
ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o
obj-$(CONFIG_AD7887) += ad7887.o
@@ -38,4 +34,5 @@ obj-$(CONFIG_ADT7310) += adt7310.o
obj-$(CONFIG_ADT7410) += adt7410.o
obj-$(CONFIG_AD7280) += ad7280a.o
obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
+obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 19a064d..aeaa61d 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -23,6 +23,7 @@
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/adc/ad_sigma_delta.h>
#include "ad7192.h"
@@ -57,6 +58,7 @@
/* Mode Register Bit Designations (AD7192_REG_MODE) */
#define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */
+#define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */
#define AD7192_MODE_DAT_STA (1 << 20) /* Status Register transmission */
#define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */
#define AD7192_MODE_SINC3 (1 << 15) /* SINC3 Filter Select */
@@ -91,7 +93,8 @@
#define AD7192_CONF_CHOP (1 << 23) /* CHOP enable */
#define AD7192_CONF_REFSEL (1 << 20) /* REFIN1/REFIN2 Reference Select */
-#define AD7192_CONF_CHAN(x) (((x) & 0xFF) << 8) /* Channel select */
+#define AD7192_CONF_CHAN(x) (((1 << (x)) & 0xFF) << 8) /* Channel select */
+#define AD7192_CONF_CHAN_MASK (0xFF << 8) /* Channel select mask */
#define AD7192_CONF_BURN (1 << 7) /* Burnout current enable */
#define AD7192_CONF_REFDET (1 << 6) /* Reference detect enable */
#define AD7192_CONF_BUF (1 << 4) /* Buffered Mode Enable */
@@ -133,13 +136,7 @@
*/
struct ad7192_state {
- struct spi_device *spi;
- struct iio_trigger *trig;
struct regulator *reg;
- struct ad7192_platform_data *pdata;
- wait_queue_head_t wq_data_avail;
- bool done;
- bool irq_dis;
u16 int_vref_mv;
u32 mclk;
u32 f_order;
@@ -148,178 +145,45 @@ struct ad7192_state {
u32 scale_avail[8][2];
u8 gpocon;
u8 devid;
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
- u8 data[4] ____cacheline_aligned;
-};
-
-static int __ad7192_write_reg(struct ad7192_state *st, bool locked,
- bool cs_change, unsigned char reg,
- unsigned size, unsigned val)
-{
- u8 *data = st->data;
- struct spi_transfer t = {
- .tx_buf = data,
- .len = size + 1,
- .cs_change = cs_change,
- };
- struct spi_message m;
-
- data[0] = AD7192_COMM_WRITE | AD7192_COMM_ADDR(reg);
-
- switch (size) {
- case 3:
- data[1] = val >> 16;
- data[2] = val >> 8;
- data[3] = val;
- break;
- case 2:
- data[1] = val >> 8;
- data[2] = val;
- break;
- case 1:
- data[1] = val;
- break;
- default:
- return -EINVAL;
- }
-
- spi_message_init(&m);
- spi_message_add_tail(&t, &m);
- if (locked)
- return spi_sync_locked(st->spi, &m);
- else
- return spi_sync(st->spi, &m);
-}
+ struct ad_sigma_delta sd;
+};
-static int ad7192_write_reg(struct ad7192_state *st,
- unsigned reg, unsigned size, unsigned val)
+static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd)
{
- return __ad7192_write_reg(st, false, false, reg, size, val);
+ return container_of(sd, struct ad7192_state, sd);
}
-static int __ad7192_read_reg(struct ad7192_state *st, bool locked,
- bool cs_change, unsigned char reg,
- int *val, unsigned size)
+static int ad7192_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
{
- u8 *data = st->data;
- int ret;
- struct spi_transfer t[] = {
- {
- .tx_buf = data,
- .len = 1,
- }, {
- .rx_buf = data,
- .len = size,
- .cs_change = cs_change,
- },
- };
- struct spi_message m;
-
- data[0] = AD7192_COMM_READ | AD7192_COMM_ADDR(reg);
-
- spi_message_init(&m);
- spi_message_add_tail(&t[0], &m);
- spi_message_add_tail(&t[1], &m);
-
- if (locked)
- ret = spi_sync_locked(st->spi, &m);
- else
- ret = spi_sync(st->spi, &m);
-
- if (ret < 0)
- return ret;
-
- switch (size) {
- case 3:
- *val = data[0] << 16 | data[1] << 8 | data[2];
- break;
- case 2:
- *val = data[0] << 8 | data[1];
- break;
- case 1:
- *val = data[0];
- break;
- default:
- return -EINVAL;
- }
+ struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd);
- return 0;
-}
+ st->conf &= ~AD7192_CONF_CHAN_MASK;
+ st->conf |= AD7192_CONF_CHAN(channel);
-static int ad7192_read_reg(struct ad7192_state *st,
- unsigned reg, int *val, unsigned size)
-{
- return __ad7192_read_reg(st, 0, 0, reg, val, size);
+ return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf);
}
-static int ad7192_read(struct ad7192_state *st, unsigned ch,
- unsigned len, int *val)
+static int ad7192_set_mode(struct ad_sigma_delta *sd,
+ enum ad_sigma_delta_mode mode)
{
- int ret;
- st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) |
- AD7192_CONF_CHAN(1 << ch);
- st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) |
- AD7192_MODE_SEL(AD7192_MODE_SINGLE);
+ struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd);
- ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf);
+ st->mode &= ~AD7192_MODE_SEL_MASK;
+ st->mode |= AD7192_MODE_SEL(mode);
- spi_bus_lock(st->spi->master);
- st->done = false;
-
- ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode);
- if (ret < 0)
- goto out;
-
- st->irq_dis = false;
- enable_irq(st->spi->irq);
- wait_event_interruptible(st->wq_data_avail, st->done);
-
- ret = __ad7192_read_reg(st, 1, 0, AD7192_REG_DATA, val, len);
-out:
- spi_bus_unlock(st->spi->master);
-
- return ret;
+ return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
}
-static int ad7192_calibrate(struct ad7192_state *st, unsigned mode, unsigned ch)
-{
- int ret;
-
- st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) |
- AD7192_CONF_CHAN(1 << ch);
- st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(mode);
-
- ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf);
-
- spi_bus_lock(st->spi->master);
- st->done = false;
-
- ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3,
- (st->devid != ID_AD7195) ?
- st->mode | AD7192_MODE_CLKDIV :
- st->mode);
- if (ret < 0)
- goto out;
-
- st->irq_dis = false;
- enable_irq(st->spi->irq);
- wait_event_interruptible(st->wq_data_avail, st->done);
-
- st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) |
- AD7192_MODE_SEL(AD7192_MODE_IDLE);
-
- ret = __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode);
-out:
- spi_bus_unlock(st->spi->master);
-
- return ret;
-}
+static const struct ad_sigma_delta_info ad7192_sigma_delta_info = {
+ .set_channel = ad7192_set_channel,
+ .set_mode = ad7192_set_mode,
+ .has_registers = true,
+ .addr_shift = 3,
+ .read_mask = BIT(6),
+};
-static const u8 ad7192_calib_arr[8][2] = {
+static const struct ad_sd_calib_data ad7192_calib_arr[8] = {
{AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN1},
{AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN1},
{AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN2},
@@ -332,45 +196,34 @@ static const u8 ad7192_calib_arr[8][2] = {
static int ad7192_calibrate_all(struct ad7192_state *st)
{
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(ad7192_calib_arr); i++) {
- ret = ad7192_calibrate(st, ad7192_calib_arr[i][0],
- ad7192_calib_arr[i][1]);
- if (ret)
- goto out;
- }
-
- return 0;
-out:
- dev_err(&st->spi->dev, "Calibration failed\n");
- return ret;
+ return ad_sd_calibrate_all(&st->sd, ad7192_calib_arr,
+ ARRAY_SIZE(ad7192_calib_arr));
}
-static int ad7192_setup(struct ad7192_state *st)
+static int ad7192_setup(struct ad7192_state *st,
+ const struct ad7192_platform_data *pdata)
{
- struct iio_dev *indio_dev = spi_get_drvdata(st->spi);
- struct ad7192_platform_data *pdata = st->pdata;
+ struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi);
unsigned long long scale_uv;
int i, ret, id;
u8 ones[6];
/* reset the serial interface */
memset(&ones, 0xFF, 6);
- ret = spi_write(st->spi, &ones, 6);
+ ret = spi_write(st->sd.spi, &ones, 6);
if (ret < 0)
goto out;
msleep(1); /* Wait for at least 500us */
/* write/read test for device presence */
- ret = ad7192_read_reg(st, AD7192_REG_ID, &id, 1);
+ ret = ad_sd_read_reg(&st->sd, AD7192_REG_ID, 1, &id);
if (ret)
goto out;
id &= AD7192_ID_MASK;
if (id != st->devid)
- dev_warn(&st->spi->dev, "device ID query failed (0x%X)\n", id);
+ dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id);
switch (pdata->clock_source_sel) {
case AD7192_CLK_EXT_MCLK1_2:
@@ -423,11 +276,11 @@ static int ad7192_setup(struct ad7192_state *st)
if (pdata->burnout_curr_en)
st->conf |= AD7192_CONF_BURN;
- ret = ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode);
+ ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
if (ret)
goto out;
- ret = ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf);
+ ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf);
if (ret)
goto out;
@@ -448,181 +301,10 @@ static int ad7192_setup(struct ad7192_state *st)
return 0;
out:
- dev_err(&st->spi->dev, "setup failed\n");
+ dev_err(&st->sd.spi->dev, "setup failed\n");
return ret;
}
-static int ad7192_ring_preenable(struct iio_dev *indio_dev)
-{
- struct ad7192_state *st = iio_priv(indio_dev);
- unsigned channel;
- int ret;
-
- if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
- return -EINVAL;
-
- ret = iio_sw_buffer_preenable(indio_dev);
- if (ret < 0)
- return ret;
-
- channel = find_first_bit(indio_dev->active_scan_mask,
- indio_dev->masklength);
-
- st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) |
- AD7192_MODE_SEL(AD7192_MODE_CONT);
- st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) |
- AD7192_CONF_CHAN(1 << indio_dev->channels[channel].address);
-
- ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf);
-
- spi_bus_lock(st->spi->master);
- __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode);
-
- st->irq_dis = false;
- enable_irq(st->spi->irq);
-
- return 0;
-}
-
-static int ad7192_ring_postdisable(struct iio_dev *indio_dev)
-{
- struct ad7192_state *st = iio_priv(indio_dev);
-
- st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) |
- AD7192_MODE_SEL(AD7192_MODE_IDLE);
-
- st->done = false;
- wait_event_interruptible(st->wq_data_avail, st->done);
-
- if (!st->irq_dis)
- disable_irq_nosync(st->spi->irq);
-
- __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode);
-
- return spi_bus_unlock(st->spi->master);
-}
-
-/**
- * ad7192_trigger_handler() bh of trigger launched polling to ring buffer
- **/
-static irqreturn_t ad7192_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
- struct ad7192_state *st = iio_priv(indio_dev);
- s64 dat64[2];
- s32 *dat32 = (s32 *)dat64;
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
- __ad7192_read_reg(st, 1, 1, AD7192_REG_DATA,
- dat32,
- indio_dev->channels[0].scan_type.realbits/8);
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- dat64[1] = pf->timestamp;
-
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
-
- iio_trigger_notify_done(indio_dev->trig);
- st->irq_dis = false;
- enable_irq(st->spi->irq);
-
- return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops ad7192_ring_setup_ops = {
- .preenable = &ad7192_ring_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
- .postdisable = &ad7192_ring_postdisable,
- .validate_scan_mask = &iio_validate_scan_mask_onehot,
-};
-
-static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
- &ad7192_trigger_handler, &ad7192_ring_setup_ops);
-}
-
-static void ad7192_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
-
-/**
- * ad7192_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t ad7192_data_rdy_trig_poll(int irq, void *private)
-{
- struct ad7192_state *st = iio_priv(private);
-
- st->done = true;
- wake_up_interruptible(&st->wq_data_avail);
- disable_irq_nosync(irq);
- st->irq_dis = true;
- iio_trigger_poll(st->trig, iio_get_time_ns());
-
- return IRQ_HANDLED;
-}
-
-static struct iio_trigger_ops ad7192_trigger_ops = {
- .owner = THIS_MODULE,
-};
-
-static int ad7192_probe_trigger(struct iio_dev *indio_dev)
-{
- struct ad7192_state *st = iio_priv(indio_dev);
- int ret;
-
- st->trig = iio_trigger_alloc("%s-dev%d",
- spi_get_device_id(st->spi)->name,
- indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st->trig->ops = &ad7192_trigger_ops;
- ret = request_irq(st->spi->irq,
- ad7192_data_rdy_trig_poll,
- IRQF_TRIGGER_LOW,
- spi_get_device_id(st->spi)->name,
- indio_dev);
- if (ret)
- goto error_free_trig;
-
- disable_irq_nosync(st->spi->irq);
- st->irq_dis = true;
- st->trig->dev.parent = &st->spi->dev;
- st->trig->private_data = indio_dev;
-
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->spi->irq, indio_dev);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-static void ad7192_remove_trigger(struct iio_dev *indio_dev)
-{
- struct ad7192_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->spi->irq, indio_dev);
- iio_trigger_free(st->trig);
-}
-
static ssize_t ad7192_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -664,7 +346,7 @@ static ssize_t ad7192_write_frequency(struct device *dev,
st->mode &= ~AD7192_MODE_RATE(-1);
st->mode |= AD7192_MODE_RATE(div);
- ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode);
+ ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
out:
mutex_unlock(&indio_dev->mlock);
@@ -676,7 +358,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ad7192_read_frequency,
ad7192_write_frequency);
-
static ssize_t ad7192_show_scale_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -748,7 +429,7 @@ static ssize_t ad7192_set(struct device *dev,
else
st->gpocon &= ~AD7192_GPOCON_BPDSW;
- ad7192_write_reg(st, AD7192_REG_GPOCON, 1, st->gpocon);
+ ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon);
break;
case AD7192_REG_MODE:
if (val)
@@ -756,7 +437,7 @@ static ssize_t ad7192_set(struct device *dev,
else
st->mode &= ~AD7192_MODE_ACX;
- ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode);
+ ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
break;
default:
ret = -EINVAL;
@@ -812,27 +493,11 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7192_state *st = iio_priv(indio_dev);
- int ret, smpl = 0;
bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR);
switch (m) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = ad7192_read(st, chan->address,
- chan->scan_type.realbits / 8, &smpl);
- mutex_unlock(&indio_dev->mlock);
-
- if (ret < 0)
- return ret;
-
- *val = (smpl >> chan->scan_type.shift) &
- ((1 << (chan->scan_type.realbits)) - 1);
-
- return IIO_VAL_INT;
-
+ return ad_sigma_delta_single_conversion(indio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -883,16 +548,16 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
if (val2 == st->scale_avail[i][1]) {
+ ret = 0;
tmp = st->conf;
st->conf &= ~AD7192_CONF_GAIN(-1);
st->conf |= AD7192_CONF_GAIN(i);
-
- if (tmp != st->conf) {
- ad7192_write_reg(st, AD7192_REG_CONF,
- 3, st->conf);
- ad7192_calibrate_all(st);
- }
- ret = 0;
+ if (tmp == st->conf)
+ break;
+ ad_sd_write_reg(&st->sd, AD7192_REG_CONF,
+ 3, st->conf);
+ ad7192_calibrate_all(st);
+ break;
}
break;
default:
@@ -904,15 +569,6 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
return ret;
}
-static int ad7192_validate_trigger(struct iio_dev *indio_dev,
- struct iio_trigger *trig)
-{
- if (indio_dev->trig != trig)
- return -EINVAL;
-
- return 0;
-}
-
static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
@@ -925,7 +581,7 @@ static const struct iio_info ad7192_info = {
.write_raw = &ad7192_write_raw,
.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
.attrs = &ad7192_attribute_group,
- .validate_trigger = ad7192_validate_trigger,
+ .validate_trigger = ad_sd_validate_trigger,
.driver_module = THIS_MODULE,
};
@@ -934,60 +590,25 @@ static const struct iio_info ad7195_info = {
.write_raw = &ad7192_write_raw,
.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
.attrs = &ad7195_attribute_group,
- .validate_trigger = ad7192_validate_trigger,
+ .validate_trigger = ad_sd_validate_trigger,
.driver_module = THIS_MODULE,
};
-#define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \
- { .type = IIO_VOLTAGE, \
- .differential = 1, \
- .indexed = 1, \
- .extend_name = _name, \
- .channel = _chan, \
- .channel2 = _chan2, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_OFFSET_SHARED_BIT, \
- .address = _address, \
- .scan_index = _si, \
- .scan_type = IIO_ST('u', 24, 32, 0)}
-
-#define AD7192_CHAN(_chan, _address, _si) \
- { .type = IIO_VOLTAGE, \
- .indexed = 1, \
- .channel = _chan, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_OFFSET_SHARED_BIT, \
- .address = _address, \
- .scan_index = _si, \
- .scan_type = IIO_ST('u', 24, 32, 0)}
-
-#define AD7192_CHAN_TEMP(_chan, _address, _si) \
- { .type = IIO_TEMP, \
- .indexed = 1, \
- .channel = _chan, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = _address, \
- .scan_index = _si, \
- .scan_type = IIO_ST('u', 24, 32, 0)}
-
-static struct iio_chan_spec ad7192_channels[] = {
- AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0),
- AD7192_CHAN_DIFF(3, 4, NULL, AD7192_CH_AIN3P_AIN4M, 1),
- AD7192_CHAN_TEMP(0, AD7192_CH_TEMP, 2),
- AD7192_CHAN_DIFF(2, 2, "shorted", AD7192_CH_AIN2P_AIN2M, 3),
- AD7192_CHAN(1, AD7192_CH_AIN1, 4),
- AD7192_CHAN(2, AD7192_CH_AIN2, 5),
- AD7192_CHAN(3, AD7192_CH_AIN3, 6),
- AD7192_CHAN(4, AD7192_CH_AIN4, 7),
+static const struct iio_chan_spec ad7192_channels[] = {
+ AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0),
+ AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0),
+ AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0),
+ AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0),
+ AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0),
+ AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0),
+ AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0),
+ AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0),
IIO_CHAN_SOFT_TIMESTAMP(8),
};
static int __devinit ad7192_probe(struct spi_device *spi)
{
- struct ad7192_platform_data *pdata = spi->dev.platform_data;
+ const struct ad7192_platform_data *pdata = spi->dev.platform_data;
struct ad7192_state *st;
struct iio_dev *indio_dev;
int ret , voltage_uv = 0;
@@ -1017,8 +638,6 @@ static int __devinit ad7192_probe(struct spi_device *spi)
voltage_uv = regulator_get_voltage(st->reg);
}
- st->pdata = pdata;
-
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
@@ -1027,7 +646,6 @@ static int __devinit ad7192_probe(struct spi_device *spi)
dev_warn(&spi->dev, "reference voltage undefined\n");
spi_set_drvdata(spi, indio_dev);
- st->spi = spi;
st->devid = spi_get_device_id(spi)->driver_data;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
@@ -1039,17 +657,13 @@ static int __devinit ad7192_probe(struct spi_device *spi)
else
indio_dev->info = &ad7192_info;
- init_waitqueue_head(&st->wq_data_avail);
+ ad_sd_init(&st->sd, indio_dev, spi, &ad7192_sigma_delta_info);
- ret = ad7192_register_ring_funcs_and_init(indio_dev);
+ ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
goto error_disable_reg;
- ret = ad7192_probe_trigger(indio_dev);
- if (ret)
- goto error_ring_cleanup;
-
- ret = ad7192_setup(st);
+ ret = ad7192_setup(st, pdata);
if (ret)
goto error_remove_trigger;
@@ -1059,9 +673,7 @@ static int __devinit ad7192_probe(struct spi_device *spi)
return 0;
error_remove_trigger:
- ad7192_remove_trigger(indio_dev);
-error_ring_cleanup:
- ad7192_ring_cleanup(indio_dev);
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
@@ -1074,14 +686,13 @@ error_put_reg:
return ret;
}
-static int ad7192_remove(struct spi_device *spi)
+static int __devexit ad7192_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7192_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7192_remove_trigger(indio_dev);
- ad7192_ring_cleanup(indio_dev);
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 6141f4a..4c75114 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -38,7 +38,7 @@
}, \
}
-static struct iio_chan_spec ad7298_channels[] = {
+static const struct iio_chan_spec ad7298_channels[] = {
{
.type = IIO_TEMP,
.indexed = 1,
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 506016f..c2906a8 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -75,7 +75,6 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7298_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns = 0;
__u16 buf[16];
int b_sent, i;
@@ -94,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
indio_dev->masklength); i++)
buf[i] = be16_to_cpu(st->rx_buf[i]);
- indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)buf);
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h
deleted file mode 100644
index b1dd931..0000000
--- a/drivers/staging/iio/adc/ad7476.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * AD7476/5/7/8 (A) SPI ADC driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-#ifndef IIO_ADC_AD7476_H_
-#define IIO_ADC_AD7476_H_
-
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
-/*
- * TODO: struct ad7476_platform_data needs to go into include/linux/iio
- */
-
-struct ad7476_platform_data {
- u16 vref_mv;
-};
-
-struct ad7476_chip_info {
- u16 int_vref_mv;
- struct iio_chan_spec channel[2];
-};
-
-struct ad7476_state {
- struct spi_device *spi;
- const struct ad7476_chip_info *chip_info;
- struct regulator *reg;
- u16 int_vref_mv;
- struct spi_transfer xfer;
- struct spi_message msg;
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
- unsigned char data[2] ____cacheline_aligned;
-};
-
-enum ad7476_supported_device_ids {
- ID_AD7466,
- ID_AD7467,
- ID_AD7468,
- ID_AD7475,
- ID_AD7476,
- ID_AD7477,
- ID_AD7478,
- ID_AD7495
-};
-
-#ifdef CONFIG_IIO_BUFFER
-int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad7476_ring_cleanup(struct iio_dev *indio_dev);
-#else /* CONFIG_IIO_BUFFER */
-
-static inline int
-ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad7476_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_IIO_BUFFER */
-#endif /* IIO_ADC_AD7476_H_ */
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
deleted file mode 100644
index 4d30a79..0000000
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-
-#include "ad7476.h"
-
-static int ad7476_scan_direct(struct ad7476_state *st)
-{
- int ret;
-
- ret = spi_sync(st->spi, &st->msg);
- if (ret)
- return ret;
-
- return (st->data[0] << 8) | st->data[1];
-}
-
-static int ad7476_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long m)
-{
- int ret;
- struct ad7476_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
-
- switch (m) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = ad7476_scan_direct(st);
- mutex_unlock(&indio_dev->mlock);
-
- if (ret < 0)
- return ret;
- *val = (ret >> st->chip_info->channel[0].scan_type.shift) &
- RES_MASK(st->chip_info->channel[0].scan_type.realbits);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->int_vref_mv * 1000)
- >> st->chip_info->channel[0].scan_type.realbits;
- *val = scale_uv/1000;
- *val2 = (scale_uv%1000)*1000;
- return IIO_VAL_INT_PLUS_MICRO;
- }
- return -EINVAL;
-}
-
-#define AD7476_CHAN(bits) \
- { \
- .type = IIO_VOLTAGE, \
- .indexed = 1, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
- .scan_type = { \
- .sign = 'u', \
- .realbits = bits, \
- .storagebits = 16, \
- .shift = 12 - bits, \
- }, \
-}
-
-static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
- [ID_AD7466] = {
- .channel[0] = AD7476_CHAN(12),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7467] = {
- .channel[0] = AD7476_CHAN(10),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7468] = {
- .channel[0] = AD7476_CHAN(8),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7475] = {
- .channel[0] = AD7476_CHAN(12),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7476] = {
- .channel[0] = AD7476_CHAN(12),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7477] = {
- .channel[0] = AD7476_CHAN(10),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7478] = {
- .channel[0] = AD7476_CHAN(8),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- },
- [ID_AD7495] = {
- .channel[0] = AD7476_CHAN(12),
- .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
- .int_vref_mv = 2500,
- },
-};
-
-static const struct iio_info ad7476_info = {
- .driver_module = THIS_MODULE,
- .read_raw = &ad7476_read_raw,
-};
-
-static int __devinit ad7476_probe(struct spi_device *spi)
-{
- struct ad7476_platform_data *pdata = spi->dev.platform_data;
- struct ad7476_state *st;
- struct iio_dev *indio_dev;
- int ret, voltage_uv = 0;
-
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- goto error_put_reg;
-
- voltage_uv = regulator_get_voltage(st->reg);
- }
- st->chip_info =
- &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
-
- if (st->chip_info->int_vref_mv)
- st->int_vref_mv = st->chip_info->int_vref_mv;
- else if (pdata && pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (voltage_uv)
- st->int_vref_mv = voltage_uv / 1000;
- else
- dev_warn(&spi->dev, "reference voltage unspecified\n");
-
- spi_set_drvdata(spi, indio_dev);
-
- st->spi = spi;
-
- /* Establish that the iio_dev is a child of the spi device */
- indio_dev->dev.parent = &spi->dev;
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = st->chip_info->channel;
- indio_dev->num_channels = 2;
- indio_dev->info = &ad7476_info;
- /* Setup default message */
-
- st->xfer.rx_buf = &st->data;
- st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
-
- spi_message_init(&st->msg);
- spi_message_add_tail(&st->xfer, &st->msg);
-
- ret = ad7476_register_ring_funcs_and_init(indio_dev);
- if (ret)
- goto error_disable_reg;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_ring_unregister;
- return 0;
-
-error_ring_unregister:
- ad7476_ring_cleanup(indio_dev);
-error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
- iio_device_free(indio_dev);
-
-error_ret:
- return ret;
-}
-
-static int ad7476_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct ad7476_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- ad7476_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg)) {
- regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-static const struct spi_device_id ad7476_id[] = {
- {"ad7466", ID_AD7466},
- {"ad7467", ID_AD7467},
- {"ad7468", ID_AD7468},
- {"ad7475", ID_AD7475},
- {"ad7476", ID_AD7476},
- {"ad7476a", ID_AD7476},
- {"ad7477", ID_AD7477},
- {"ad7477a", ID_AD7477},
- {"ad7478", ID_AD7478},
- {"ad7478a", ID_AD7478},
- {"ad7495", ID_AD7495},
- {}
-};
-MODULE_DEVICE_TABLE(spi, ad7476_id);
-
-static struct spi_driver ad7476_driver = {
- .driver = {
- .name = "ad7476",
- .owner = THIS_MODULE,
- },
- .probe = ad7476_probe,
- .remove = __devexit_p(ad7476_remove),
- .id_table = ad7476_id,
-};
-module_spi_driver(ad7476_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
deleted file mode 100644
index d087b21..0000000
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2010-2012 Analog Devices Inc.
- * Copyright (C) 2008 Jonathan Cameron
- *
- * Licensed under the GPL-2 or later.
- *
- * ad7476_ring.c
- */
-
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad7476.h"
-
-static irqreturn_t ad7476_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct ad7476_state *st = iio_priv(indio_dev);
- s64 time_ns;
- __u8 *rxbuf;
- int b_sent;
-
- rxbuf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (rxbuf == NULL)
- goto done;
-
- b_sent = spi_read(st->spi, rxbuf,
- st->chip_info->channel[0].scan_type.storagebits / 8);
- if (b_sent < 0)
- goto done;
-
- time_ns = iio_get_time_ns();
-
- if (indio_dev->scan_timestamp)
- memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
- &time_ns, sizeof(time_ns));
-
- indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns);
-done:
- iio_trigger_notify_done(indio_dev->trig);
- kfree(rxbuf);
-
- return IRQ_HANDLED;
-}
-
-int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, NULL,
- &ad7476_trigger_handler, NULL);
-}
-
-void ad7476_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 10f5989..9221a74 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -51,7 +51,7 @@ struct ad7606_platform_data {
struct ad7606_chip_info {
const char *name;
u16 int_vref_mv;
- struct iio_chan_spec *channels;
+ const struct iio_chan_spec *channels;
unsigned num_channels;
};
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index ccb97fe..bae61cb 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -241,7 +241,7 @@ static const struct attribute_group ad7606_attribute_group_range = {
.scan_type = IIO_ST('s', 16, 16, 0), \
}
-static struct iio_chan_spec ad7606_8_channels[] = {
+static const struct iio_chan_spec ad7606_8_channels[] = {
AD7606_CHANNEL(0),
AD7606_CHANNEL(1),
AD7606_CHANNEL(2),
@@ -253,7 +253,7 @@ static struct iio_chan_spec ad7606_8_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(8),
};
-static struct iio_chan_spec ad7606_6_channels[] = {
+static const struct iio_chan_spec ad7606_6_channels[] = {
AD7606_CHANNEL(0),
AD7606_CHANNEL(1),
AD7606_CHANNEL(2),
@@ -263,7 +263,7 @@ static struct iio_chan_spec ad7606_6_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(6),
};
-static struct iio_chan_spec ad7606_4_channels[] = {
+static const struct iio_chan_spec ad7606_4_channels[] = {
AD7606_CHANNEL(0),
AD7606_CHANNEL(1),
AD7606_CHANNEL(2),
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index f15afe4..ba04d0f 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
poll_work);
struct iio_dev *indio_dev = iio_priv_to_dev(st);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u8 *buf;
int ret;
@@ -84,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
if (indio_dev->scan_timestamp)
*((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
- ring->access->store_to(indio_dev->buffer, buf, time_ns);
+ iio_push_to_buffer(indio_dev->buffer, buf);
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 19ee49c..0a1328b 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -1,5 +1,5 @@
/*
- * AD7780/AD7781 SPI ADC driver
+ * AD7170/AD7171 and AD7780/AD7781 SPI ADC driver
*
* Copyright 2011 Analog Devices Inc.
*
@@ -20,6 +20,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/adc/ad_sigma_delta.h>
#include "ad7780.h"
@@ -33,53 +34,53 @@
#define AD7780_PAT0 (1 << 0)
struct ad7780_chip_info {
- struct iio_chan_spec channel;
+ struct iio_chan_spec channel;
+ unsigned int pattern_mask;
+ unsigned int pattern;
};
struct ad7780_state {
- struct spi_device *spi;
const struct ad7780_chip_info *chip_info;
struct regulator *reg;
- struct ad7780_platform_data *pdata;
- wait_queue_head_t wq_data_avail;
- bool done;
+ int powerdown_gpio;
+ unsigned int gain;
u16 int_vref_mv;
- struct spi_transfer xfer;
- struct spi_message msg;
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
- unsigned int data ____cacheline_aligned;
+
+ struct ad_sigma_delta sd;
};
enum ad7780_supported_device_ids {
+ ID_AD7170,
+ ID_AD7171,
ID_AD7780,
ID_AD7781,
};
-static int ad7780_read(struct ad7780_state *st, int *val)
+static struct ad7780_state *ad_sigma_delta_to_ad7780(struct ad_sigma_delta *sd)
{
- int ret;
-
- spi_bus_lock(st->spi->master);
-
- enable_irq(st->spi->irq);
- st->done = false;
- gpio_set_value(st->pdata->gpio_pdrst, 1);
+ return container_of(sd, struct ad7780_state, sd);
+}
- ret = wait_event_interruptible(st->wq_data_avail, st->done);
- disable_irq_nosync(st->spi->irq);
- if (ret)
- goto out;
+static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta,
+ enum ad_sigma_delta_mode mode)
+{
+ struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta);
+ unsigned val;
+
+ switch (mode) {
+ case AD_SD_MODE_SINGLE:
+ case AD_SD_MODE_CONTINUOUS:
+ val = 1;
+ break;
+ default:
+ val = 0;
+ break;
+ }
- ret = spi_sync_locked(st->spi, &st->msg);
- *val = be32_to_cpu(st->data);
-out:
- gpio_set_value(st->pdata->gpio_pdrst, 0);
- spi_bus_unlock(st->spi->master);
+ if (gpio_is_valid(st->powerdown_gpio))
+ gpio_set_value(st->powerdown_gpio, val);
- return ret;
+ return 0;
}
static int ad7780_read_raw(struct iio_dev *indio_dev,
@@ -89,89 +90,75 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7780_state *st = iio_priv(indio_dev);
- struct iio_chan_spec channel = st->chip_info->channel;
- int ret, smpl = 0;
unsigned long scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- ret = ad7780_read(st, &smpl);
- mutex_unlock(&indio_dev->mlock);
-
- if (ret < 0)
- return ret;
-
- if ((smpl & AD7780_ERR) ||
- !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
- return -EIO;
-
- *val = (smpl >> channel.scan_type.shift) &
- ((1 << (channel.scan_type.realbits)) - 1);
- *val -= (1 << (channel.scan_type.realbits - 1));
-
- if (!(smpl & AD7780_GAIN))
- *val *= 128;
-
- return IIO_VAL_INT;
+ return ad_sigma_delta_single_conversion(indio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->int_vref_mv * 100000)
- >> (channel.scan_type.realbits - 1);
+ scale_uv = (st->int_vref_mv * 100000 * st->gain)
+ >> (chan->scan_type.realbits - 1);
*val = scale_uv / 100000;
*val2 = (scale_uv % 100000) * 10;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_OFFSET:
+ *val -= (1 << (chan->scan_type.realbits - 1));
+ return IIO_VAL_INT;
}
+
return -EINVAL;
}
+static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta,
+ unsigned int raw_sample)
+{
+ struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta);
+ const struct ad7780_chip_info *chip_info = st->chip_info;
+
+ if ((raw_sample & AD7780_ERR) ||
+ ((raw_sample & chip_info->pattern_mask) != chip_info->pattern))
+ return -EIO;
+
+ if (raw_sample & AD7780_GAIN)
+ st->gain = 1;
+ else
+ st->gain = 128;
+
+ return 0;
+}
+
+static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
+ .set_mode = ad7780_set_mode,
+ .postprocess_sample = ad7780_postprocess_sample,
+ .has_registers = false,
+};
+
+#define AD7780_CHANNEL(bits, wordsize) \
+ AD_SD_CHANNEL(1, 0, 0, bits, 32, wordsize - bits)
+
static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
+ [ID_AD7170] = {
+ .channel = AD7780_CHANNEL(12, 24),
+ .pattern = 0x5,
+ .pattern_mask = 0x7,
+ },
+ [ID_AD7171] = {
+ .channel = AD7780_CHANNEL(16, 24),
+ .pattern = 0x5,
+ .pattern_mask = 0x7,
+ },
[ID_AD7780] = {
- .channel = {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_type = {
- .sign = 'u',
- .realbits = 24,
- .storagebits = 32,
- .shift = 8,
- },
- },
+ .channel = AD7780_CHANNEL(24, 32),
+ .pattern = 0x1,
+ .pattern_mask = 0x3,
},
[ID_AD7781] = {
- .channel = {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_type = {
- .sign = 'u',
- .realbits = 20,
- .storagebits = 32,
- .shift = 12,
- },
- },
+ .channel = AD7780_CHANNEL(20, 32),
+ .pattern = 0x1,
+ .pattern_mask = 0x3,
},
};
-/**
- * Interrupt handler
- */
-static irqreturn_t ad7780_interrupt(int irq, void *dev_id)
-{
- struct ad7780_state *st = dev_id;
-
- st->done = true;
- wake_up_interruptible(&st->wq_data_avail);
-
- return IRQ_HANDLED;
-};
-
static const struct iio_info ad7780_info = {
.read_raw = &ad7780_read_raw,
.driver_module = THIS_MODULE,
@@ -184,16 +171,14 @@ static int __devinit ad7780_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
- if (!pdata) {
- dev_dbg(&spi->dev, "no platform data?\n");
- return -ENODEV;
- }
-
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
+ st->gain = 1;
+
+ ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
@@ -207,8 +192,6 @@ static int __devinit ad7780_probe(struct spi_device *spi)
st->chip_info =
&ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data];
- st->pdata = pdata;
-
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
@@ -217,7 +200,6 @@ static int __devinit ad7780_probe(struct spi_device *spi)
dev_warn(&spi->dev, "reference voltage unspecified\n");
spi_set_drvdata(spi, indio_dev);
- st->spi = spi;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
@@ -226,40 +208,34 @@ static int __devinit ad7780_probe(struct spi_device *spi)
indio_dev->num_channels = 1;
indio_dev->info = &ad7780_info;
- init_waitqueue_head(&st->wq_data_avail);
-
- /* Setup default message */
+ if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
- st->xfer.rx_buf = &st->data;
- st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8;
-
- spi_message_init(&st->msg);
- spi_message_add_tail(&st->xfer, &st->msg);
-
- ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
+ ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
"AD7780 /PDRST");
- if (ret) {
- dev_err(&spi->dev, "failed to request GPIO PDRST\n");
- goto error_disable_reg;
+ if (ret) {
+ dev_err(&spi->dev, "failed to request GPIO PDRST\n");
+ goto error_disable_reg;
+ }
+ st->powerdown_gpio = pdata->gpio_pdrst;
+ } else {
+ st->powerdown_gpio = -1;
}
- ret = request_irq(spi->irq, ad7780_interrupt,
- IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st);
+ ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
goto error_free_gpio;
- disable_irq(spi->irq);
-
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_irq;
+ goto error_cleanup_buffer_and_trigger;
return 0;
-error_free_irq:
- free_irq(spi->irq, st);
+error_cleanup_buffer_and_trigger:
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_free_gpio:
- gpio_free(st->pdata->gpio_pdrst);
+ if (pdata && gpio_is_valid(pdata->gpio_pdrst))
+ gpio_free(pdata->gpio_pdrst);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
@@ -272,14 +248,17 @@ error_put_reg:
return ret;
}
-static int ad7780_remove(struct spi_device *spi)
+static int __devexit ad7780_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7780_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- free_irq(spi->irq, st);
- gpio_free(st->pdata->gpio_pdrst);
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
+
+ if (gpio_is_valid(st->powerdown_gpio))
+ gpio_free(st->powerdown_gpio);
+
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
regulator_put(st->reg);
@@ -290,6 +269,8 @@ static int ad7780_remove(struct spi_device *spi)
}
static const struct spi_device_id ad7780_id[] = {
+ {"ad7170", ID_AD7170},
+ {"ad7171", ID_AD7171},
{"ad7780", ID_AD7780},
{"ad7781", ID_AD7781},
{}
@@ -308,5 +289,5 @@ static struct spi_driver ad7780_driver = {
module_spi_driver(ad7780_driver);
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC");
+MODULE_DESCRIPTION("Analog Devices AD7780 and similar ADCs");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index 112e2b7..691a7be 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -1,5 +1,5 @@
/*
- * AD7792/AD7793 SPI ADC driver
+ * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver
*
* Copyright 2011-2012 Analog Devices Inc.
*
@@ -24,6 +24,7 @@
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/adc/ad_sigma_delta.h>
#include "ad7793.h"
@@ -36,198 +37,65 @@
*/
struct ad7793_chip_info {
- struct iio_chan_spec channel[7];
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
};
struct ad7793_state {
- struct spi_device *spi;
- struct iio_trigger *trig;
const struct ad7793_chip_info *chip_info;
struct regulator *reg;
- struct ad7793_platform_data *pdata;
- wait_queue_head_t wq_data_avail;
- bool done;
- bool irq_dis;
u16 int_vref_mv;
u16 mode;
u16 conf;
u32 scale_avail[8][2];
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- */
- u8 data[4] ____cacheline_aligned;
+ struct ad_sigma_delta sd;
+
};
enum ad7793_supported_device_ids {
+ ID_AD7785,
ID_AD7792,
ID_AD7793,
+ ID_AD7794,
+ ID_AD7795,
};
-static int __ad7793_write_reg(struct ad7793_state *st, bool locked,
- bool cs_change, unsigned char reg,
- unsigned size, unsigned val)
-{
- u8 *data = st->data;
- struct spi_transfer t = {
- .tx_buf = data,
- .len = size + 1,
- .cs_change = cs_change,
- };
- struct spi_message m;
-
- data[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(reg);
-
- switch (size) {
- case 3:
- data[1] = val >> 16;
- data[2] = val >> 8;
- data[3] = val;
- break;
- case 2:
- data[1] = val >> 8;
- data[2] = val;
- break;
- case 1:
- data[1] = val;
- break;
- default:
- return -EINVAL;
- }
-
- spi_message_init(&m);
- spi_message_add_tail(&t, &m);
-
- if (locked)
- return spi_sync_locked(st->spi, &m);
- else
- return spi_sync(st->spi, &m);
-}
-
-static int ad7793_write_reg(struct ad7793_state *st,
- unsigned reg, unsigned size, unsigned val)
+static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
{
- return __ad7793_write_reg(st, false, false, reg, size, val);
+ return container_of(sd, struct ad7793_state, sd);
}
-static int __ad7793_read_reg(struct ad7793_state *st, bool locked,
- bool cs_change, unsigned char reg,
- int *val, unsigned size)
+static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
{
- u8 *data = st->data;
- int ret;
- struct spi_transfer t[] = {
- {
- .tx_buf = data,
- .len = 1,
- }, {
- .rx_buf = data,
- .len = size,
- .cs_change = cs_change,
- },
- };
- struct spi_message m;
-
- data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg);
-
- spi_message_init(&m);
- spi_message_add_tail(&t[0], &m);
- spi_message_add_tail(&t[1], &m);
-
- if (locked)
- ret = spi_sync_locked(st->spi, &m);
- else
- ret = spi_sync(st->spi, &m);
-
- if (ret < 0)
- return ret;
-
- switch (size) {
- case 3:
- *val = data[0] << 16 | data[1] << 8 | data[2];
- break;
- case 2:
- *val = data[0] << 8 | data[1];
- break;
- case 1:
- *val = data[0];
- break;
- default:
- return -EINVAL;
- }
+ struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
- return 0;
-}
+ st->conf &= ~AD7793_CONF_CHAN_MASK;
+ st->conf |= AD7793_CONF_CHAN(channel);
-static int ad7793_read_reg(struct ad7793_state *st,
- unsigned reg, int *val, unsigned size)
-{
- return __ad7793_read_reg(st, 0, 0, reg, val, size);
+ return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf);
}
-static int ad7793_read(struct ad7793_state *st, unsigned ch,
- unsigned len, int *val)
+static int ad7793_set_mode(struct ad_sigma_delta *sd,
+ enum ad_sigma_delta_mode mode)
{
- int ret;
- st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch);
- st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) |
- AD7793_MODE_SEL(AD7793_MODE_SINGLE);
-
- ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf);
-
- spi_bus_lock(st->spi->master);
- st->done = false;
-
- ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE,
- sizeof(st->mode), st->mode);
- if (ret < 0)
- goto out;
+ struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
- st->irq_dis = false;
- enable_irq(st->spi->irq);
- wait_event_interruptible(st->wq_data_avail, st->done);
+ st->mode &= ~AD7793_MODE_SEL_MASK;
+ st->mode |= AD7793_MODE_SEL(mode);
- ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len);
-out:
- spi_bus_unlock(st->spi->master);
-
- return ret;
+ return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode);
}
-static int ad7793_calibrate(struct ad7793_state *st, unsigned mode, unsigned ch)
-{
- int ret;
-
- st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch);
- st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(mode);
-
- ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf);
-
- spi_bus_lock(st->spi->master);
- st->done = false;
-
- ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE,
- sizeof(st->mode), st->mode);
- if (ret < 0)
- goto out;
-
- st->irq_dis = false;
- enable_irq(st->spi->irq);
- wait_event_interruptible(st->wq_data_avail, st->done);
-
- st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) |
- AD7793_MODE_SEL(AD7793_MODE_IDLE);
-
- ret = __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE,
- sizeof(st->mode), st->mode);
-out:
- spi_bus_unlock(st->spi->master);
-
- return ret;
-}
+static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
+ .set_channel = ad7793_set_channel,
+ .set_mode = ad7793_set_mode,
+ .has_registers = true,
+ .addr_shift = 3,
+ .read_mask = BIT(6),
+};
-static const u8 ad7793_calib_arr[6][2] = {
+static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M},
{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M},
{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M},
@@ -238,59 +106,49 @@ static const u8 ad7793_calib_arr[6][2] = {
static int ad7793_calibrate_all(struct ad7793_state *st)
{
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(ad7793_calib_arr); i++) {
- ret = ad7793_calibrate(st, ad7793_calib_arr[i][0],
- ad7793_calib_arr[i][1]);
- if (ret)
- goto out;
- }
-
- return 0;
-out:
- dev_err(&st->spi->dev, "Calibration failed\n");
- return ret;
+ return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr,
+ ARRAY_SIZE(ad7793_calib_arr));
}
-static int ad7793_setup(struct ad7793_state *st)
+static int ad7793_setup(struct iio_dev *indio_dev,
+ const struct ad7793_platform_data *pdata)
{
+ struct ad7793_state *st = iio_priv(indio_dev);
int i, ret = -1;
unsigned long long scale_uv;
u32 id;
/* reset the serial interface */
- ret = spi_write(st->spi, (u8 *)&ret, sizeof(ret));
+ ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
if (ret < 0)
goto out;
msleep(1); /* Wait for at least 500us */
/* write/read test for device presence */
- ret = ad7793_read_reg(st, AD7793_REG_ID, &id, 1);
+ ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
if (ret)
goto out;
id &= AD7793_ID_MASK;
- if (!((id == AD7792_ID) || (id == AD7793_ID))) {
- dev_err(&st->spi->dev, "device ID query failed\n");
+ if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) {
+ dev_err(&st->sd.spi->dev, "device ID query failed\n");
goto out;
}
- st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) |
- AD7793_MODE_SEL(AD7793_MODE_IDLE);
- st->conf = st->pdata->conf & ~AD7793_CONF_CHAN(-1);
+ st->mode = pdata->mode;
+ st->conf = pdata->conf;
- ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode);
+ ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
if (ret)
goto out;
- ret = ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf);
+ ret = ad7793_set_channel(&st->sd, 0);
if (ret)
goto out;
- ret = ad7793_write_reg(st, AD7793_REG_IO,
- sizeof(st->pdata->io), st->pdata->io);
+ ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO,
+ sizeof(pdata->io), pdata->io);
if (ret)
goto out;
@@ -301,7 +159,7 @@ static int ad7793_setup(struct ad7793_state *st)
/* Populate available ADC input ranges */
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
scale_uv = ((u64)st->int_vref_mv * 100000000)
- >> (st->chip_info->channel[0].scan_type.realbits -
+ >> (st->chip_info->channels[0].scan_type.realbits -
(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
scale_uv >>= i;
@@ -311,184 +169,10 @@ static int ad7793_setup(struct ad7793_state *st)
return 0;
out:
- dev_err(&st->spi->dev, "setup failed\n");
+ dev_err(&st->sd.spi->dev, "setup failed\n");
return ret;
}
-static int ad7793_ring_preenable(struct iio_dev *indio_dev)
-{
- struct ad7793_state *st = iio_priv(indio_dev);
- unsigned channel;
- int ret;
-
- if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
- return -EINVAL;
- ret = iio_sw_buffer_preenable(indio_dev);
- if (ret < 0)
- return ret;
-
- channel = find_first_bit(indio_dev->active_scan_mask,
- indio_dev->masklength);
-
- st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) |
- AD7793_MODE_SEL(AD7793_MODE_CONT);
- st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) |
- AD7793_CONF_CHAN(indio_dev->channels[channel].address);
-
- ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf);
-
- spi_bus_lock(st->spi->master);
- __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE,
- sizeof(st->mode), st->mode);
-
- st->irq_dis = false;
- enable_irq(st->spi->irq);
-
- return 0;
-}
-
-static int ad7793_ring_postdisable(struct iio_dev *indio_dev)
-{
- struct ad7793_state *st = iio_priv(indio_dev);
-
- st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) |
- AD7793_MODE_SEL(AD7793_MODE_IDLE);
-
- st->done = false;
- wait_event_interruptible(st->wq_data_avail, st->done);
-
- if (!st->irq_dis)
- disable_irq_nosync(st->spi->irq);
-
- __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE,
- sizeof(st->mode), st->mode);
-
- return spi_bus_unlock(st->spi->master);
-}
-
-/**
- * ad7793_trigger_handler() bh of trigger launched polling to ring buffer
- **/
-
-static irqreturn_t ad7793_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
- struct ad7793_state *st = iio_priv(indio_dev);
- s64 dat64[2];
- s32 *dat32 = (s32 *)dat64;
-
- if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
- __ad7793_read_reg(st, 1, 1, AD7793_REG_DATA,
- dat32,
- indio_dev->channels[0].scan_type.realbits/8);
-
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- dat64[1] = pf->timestamp;
-
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
-
- iio_trigger_notify_done(indio_dev->trig);
- st->irq_dis = false;
- enable_irq(st->spi->irq);
-
- return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops ad7793_ring_setup_ops = {
- .preenable = &ad7793_ring_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
- .postdisable = &ad7793_ring_postdisable,
- .validate_scan_mask = &iio_validate_scan_mask_onehot,
-};
-
-static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
- &ad7793_trigger_handler, &ad7793_ring_setup_ops);
-}
-
-static void ad7793_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
-
-/**
- * ad7793_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t ad7793_data_rdy_trig_poll(int irq, void *private)
-{
- struct ad7793_state *st = iio_priv(private);
-
- st->done = true;
- wake_up_interruptible(&st->wq_data_avail);
- disable_irq_nosync(irq);
- st->irq_dis = true;
- iio_trigger_poll(st->trig, iio_get_time_ns());
-
- return IRQ_HANDLED;
-}
-
-static struct iio_trigger_ops ad7793_trigger_ops = {
- .owner = THIS_MODULE,
-};
-
-static int ad7793_probe_trigger(struct iio_dev *indio_dev)
-{
- struct ad7793_state *st = iio_priv(indio_dev);
- int ret;
-
- st->trig = iio_trigger_alloc("%s-dev%d",
- spi_get_device_id(st->spi)->name,
- indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st->trig->ops = &ad7793_trigger_ops;
-
- ret = request_irq(st->spi->irq,
- ad7793_data_rdy_trig_poll,
- IRQF_TRIGGER_LOW,
- spi_get_device_id(st->spi)->name,
- indio_dev);
- if (ret)
- goto error_free_trig;
-
- disable_irq_nosync(st->spi->irq);
- st->irq_dis = true;
- st->trig->dev.parent = &st->spi->dev;
- st->trig->private_data = indio_dev;
-
- ret = iio_trigger_register(st->trig);
-
- /* select default trigger */
- indio_dev->trig = st->trig;
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(st->spi->irq, indio_dev);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-static void ad7793_remove_trigger(struct iio_dev *indio_dev)
-{
- struct ad7793_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->spi->irq, indio_dev);
- iio_trigger_free(st->trig);
-}
-
static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19,
17, 16, 12, 10, 8, 6, 4};
@@ -531,7 +215,7 @@ static ssize_t ad7793_write_frequency(struct device *dev,
mutex_lock(&indio_dev->mlock);
st->mode &= ~AD7793_MODE_RATE(-1);
st->mode |= AD7793_MODE_RATE(i);
- ad7793_write_reg(st, AD7793_REG_MODE,
+ ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
sizeof(st->mode), st->mode);
mutex_unlock(&indio_dev->mlock);
ret = 0;
@@ -585,26 +269,16 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7793_state *st = iio_priv(indio_dev);
- int ret, smpl = 0;
+ int ret;
unsigned long long scale_uv;
bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR);
switch (m) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = ad7793_read(st, chan->address,
- chan->scan_type.realbits / 8, &smpl);
- mutex_unlock(&indio_dev->mlock);
-
+ ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
if (ret < 0)
return ret;
- *val = (smpl >> chan->scan_type.shift) &
- ((1 << (chan->scan_type.realbits)) - 1);
-
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
@@ -675,17 +349,18 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
if (val2 == st->scale_avail[i][1]) {
+ ret = 0;
tmp = st->conf;
st->conf &= ~AD7793_CONF_GAIN(-1);
st->conf |= AD7793_CONF_GAIN(i);
- if (tmp != st->conf) {
- ad7793_write_reg(st, AD7793_REG_CONF,
- sizeof(st->conf),
- st->conf);
- ad7793_calibrate_all(st);
- }
- ret = 0;
+ if (tmp == st->conf)
+ break;
+
+ ad_sd_write_reg(&st->sd, AD7793_REG_CONF,
+ sizeof(st->conf), st->conf);
+ ad7793_calibrate_all(st);
+ break;
}
break;
default:
@@ -696,15 +371,6 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
return ret;
}
-static int ad7793_validate_trigger(struct iio_dev *indio_dev,
- struct iio_trigger *trig)
-{
- if (indio_dev->trig != trig)
- return -EINVAL;
-
- return 0;
-}
-
static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
@@ -717,172 +383,67 @@ static const struct iio_info ad7793_info = {
.write_raw = &ad7793_write_raw,
.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
.attrs = &ad7793_attribute_group,
- .validate_trigger = ad7793_validate_trigger,
+ .validate_trigger = ad_sd_validate_trigger,
.driver_module = THIS_MODULE,
};
+#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
+const struct iio_chan_spec _name##_channels[] = { \
+ AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
+ AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
+ AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
+ AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
+ AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
+ AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
+ IIO_CHAN_SOFT_TIMESTAMP(6), \
+}
+
+#define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
+const struct iio_chan_spec _name##_channels[] = { \
+ AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
+ AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
+ AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
+ AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
+ AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
+ IIO_CHAN_SOFT_TIMESTAMP(9), \
+}
+
+static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
+static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
+static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
+static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
+static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
+
static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
- [ID_AD7793] = {
- .channel[0] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 0,
- .channel2 = 0,
- .address = AD7793_CH_AIN1P_AIN1M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 0,
- .scan_type = IIO_ST('u', 24, 32, 0)
- },
- .channel[1] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 1,
- .channel2 = 1,
- .address = AD7793_CH_AIN2P_AIN2M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 1,
- .scan_type = IIO_ST('u', 24, 32, 0)
- },
- .channel[2] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 2,
- .channel2 = 2,
- .address = AD7793_CH_AIN3P_AIN3M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 2,
- .scan_type = IIO_ST('u', 24, 32, 0)
- },
- .channel[3] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .extend_name = "shorted",
- .indexed = 1,
- .channel = 2,
- .channel2 = 2,
- .address = AD7793_CH_AIN1M_AIN1M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 3,
- .scan_type = IIO_ST('u', 24, 32, 0)
- },
- .channel[4] = {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .address = AD7793_CH_TEMP,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .scan_index = 4,
- .scan_type = IIO_ST('u', 24, 32, 0),
- },
- .channel[5] = {
- .type = IIO_VOLTAGE,
- .extend_name = "supply",
- .indexed = 1,
- .channel = 4,
- .address = AD7793_CH_AVDD_MONITOR,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 5,
- .scan_type = IIO_ST('u', 24, 32, 0),
- },
- .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6),
+ [ID_AD7785] = {
+ .channels = ad7785_channels,
+ .num_channels = ARRAY_SIZE(ad7785_channels),
},
[ID_AD7792] = {
- .channel[0] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 0,
- .channel2 = 0,
- .address = AD7793_CH_AIN1P_AIN1M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 0,
- .scan_type = IIO_ST('u', 16, 32, 0)
- },
- .channel[1] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 1,
- .channel2 = 1,
- .address = AD7793_CH_AIN2P_AIN2M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 1,
- .scan_type = IIO_ST('u', 16, 32, 0)
- },
- .channel[2] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .indexed = 1,
- .channel = 2,
- .channel2 = 2,
- .address = AD7793_CH_AIN3P_AIN3M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 2,
- .scan_type = IIO_ST('u', 16, 32, 0)
- },
- .channel[3] = {
- .type = IIO_VOLTAGE,
- .differential = 1,
- .extend_name = "shorted",
- .indexed = 1,
- .channel = 2,
- .channel2 = 2,
- .address = AD7793_CH_AIN1M_AIN1M,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 3,
- .scan_type = IIO_ST('u', 16, 32, 0)
- },
- .channel[4] = {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .address = AD7793_CH_TEMP,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .scan_index = 4,
- .scan_type = IIO_ST('u', 16, 32, 0),
- },
- .channel[5] = {
- .type = IIO_VOLTAGE,
- .extend_name = "supply",
- .indexed = 1,
- .channel = 4,
- .address = AD7793_CH_AVDD_MONITOR,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT,
- .scan_index = 5,
- .scan_type = IIO_ST('u', 16, 32, 0),
- },
- .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6),
+ .channels = ad7792_channels,
+ .num_channels = ARRAY_SIZE(ad7792_channels),
+ },
+ [ID_AD7793] = {
+ .channels = ad7793_channels,
+ .num_channels = ARRAY_SIZE(ad7793_channels),
+ },
+ [ID_AD7794] = {
+ .channels = ad7794_channels,
+ .num_channels = ARRAY_SIZE(ad7794_channels),
+ },
+ [ID_AD7795] = {
+ .channels = ad7795_channels,
+ .num_channels = ARRAY_SIZE(ad7795_channels),
},
};
static int __devinit ad7793_probe(struct spi_device *spi)
{
- struct ad7793_platform_data *pdata = spi->dev.platform_data;
+ const struct ad7793_platform_data *pdata = spi->dev.platform_data;
struct ad7793_state *st;
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
@@ -903,6 +464,8 @@ static int __devinit ad7793_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
+ ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
+
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
@@ -915,8 +478,6 @@ static int __devinit ad7793_probe(struct spi_device *spi)
st->chip_info =
&ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
- st->pdata = pdata;
-
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
@@ -925,26 +486,19 @@ static int __devinit ad7793_probe(struct spi_device *spi)
st->int_vref_mv = 1170; /* Build-in ref */
spi_set_drvdata(spi, indio_dev);
- st->spi = spi;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = st->chip_info->channel;
- indio_dev->num_channels = 7;
+ indio_dev->channels = st->chip_info->channels;
+ indio_dev->num_channels = st->chip_info->num_channels;
indio_dev->info = &ad7793_info;
- init_waitqueue_head(&st->wq_data_avail);
-
- ret = ad7793_register_ring_funcs_and_init(indio_dev);
+ ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
goto error_disable_reg;
- ret = ad7793_probe_trigger(indio_dev);
- if (ret)
- goto error_unreg_ring;
-
- ret = ad7793_setup(st);
+ ret = ad7793_setup(indio_dev, pdata);
if (ret)
goto error_remove_trigger;
@@ -955,9 +509,7 @@ static int __devinit ad7793_probe(struct spi_device *spi)
return 0;
error_remove_trigger:
- ad7793_remove_trigger(indio_dev);
-error_unreg_ring:
- ad7793_ring_cleanup(indio_dev);
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
@@ -970,14 +522,13 @@ error_put_reg:
return ret;
}
-static int ad7793_remove(struct spi_device *spi)
+static int __devexit ad7793_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7793_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7793_remove_trigger(indio_dev);
- ad7793_ring_cleanup(indio_dev);
+ ad_sd_cleanup_buffer_and_trigger(indio_dev);
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
@@ -990,8 +541,11 @@ static int ad7793_remove(struct spi_device *spi)
}
static const struct spi_device_id ad7793_id[] = {
+ {"ad7785", ID_AD7785},
{"ad7792", ID_AD7792},
{"ad7793", ID_AD7793},
+ {"ad7794", ID_AD7794},
+ {"ad7795", ID_AD7795},
{}
};
MODULE_DEVICE_TABLE(spi, ad7793_id);
@@ -1008,5 +562,5 @@ static struct spi_driver ad7793_driver = {
module_spi_driver(ad7793_driver);
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC");
+MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h
index 64f7d41..8fdd450a 100644
--- a/drivers/staging/iio/adc/ad7793.h
+++ b/drivers/staging/iio/adc/ad7793.h
@@ -41,6 +41,7 @@
/* Mode Register Bit Designations (AD7793_REG_MODE) */
#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */
+#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */
#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */
#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */
@@ -69,7 +70,8 @@
#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */
#define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */
#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */
-#define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */
+#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */
+#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */
#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */
#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */
@@ -78,9 +80,15 @@
#define AD7793_CH_TEMP 6 /* Temp Sensor */
#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */
+#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */
+#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */
+#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */
+#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */
+
/* ID Register Bit Designations (AD7793_REG_ID) */
#define AD7792_ID 0xA
#define AD7793_ID 0xB
+#define AD7795_ID 0xF
#define AD7793_ID_MASK 0xF
/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 397b849..5517905 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -219,7 +219,7 @@ error_put_reg:
return ret;
}
-static int ad7887_remove(struct spi_device *spi)
+static int __devexit ad7887_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7887_state *st = iio_priv(indio_dev);
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index c76fdb5..b39923b 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -95,7 +95,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
- indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns);
+ iio_push_to_buffer(indio_dev->buffer, buf);
done:
kfree(buf);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 858a685..86026d9 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -35,7 +35,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad799x_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u8 *rxbuf;
int b_sent;
@@ -78,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
- ring->access->store_to(indio_dev->buffer, rxbuf, time_ns);
+ iio_push_to_buffer(indio_dev->buffer, rxbuf);
done:
kfree(rxbuf);
out:
diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c
index 348d051..7e9bd00 100644
--- a/drivers/staging/iio/adc/lpc32xx_adc.c
+++ b/drivers/staging/iio/adc/lpc32xx_adc.c
@@ -108,7 +108,7 @@ static const struct iio_info lpc32xx_adc_iio_info = {
.scan_index = _index, \
}
-static struct iio_chan_spec lpc32xx_adc_iio_channels[] = {
+static const struct iio_chan_spec lpc32xx_adc_iio_channels[] = {
LPC32XX_ADC_CHANNEL(0),
LPC32XX_ADC_CHANNEL(1),
LPC32XX_ADC_CHANNEL(2),
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 2cd0112..c746918 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -100,7 +100,7 @@ enum max1363_modes {
*/
struct max1363_chip_info {
const struct iio_info *info;
- struct iio_chan_spec *channels;
+ const struct iio_chan_spec *channels;
int num_channels;
const enum max1363_modes *mode_list;
enum max1363_modes default_mode;
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 6799ce2..d7b4ffc 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -335,12 +335,12 @@ static const enum max1363_modes max1363_mode_list[] = {
IIO_CHAN_SOFT_TIMESTAMP(8) \
}
-static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0);
-static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0);
-static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0);
-static struct iio_chan_spec max1361_channels[] =
+static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0);
+static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0);
+static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0);
+static const struct iio_chan_spec max1361_channels[] =
MAX1363_4X_CHANS(10, MAX1363_EV_M);
-static struct iio_chan_spec max1363_channels[] =
+static const struct iio_chan_spec max1363_channels[] =
MAX1363_4X_CHANS(12, MAX1363_EV_M);
/* Applies to max1236, max1237 */
@@ -392,9 +392,9 @@ static const enum max1363_modes max1238_mode_list[] = {
MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \
IIO_CHAN_SOFT_TIMESTAMP(24) \
}
-static struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
-static struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
-static struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
+static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
+static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
+static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
static const enum max1363_modes max11607_mode_list[] = {
_s0, _s1, _s2, _s3,
@@ -433,9 +433,9 @@ static const enum max1363_modes max11608_mode_list[] = {
MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \
IIO_CHAN_SOFT_TIMESTAMP(16) \
}
-static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
-static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
-static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
+static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
+static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
+static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
static const enum max1363_modes max11644_mode_list[] = {
_s0, _s1, s0to1, d0m1, d1m0,
@@ -449,8 +449,8 @@ static const enum max1363_modes max11644_mode_list[] = {
IIO_CHAN_SOFT_TIMESTAMP(4) \
}
-static struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
-static struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
+static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
+static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
enum { max1361,
max1362,
@@ -1367,7 +1367,7 @@ error_out:
return ret;
}
-static int max1363_remove(struct i2c_client *client)
+static int __devexit max1363_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct max1363_state *st = iio_priv(indio_dev);
@@ -1434,11 +1434,11 @@ static struct i2c_driver max1363_driver = {
.name = "max1363",
},
.probe = max1363_probe,
- .remove = max1363_remove,
+ .remove = __devexit_p(max1363_remove),
.id_table = max1363_id,
};
module_i2c_driver(max1363_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Maxim 1363 ADC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 774ae1b..5f74f3b 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -80,7 +80,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
- iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns);
+ iio_push_to_buffer(indio_dev->buffer, rxbuf);
done_free:
kfree(rxbuf);
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
new file mode 100644
index 0000000..ca7c1fa
--- /dev/null
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -0,0 +1,590 @@
+/*
+ * Freescale i.MX28 LRADC driver
+ *
+ * Copyright (c) 2012 DENX Software Engineering, GmbH.
+ * Marek Vasut <marex@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/stmp_device.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define DRIVER_NAME "mxs-lradc"
+
+#define LRADC_MAX_DELAY_CHANS 4
+#define LRADC_MAX_MAPPED_CHANS 8
+#define LRADC_MAX_TOTAL_CHANS 16
+
+#define LRADC_DELAY_TIMER_HZ 2000
+
+/*
+ * Make this runtime configurable if necessary. Currently, if the buffered mode
+ * is enabled, the LRADC takes LRADC_DELAY_TIMER_LOOP samples of data before
+ * triggering IRQ. The sampling happens every (LRADC_DELAY_TIMER_PER / 2000)
+ * seconds. The result is that the samples arrive every 500mS.
+ */
+#define LRADC_DELAY_TIMER_PER 200
+#define LRADC_DELAY_TIMER_LOOP 5
+
+static const char * const mxs_lradc_irq_name[] = {
+ "mxs-lradc-touchscreen",
+ "mxs-lradc-thresh0",
+ "mxs-lradc-thresh1",
+ "mxs-lradc-channel0",
+ "mxs-lradc-channel1",
+ "mxs-lradc-channel2",
+ "mxs-lradc-channel3",
+ "mxs-lradc-channel4",
+ "mxs-lradc-channel5",
+ "mxs-lradc-channel6",
+ "mxs-lradc-channel7",
+ "mxs-lradc-button0",
+ "mxs-lradc-button1",
+};
+
+struct mxs_lradc_chan {
+ uint8_t slot;
+ uint8_t flags;
+};
+
+struct mxs_lradc {
+ struct device *dev;
+ void __iomem *base;
+ int irq[13];
+
+ uint32_t *buffer;
+ struct iio_trigger *trig;
+
+ struct mutex lock;
+
+ uint8_t enable;
+
+ struct completion completion;
+};
+
+#define LRADC_CTRL0 0x00
+#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23)
+#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22)
+
+#define LRADC_CTRL1 0x10
+#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
+#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff
+#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
+#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16)
+
+#define LRADC_CTRL2 0x20
+#define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15)
+
+#define LRADC_CH(n) (0x50 + (0x10 * (n)))
+#define LRADC_CH_ACCUMULATE (1 << 29)
+#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
+#define LRADC_CH_NUM_SAMPLES_OFFSET 24
+#define LRADC_CH_VALUE_MASK 0x3ffff
+#define LRADC_CH_VALUE_OFFSET 0
+
+#define LRADC_DELAY(n) (0xd0 + (0x10 * (n)))
+#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24)
+#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24
+#define LRADC_DELAY_KICK (1 << 20)
+#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16)
+#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16
+#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11)
+#define LRADC_DELAY_LOOP_COUNT_OFFSET 11
+#define LRADC_DELAY_DELAY_MASK 0x7ff
+#define LRADC_DELAY_DELAY_OFFSET 0
+
+#define LRADC_CTRL4 0x140
+#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
+#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4)
+
+/*
+ * Raw I/O operations
+ */
+static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long m)
+{
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
+ int ret;
+
+ if (m != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ /* Check for invalid channel */
+ if (chan->channel > LRADC_MAX_TOTAL_CHANS)
+ return -EINVAL;
+
+ /*
+ * See if there is no buffered operation in progess. If there is, simply
+ * bail out. This can be improved to support both buffered and raw IO at
+ * the same time, yet the code becomes horribly complicated. Therefore I
+ * applied KISS principle here.
+ */
+ ret = mutex_trylock(&lradc->lock);
+ if (!ret)
+ return -EBUSY;
+
+ INIT_COMPLETION(lradc->completion);
+
+ /*
+ * No buffered operation in progress, map the channel and trigger it.
+ * Virtual channel 0 is always used here as the others are always not
+ * used if doing raw sampling.
+ */
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+
+ writel(chan->channel, lradc->base + LRADC_CTRL4);
+ writel(0, lradc->base + LRADC_CH(0));
+
+ /* Enable the IRQ and start sampling the channel. */
+ writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+ writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ /* Wait for completion on the channel, 1 second max. */
+ ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
+ if (!ret)
+ ret = -ETIMEDOUT;
+ if (ret < 0)
+ goto err;
+
+ /* Read the data. */
+ *val = readl(lradc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK;
+ ret = IIO_VAL_INT;
+
+err:
+ writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ mutex_unlock(&lradc->lock);
+
+ return ret;
+}
+
+static const struct iio_info mxs_lradc_iio_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = mxs_lradc_read_raw,
+};
+
+/*
+ * IRQ Handling
+ */
+static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
+{
+ struct iio_dev *iio = data;
+ struct mxs_lradc *lradc = iio_priv(iio);
+ unsigned long reg = readl(lradc->base + LRADC_CTRL1);
+
+ if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
+ return IRQ_NONE;
+
+ /*
+ * Touchscreen IRQ handling code shall probably have priority
+ * and therefore shall be placed here.
+ */
+
+ if (iio_buffer_enabled(iio))
+ iio_trigger_poll(iio->trig, iio_get_time_ns());
+ else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
+ complete(&lradc->completion);
+
+ writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Trigger handling
+ */
+static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *iio = pf->indio_dev;
+ struct mxs_lradc *lradc = iio_priv(iio);
+ struct iio_buffer *buffer = iio->buffer;
+ const uint32_t chan_value = LRADC_CH_ACCUMULATE |
+ ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
+ int i, j = 0;
+
+ for_each_set_bit(i, iio->active_scan_mask, iio->masklength) {
+ lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
+ writel(chan_value, lradc->base + LRADC_CH(j));
+ lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
+ lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
+ j++;
+ }
+
+ if (iio->scan_timestamp) {
+ s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
+ ALIGN(j, sizeof(s64)));
+ *timestamp = pf->timestamp;
+ }
+
+ iio_push_to_buffer(buffer, (u8 *)lradc->buffer);
+
+ iio_trigger_notify_done(iio->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *iio = trig->private_data;
+ struct mxs_lradc *lradc = iio_priv(iio);
+ const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
+
+ writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st);
+
+ return 0;
+}
+
+static const struct iio_trigger_ops mxs_lradc_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = &mxs_lradc_configure_trigger,
+};
+
+static int mxs_lradc_trigger_init(struct iio_dev *iio)
+{
+ int ret;
+ struct iio_trigger *trig;
+
+ trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id);
+ if (trig == NULL)
+ return -ENOMEM;
+
+ trig->dev.parent = iio->dev.parent;
+ trig->private_data = iio;
+ trig->ops = &mxs_lradc_trigger_ops;
+
+ ret = iio_trigger_register(trig);
+ if (ret) {
+ iio_trigger_free(trig);
+ return ret;
+ }
+
+ iio->trig = trig;
+
+ return 0;
+}
+
+static void mxs_lradc_trigger_remove(struct iio_dev *iio)
+{
+ iio_trigger_unregister(iio->trig);
+ iio_trigger_free(iio->trig);
+}
+
+static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
+{
+ struct mxs_lradc *lradc = iio_priv(iio);
+ struct iio_buffer *buffer = iio->buffer;
+ int ret = 0, chan, ofs = 0, enable = 0;
+ uint32_t ctrl4 = 0;
+ uint32_t ctrl1_irq = 0;
+ const uint32_t chan_value = LRADC_CH_ACCUMULATE |
+ ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
+ const int len = bitmap_weight(buffer->scan_mask, LRADC_MAX_TOTAL_CHANS);
+
+ if (!len)
+ return -EINVAL;
+
+ /*
+ * Lock the driver so raw access can not be done during buffered
+ * operation. This simplifies the code a lot.
+ */
+ ret = mutex_trylock(&lradc->lock);
+ if (!ret)
+ return -EBUSY;
+
+ lradc->buffer = kmalloc(len * sizeof(*lradc->buffer), GFP_KERNEL);
+ if (!lradc->buffer) {
+ ret = -ENOMEM;
+ goto err_mem;
+ }
+
+ ret = iio_sw_buffer_preenable(iio);
+ if (ret < 0)
+ goto err_buf;
+
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+
+ for_each_set_bit(chan, buffer->scan_mask, LRADC_MAX_TOTAL_CHANS) {
+ ctrl4 |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
+ ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
+ writel(chan_value, lradc->base + LRADC_CH(ofs));
+ enable |= 1 << ofs;
+ ofs++;
+ };
+
+ writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+
+ writel(ctrl4, lradc->base + LRADC_CTRL4);
+ writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+
+ writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
+
+ return 0;
+
+err_buf:
+ kfree(lradc->buffer);
+err_mem:
+ mutex_unlock(&lradc->lock);
+ return ret;
+}
+
+static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
+{
+ struct mxs_lradc *lradc = iio_priv(iio);
+
+ writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ kfree(lradc->buffer);
+ mutex_unlock(&lradc->lock);
+
+ return 0;
+}
+
+static bool mxs_lradc_validate_scan_mask(struct iio_dev *iio,
+ const unsigned long *mask)
+{
+ const int mw = bitmap_weight(mask, iio->masklength);
+
+ return mw <= LRADC_MAX_MAPPED_CHANS;
+}
+
+static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
+ .preenable = &mxs_lradc_buffer_preenable,
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = &iio_triggered_buffer_predisable,
+ .postdisable = &mxs_lradc_buffer_postdisable,
+ .validate_scan_mask = &mxs_lradc_validate_scan_mask,
+};
+
+/*
+ * Driver initialization
+ */
+
+#define MXS_ADC_CHAN(idx, chan_type) { \
+ .type = (chan_type), \
+ .indexed = 1, \
+ .scan_index = (idx), \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
+ .channel = (idx), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 18, \
+ .storagebits = 32, \
+ }, \
+}
+
+static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
+ MXS_ADC_CHAN(0, IIO_VOLTAGE),
+ MXS_ADC_CHAN(1, IIO_VOLTAGE),
+ MXS_ADC_CHAN(2, IIO_VOLTAGE),
+ MXS_ADC_CHAN(3, IIO_VOLTAGE),
+ MXS_ADC_CHAN(4, IIO_VOLTAGE),
+ MXS_ADC_CHAN(5, IIO_VOLTAGE),
+ MXS_ADC_CHAN(6, IIO_VOLTAGE),
+ MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */
+ MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */
+ MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */
+ MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */
+ MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */
+ MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */
+ MXS_ADC_CHAN(13, IIO_VOLTAGE), /* VDDD */
+ MXS_ADC_CHAN(14, IIO_VOLTAGE), /* VBG */
+ MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */
+};
+
+static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
+{
+ int i;
+ const uint32_t cfg =
+ (LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
+
+ stmp_reset_block(lradc->base);
+
+ for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
+ writel(cfg | (1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + i)),
+ lradc->base + LRADC_DELAY(i));
+
+ /* Start internal temperature sensing. */
+ writel(0, lradc->base + LRADC_CTRL2);
+}
+
+static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
+{
+ int i;
+
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
+ writel(0, lradc->base + LRADC_DELAY(i));
+}
+
+static int __devinit mxs_lradc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mxs_lradc *lradc;
+ struct iio_dev *iio;
+ struct resource *iores;
+ int ret = 0;
+ int i;
+
+ /* Allocate the IIO device. */
+ iio = iio_device_alloc(sizeof(*lradc));
+ if (!iio) {
+ dev_err(dev, "Failed to allocate IIO device\n");
+ return -ENOMEM;
+ }
+
+ lradc = iio_priv(iio);
+
+ /* Grab the memory area */
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ lradc->dev = &pdev->dev;
+ lradc->base = devm_request_and_ioremap(dev, iores);
+ if (!lradc->base) {
+ ret = -EADDRNOTAVAIL;
+ goto err_addr;
+ }
+
+ /* Grab all IRQ sources */
+ for (i = 0; i < 13; i++) {
+ lradc->irq[i] = platform_get_irq(pdev, i);
+ if (lradc->irq[i] < 0) {
+ ret = -EINVAL;
+ goto err_addr;
+ }
+
+ ret = devm_request_irq(dev, lradc->irq[i],
+ mxs_lradc_handle_irq, 0,
+ mxs_lradc_irq_name[i], iio);
+ if (ret)
+ goto err_addr;
+ }
+
+ platform_set_drvdata(pdev, iio);
+
+ init_completion(&lradc->completion);
+ mutex_init(&lradc->lock);
+
+ iio->name = pdev->name;
+ iio->dev.parent = &pdev->dev;
+ iio->info = &mxs_lradc_iio_info;
+ iio->modes = INDIO_DIRECT_MODE;
+ iio->channels = mxs_lradc_chan_spec;
+ iio->num_channels = ARRAY_SIZE(mxs_lradc_chan_spec);
+
+ ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time,
+ &mxs_lradc_trigger_handler,
+ &mxs_lradc_buffer_ops);
+ if (ret)
+ goto err_addr;
+
+ ret = mxs_lradc_trigger_init(iio);
+ if (ret)
+ goto err_trig;
+
+ /* Register IIO device. */
+ ret = iio_device_register(iio);
+ if (ret) {
+ dev_err(dev, "Failed to register IIO device\n");
+ goto err_dev;
+ }
+
+ /* Configure the hardware. */
+ mxs_lradc_hw_init(lradc);
+
+ return 0;
+
+err_dev:
+ mxs_lradc_trigger_remove(iio);
+err_trig:
+ iio_triggered_buffer_cleanup(iio);
+err_addr:
+ iio_device_free(iio);
+ return ret;
+}
+
+static int __devexit mxs_lradc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *iio = platform_get_drvdata(pdev);
+ struct mxs_lradc *lradc = iio_priv(iio);
+
+ mxs_lradc_hw_stop(lradc);
+
+ iio_device_unregister(iio);
+ iio_triggered_buffer_cleanup(iio);
+ mxs_lradc_trigger_remove(iio);
+ iio_device_free(iio);
+
+ return 0;
+}
+
+static const struct of_device_id mxs_lradc_dt_ids[] = {
+ { .compatible = "fsl,imx28-lradc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
+
+static struct platform_driver mxs_lradc_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mxs_lradc_dt_ids,
+ },
+ .probe = mxs_lradc_probe,
+ .remove = __devexit_p(mxs_lradc_remove),
+};
+
+module_platform_driver(mxs_lradc_driver);
+
+MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
+MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 64d630e..0b83e2e 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -189,7 +189,7 @@ static int spear_read_raw(struct iio_dev *indio_dev,
}, \
}
-static struct iio_chan_spec spear_adc_iio_channels[] = {
+static const struct iio_chan_spec spear_adc_iio_channels[] = {
SPEAR_ADC_CHAN(0),
SPEAR_ADC_CHAN(1),
SPEAR_ADC_CHAN(2),
@@ -330,36 +330,30 @@ static int __devinit spear_adc_probe(struct platform_device *pdev)
goto errout3;
}
- ret = clk_prepare(info->clk);
- if (ret) {
- dev_err(dev, "failed preparing clock\n");
- goto errout4;
- }
-
- ret = clk_enable(info->clk);
+ ret = clk_prepare_enable(info->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
- goto errout5;
+ goto errout4;
}
irq = platform_get_irq(pdev, 0);
if ((irq < 0) || (irq >= NR_IRQS)) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
- goto errout6;
+ goto errout5;
}
ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
- goto errout6;
+ goto errout5;
}
if (of_property_read_u32(np, "sampling-frequency",
&info->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
- goto errout6;
+ goto errout5;
}
/*
@@ -389,16 +383,14 @@ static int __devinit spear_adc_probe(struct platform_device *pdev)
ret = iio_device_register(iodev);
if (ret)
- goto errout6;
+ goto errout5;
dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
return 0;
-errout6:
- clk_disable(info->clk);
errout5:
- clk_unprepare(info->clk);
+ clk_disable_unprepare(info->clk);
errout4:
clk_put(info->clk);
errout3:
@@ -416,8 +408,7 @@ static int __devexit spear_adc_remove(struct platform_device *pdev)
iio_device_unregister(iodev);
platform_set_drvdata(pdev, NULL);
- clk_disable(info->clk);
- clk_unprepare(info->clk);
+ clk_disable_unprepare(info->clk);
clk_put(info->clk);
iounmap(info->adc_base_spear6xx);
iio_device_free(iodev);
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index 9931e20..87151a7 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -184,7 +184,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int adis16060_r_remove(struct spi_device *spi)
+static int __devexit adis16060_r_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
@@ -210,7 +210,7 @@ error_ret:
return ret;
}
-static int adis16060_w_remove(struct spi_device *spi)
+static int __devexit adis16060_w_remove(struct spi_device *spi)
{
return 0;
}
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index 345e4fa..a739025 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -177,7 +177,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int adis16080_remove(struct spi_device *spi)
+static int __devexit adis16080_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
index bf61cd0..fbf96b0 100644
--- a/drivers/staging/iio/gyro/adis16130_core.c
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -154,7 +154,7 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int adis16130_remove(struct spi_device *spi)
+static int __devexit adis16130_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index eb8e9d6..9571c03 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -700,24 +700,18 @@ error_ret:
return ret;
}
-static int adis16260_remove(struct spi_device *spi)
+static int __devexit adis16260_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
-
- ret = adis16260_stop_device(indio_dev);
- if (ret)
- goto err_ret;
-
+ adis16260_stop_device(indio_dev);
adis16260_remove_trigger(indio_dev);
iio_buffer_unregister(indio_dev);
adis16260_unconfigure_ring(indio_dev);
iio_device_free(indio_dev);
-err_ret:
- return ret;
+ return 0;
}
/*
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index eeee8e7..e294cb4 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -62,7 +62,6 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16260_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
@@ -82,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
kfree(data);
done:
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c
index 6513119..d93527d 100644
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ b/drivers/staging/iio/gyro/adxrs450_core.c
@@ -409,7 +409,7 @@ error_ret:
return ret;
}
-static int adxrs450_remove(struct spi_device *spi)
+static int __devexit adxrs450_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index 0cd4fe9..74e24e8 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -216,6 +216,6 @@ static __exit void iio_dummy_evgen_exit(void)
}
module_exit(iio_dummy_evgen_exit);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("IIO dummy driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c
index 27d27ec..5d49122 100644
--- a/drivers/staging/iio/iio_hwmon.c
+++ b/drivers/staging/iio/iio_hwmon.c
@@ -42,40 +42,17 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- long result;
- int val, ret, scaleint, scalepart;
+ int result;
+ int ret;
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
struct iio_hwmon_state *state = dev_get_drvdata(dev);
- /*
- * No locking between this pair, so theoretically possible
- * the scale has changed.
- */
- ret = iio_read_channel_raw(&state->channels[sattr->index],
- &val);
+ ret = iio_read_channel_processed(&state->channels[sattr->index],
+ &result);
if (ret < 0)
return ret;
- ret = iio_read_channel_scale(&state->channels[sattr->index],
- &scaleint, &scalepart);
- if (ret < 0)
- return ret;
- switch (ret) {
- case IIO_VAL_INT:
- result = val * scaleint;
- break;
- case IIO_VAL_INT_PLUS_MICRO:
- result = (s64)val * (s64)scaleint +
- div_s64((s64)val * (s64)scalepart, 1000000LL);
- break;
- case IIO_VAL_INT_PLUS_NANO:
- result = (s64)val * (s64)scaleint +
- div_s64((s64)val * (s64)scalepart, 1000000000LL);
- break;
- default:
- return -EINVAL;
- }
- return sprintf(buf, "%ld\n", result);
+ return sprintf(buf, "%d\n", result);
}
static void iio_hwmon_free_attrs(struct iio_hwmon_state *st)
@@ -215,18 +192,8 @@ static struct platform_driver __refdata iio_hwmon_driver = {
.remove = __devexit_p(iio_hwmon_remove),
};
-static int iio_inkern_init(void)
-{
- return platform_driver_register(&iio_hwmon_driver);
-}
-module_init(iio_inkern_init);
-
-static void iio_inkern_exit(void)
-{
- platform_driver_unregister(&iio_hwmon_driver);
-}
-module_exit(iio_inkern_exit);
+module_platform_driver(iio_hwmon_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("IIO to hwmon driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index 155a49a..dc6c728 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -63,7 +63,7 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = {
* This array of structures tells the IIO core about what the device
* actually provides for a given channel.
*/
-static struct iio_chan_spec iio_dummy_channels[] = {
+static const struct iio_chan_spec iio_dummy_channels[] = {
/* indexed ADC channel in_voltage0_raw etc */
{
.type = IIO_VOLTAGE,
@@ -445,26 +445,20 @@ static int __devinit iio_dummy_probe(int index)
if (ret < 0)
goto error_free_device;
- /* Configure buffered capture support. */
- ret = iio_simple_dummy_configure_buffer(indio_dev);
- if (ret < 0)
- goto error_unregister_events;
-
/*
- * Register the channels with the buffer, but avoid the output
- * channel being registered by reducing the number of channels by 1.
+ * Configure buffered capture support and register the channels with the
+ * buffer, but avoid the output channel being registered by reducing the
+ * number of channels by 1.
*/
- ret = iio_buffer_register(indio_dev, iio_dummy_channels, 5);
+ ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
if (ret < 0)
- goto error_unconfigure_buffer;
+ goto error_unregister_events;
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto error_unregister_buffer;
+ goto error_unconfigure_buffer;
return 0;
-error_unregister_buffer:
- iio_buffer_unregister(indio_dev);
error_unconfigure_buffer:
iio_simple_dummy_unconfigure_buffer(indio_dev);
error_unregister_events:
@@ -499,7 +493,6 @@ static int iio_dummy_remove(int index)
/* Device specific code to power down etc */
/* Buffered capture related cleanup */
- iio_buffer_unregister(indio_dev);
iio_simple_dummy_unconfigure_buffer(indio_dev);
ret = iio_simple_dummy_events_unregister(indio_dev);
@@ -530,6 +523,7 @@ static __init int iio_dummy_init(void)
instances = 1;
return -EINVAL;
}
+
/* Fake a bus */
iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
GFP_KERNEL);
@@ -558,6 +552,6 @@ static __exit void iio_dummy_exit(void)
}
module_exit(iio_dummy_exit);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("IIO dummy driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index 53975d9..c9e8702 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -95,10 +95,12 @@ enum iio_simple_dummy_scan_elements {
};
#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev);
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *channels, unsigned int num_channels);
void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
#else
-static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
+static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *channels, unsigned int num_channels)
{
return 0;
};
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index bd628de..697d970 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -87,7 +87,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= iio_get_time_ns();
- buffer->access->store_to(buffer, (u8 *)data, pf->timestamp);
+ iio_push_to_buffer(buffer, (u8 *)data);
kfree(data);
@@ -126,7 +126,8 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
.predisable = &iio_triggered_buffer_predisable,
};
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *channels, unsigned int num_channels)
{
int ret;
struct iio_buffer *buffer;
@@ -182,8 +183,15 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
* driven by a trigger.
*/
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
+
+ ret = iio_buffer_register(indio_dev, channels, num_channels);
+ if (ret)
+ goto error_dealloc_pollfunc;
+
return 0;
+error_dealloc_pollfunc:
+ iio_dealloc_pollfunc(indio_dev->pollfunc);
error_free_buffer:
iio_kfifo_free(indio_dev->buffer);
error_ret:
@@ -197,6 +205,7 @@ error_ret:
*/
void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
{
+ iio_buffer_unregister(indio_dev);
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_kfifo_free(indio_dev->buffer);
}
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index a8e51bc..de21d47 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -108,7 +108,7 @@ static struct ad5933_platform_data ad5933_default_pdata = {
.vref_mv = 3300,
};
-static struct iio_chan_spec ad5933_channels[] = {
+static const struct iio_chan_spec ad5933_channels[] = {
{
.type = IIO_TEMP,
.indexed = 1,
@@ -678,7 +678,7 @@ static void ad5933_work(struct work_struct *work)
buf[0] = be16_to_cpu(buf[0]);
}
/* save datum to the ring */
- ring->access->store_to(ring, (u8 *)buf, iio_get_time_ns());
+ iio_push_to_buffer(ring, (u8 *)buf);
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index 9dd9f14..d59d7ac 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -5,7 +5,7 @@
* 3d 2.5gauss magnetometers via SPI
*
* Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
- * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
*
* Loosely based upon lis3l02dq.h
*
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index a618327..b302c9b 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -5,7 +5,7 @@
* 3d Magnetometers via SPI
*
* Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
- * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
* Copyright (c) 2011 Analog Devices Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -612,7 +612,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
}
}
-static struct iio_chan_spec adis16400_channels[] = {
+static const struct iio_chan_spec adis16400_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -742,7 +742,7 @@ static struct iio_chan_spec adis16400_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(12)
};
-static struct iio_chan_spec adis16350_channels[] = {
+static const struct iio_chan_spec adis16350_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -867,7 +867,7 @@ static struct iio_chan_spec adis16350_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(11)
};
-static struct iio_chan_spec adis16300_channels[] = {
+static const struct iio_chan_spec adis16300_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -1206,15 +1206,12 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int adis16400_remove(struct spi_device *spi)
+static int __devexit adis16400_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
- ret = adis16400_stop_device(indio_dev);
- if (ret)
- goto err_ret;
+ adis16400_stop_device(indio_dev);
adis16400_remove_trigger(indio_dev);
iio_buffer_unregister(indio_dev);
@@ -1222,9 +1219,6 @@ static int adis16400_remove(struct spi_device *spi)
iio_device_free(indio_dev);
return 0;
-
-err_ret:
- return ret;
}
static const struct spi_device_id adis16400_id[] = {
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index beec650..260bdd1 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -150,7 +150,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(indio_dev->buffer, (u8 *) data, pf->timestamp);
+ iio_push_to_buffer(ring, (u8 *) data);
done:
kfree(data);
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 31d22f5..6ee5567 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -63,6 +63,7 @@ struct isl29018_chip {
struct regmap *regmap;
struct mutex lock;
unsigned int lux_scale;
+ unsigned int lux_uscale;
unsigned int range;
unsigned int adc_bit;
int prox_scheme;
@@ -145,13 +146,22 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
{
int lux_data;
+ unsigned int data_x_range, lux_unshifted;
lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE);
if (lux_data < 0)
return lux_data;
- *lux = (lux_data * chip->range * chip->lux_scale) >> chip->adc_bit;
+ /* To support fractional scaling, separate the unshifted lux
+ * into two calculations: int scaling and micro-scaling.
+ * lux_uscale ranges from 0-999999, so about 20 bits. Split
+ * the /1,000,000 in two to reduce the risk of over/underflow.
+ */
+ data_x_range = lux_data * chip->range;
+ lux_unshifted = data_x_range * chip->lux_scale;
+ lux_unshifted += data_x_range / 1000 * chip->lux_uscale / 1000;
+ *lux = lux_unshifted >> chip->adc_bit;
return 0;
}
@@ -339,6 +349,8 @@ static int isl29018_write_raw(struct iio_dev *indio_dev,
mutex_lock(&chip->lock);
if (mask == IIO_CHAN_INFO_CALIBSCALE && chan->type == IIO_LIGHT) {
chip->lux_scale = val;
+ /* With no write_raw_get_fmt(), val2 is a MICRO fraction. */
+ chip->lux_uscale = val2;
ret = 0;
}
mutex_unlock(&chip->lock);
@@ -379,7 +391,8 @@ static int isl29018_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_CALIBSCALE:
if (chan->type == IIO_LIGHT) {
*val = chip->lux_scale;
- ret = IIO_VAL_INT;
+ *val2 = chip->lux_uscale;
+ ret = IIO_VAL_INT_PLUS_MICRO;
}
break;
default:
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 9d740be..954ca2c 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -805,7 +805,7 @@ fail1:
return err;
}
-static int tsl2563_remove(struct i2c_client *client)
+static int __devexit tsl2563_remove(struct i2c_client *client)
{
struct tsl2563_chip *chip = i2c_get_clientdata(client);
struct iio_dev *indio_dev = iio_priv_to_dev(chip);
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 6c3e50f..10e0954 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -1,6 +1,6 @@
/* Copyright (C) 2010 Texas Instruments
Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
- Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
+ Acknowledgement: Jonathan Cameron <jic23@kernel.org> for valuable inputs.
Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 3ccff18..8b9eceb 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -555,20 +555,15 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int ade7753_remove(struct spi_device *spi)
+static int __devexit ade7753_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
-
- ret = ade7753_stop_device(&(indio_dev->dev));
- if (ret)
- goto err_ret;
-
+ ade7753_stop_device(&indio_dev->dev);
iio_device_free(indio_dev);
-err_ret:
- return ret;
+
+ return 0;
}
static struct spi_driver ade7753_driver = {
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index abb1e9c..76e0ade 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -577,21 +577,15 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int ade7754_remove(struct spi_device *spi)
+static int __devexit ade7754_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
- ret = ade7754_stop_device(&(indio_dev->dev));
- if (ret)
- goto err_ret;
-
+ ade7754_stop_device(&indio_dev->dev);
iio_device_free(indio_dev);
-err_ret:
- return ret;
-
+ return 0;
}
static struct spi_driver ade7754_driver = {
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index ec202b4..1e11ad5 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -122,7 +122,7 @@ struct ade7758_state {
u8 *tx;
u8 *rx;
struct mutex buf_lock;
- struct iio_chan_spec *ade7758_ring_channels;
+ const struct iio_chan_spec *ade7758_ring_channels;
struct spi_transfer ring_xfer[4];
struct spi_message ring_msg;
/*
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 7014a00..a0fef77 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -661,7 +661,7 @@ static const struct attribute_group ade7758_attribute_group = {
.attrs = ade7758_attributes,
};
-static struct iio_chan_spec ade7758_channels[] = {
+static const struct iio_chan_spec ade7758_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -962,17 +962,13 @@ error_ret:
return ret;
}
-static int ade7758_remove(struct spi_device *spi)
+static int __devexit ade7758_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ade7758_state *st = iio_priv(indio_dev);
- int ret;
iio_device_unregister(indio_dev);
- ret = ade7758_stop_device(&indio_dev->dev);
- if (ret)
- goto err_ret;
-
+ ade7758_stop_device(&indio_dev->dev);
ade7758_remove_trigger(indio_dev);
ade7758_uninitialize_ring(indio_dev);
ade7758_unconfigure_ring(indio_dev);
@@ -981,8 +977,7 @@ static int ade7758_remove(struct spi_device *spi)
iio_device_free(indio_dev);
-err_ret:
- return ret;
+ return 0;
}
static const struct spi_device_id ade7758_id[] = {
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 1ce10b2..9e49bac 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -61,7 +61,6 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
struct ade7758_state *st = iio_priv(indio_dev);
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;
@@ -74,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp;
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
+ iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index eb0a2a9..cb0707c 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -499,20 +499,15 @@ error_ret:
}
/* fixme, confirm ordering in this function */
-static int ade7759_remove(struct spi_device *spi)
+static int __devexit ade7759_remove(struct spi_device *spi)
{
- int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
- ret = ade7759_stop_device(&(indio_dev->dev));
- if (ret)
- goto err_ret;
-
+ ade7759_stop_device(&indio_dev->dev);
iio_device_free(indio_dev);
-err_ret:
- return ret;
+ return 0;
}
static struct spi_driver ade7759_driver = {
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index 9fb2f8b..7dae035 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -330,7 +330,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi)
return 0;
}
-static int ade7854_spi_remove(struct spi_device *spi)
+static int __devexit ade7854_spi_remove(struct spi_device *spi)
{
ade7854_remove(spi_get_drvdata(spi));
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index f313859..4ba4d05 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -575,7 +575,7 @@ static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR,
AD2S1210_REG_LOT_LOW_THRD);
-static struct iio_chan_spec ad2s1210_channels[] = {
+static const struct iio_chan_spec ad2s1210_channels[] = {
{
.type = IIO_ANGL,
.indexed = 1,
diff --git a/drivers/staging/iio/ring_hw.h b/drivers/staging/iio/ring_hw.h
index cad8a2e..39c14a7 100644
--- a/drivers/staging/iio/ring_hw.h
+++ b/drivers/staging/iio/ring_hw.h
@@ -5,7 +5,7 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
- * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
*
*/
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index f61c8fd..3a45f9a 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -65,7 +65,7 @@ static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
/* Lock always held if their is a chance this may be called */
/* Only one of these per ring may run concurrently - enforced by drivers */
static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
- unsigned char *data, s64 timestamp)
+ unsigned char *data)
{
int ret = 0;
unsigned char *temp_ptr, *change_test_ptr;
@@ -256,11 +256,10 @@ error_ret:
}
static int iio_store_to_sw_rb(struct iio_buffer *r,
- u8 *data,
- s64 timestamp)
+ u8 *data)
{
struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
- return iio_store_to_sw_ring(ring, data, timestamp);
+ return iio_store_to_sw_ring(ring, data);
}
static int iio_request_update_sw_rb(struct iio_buffer *r)
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig
index b8abf54..7d32075 100644
--- a/drivers/staging/iio/trigger/Kconfig
+++ b/drivers/staging/iio/trigger/Kconfig
@@ -21,6 +21,8 @@ config IIO_GPIO_TRIGGER
config IIO_SYSFS_TRIGGER
tristate "SYSFS trigger"
depends on SYSFS
+ depends on HAVE_IRQ_WORK
+ select IRQ_WORK
help
Provides support for using SYSFS entry as IIO triggers.
If unsure, say N (but it's safe to say "Y").
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index ce6a7b1..52062d7 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -14,14 +14,18 @@
#include <linux/delay.h>
#include <asm/gptimers.h>
+#include <asm/portmux.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
+#include "iio-trig-bfin-timer.h"
+
struct bfin_timer {
unsigned short id, bit;
unsigned long irqbit;
int irq;
+ int pin;
};
/*
@@ -30,22 +34,22 @@ struct bfin_timer {
*/
static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = {
- {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0},
- {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1},
- {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2},
+ {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0, P_TMR0},
+ {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1, P_TMR1},
+ {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2, P_TMR2},
#if (MAX_BLACKFIN_GPTIMERS > 3)
- {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3},
- {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4},
- {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5},
- {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6},
- {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7},
+ {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3, P_TMR3},
+ {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4, P_TMR4},
+ {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5, P_TMR5},
+ {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6, P_TMR6},
+ {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7, P_TMR7},
#endif
#if (MAX_BLACKFIN_GPTIMERS > 8)
- {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8},
- {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9},
- {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10},
+ {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8, P_TMR8},
+ {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9, P_TMR9},
+ {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10, P_TMR10},
#if (MAX_BLACKFIN_GPTIMERS > 11)
- {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11},
+ {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11, P_TMR11},
#endif
#endif
};
@@ -54,15 +58,33 @@ struct bfin_tmr_state {
struct iio_trigger *trig;
struct bfin_timer *t;
unsigned timer_num;
+ bool output_enable;
+ unsigned int duty;
int irq;
};
+static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state)
+{
+ struct bfin_tmr_state *st = trig->private_data;
+
+ if (get_gptimer_period(st->t->id) == 0)
+ return -EINVAL;
+
+ if (state)
+ enable_gptimers(st->t->bit);
+ else
+ disable_gptimers(st->t->bit);
+
+ return 0;
+}
+
static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct bfin_tmr_state *st = trig->private_data;
- long val;
+ unsigned long val;
+ bool enabled;
int ret;
ret = strict_strtoul(buf, 10, &val);
@@ -74,20 +96,25 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
goto error_ret;
}
- disable_gptimers(st->t->bit);
+ enabled = get_enabled_gptimers() & st->t->bit;
+
+ if (enabled)
+ disable_gptimers(st->t->bit);
if (!val)
goto error_ret;
val = get_sclk() / val;
- if (val <= 4) {
+ if (val <= 4 || val <= st->duty) {
ret = -EINVAL;
goto error_ret;
}
set_gptimer_period(st->t->id, val);
- set_gptimer_pwidth(st->t->id, 1);
- enable_gptimers(st->t->bit);
+ set_gptimer_pwidth(st->t->id, val - st->duty);
+
+ if (enabled)
+ enable_gptimers(st->t->bit);
error_ret:
return ret ? ret : count;
@@ -99,9 +126,15 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct bfin_tmr_state *st = trig->private_data;
+ unsigned int period = get_gptimer_period(st->t->id);
+ unsigned long val;
+
+ if (period == 0)
+ val = 0;
+ else
+ val = get_sclk() / get_gptimer_period(st->t->id);
- return sprintf(buf, "%lu\n",
- get_sclk() / get_gptimer_period(st->t->id));
+ return sprintf(buf, "%lu\n", val);
}
static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show,
@@ -121,7 +154,6 @@ static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = {
NULL
};
-
static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
{
struct bfin_tmr_state *st = devid;
@@ -145,11 +177,14 @@ static int iio_bfin_tmr_get_number(int irq)
static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = {
.owner = THIS_MODULE,
+ .set_trigger_state = iio_bfin_tmr_set_state,
};
static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
{
+ struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data;
struct bfin_tmr_state *st;
+ unsigned int config;
int ret;
st = kzalloc(sizeof(*st), GFP_KERNEL);
@@ -193,13 +228,43 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
goto out4;
}
- set_gptimer_config(st->t->id, OUT_DIS | PWM_OUT | PERIOD_CNT | IRQ_ENA);
+ config = PWM_OUT | PERIOD_CNT | IRQ_ENA;
+
+ if (pdata && pdata->output_enable) {
+ unsigned long long val;
+
+ st->output_enable = true;
+
+ ret = peripheral_request(st->t->pin, st->trig->name);
+ if (ret)
+ goto out_free_irq;
+
+ val = (unsigned long long)get_sclk() * pdata->duty_ns;
+ do_div(val, NSEC_PER_SEC);
+ st->duty = val;
+
+ /**
+ * The interrupt will be generated at the end of the period,
+ * since we want the interrupt to be generated at end of the
+ * pulse we invert both polarity and duty cycle, so that the
+ * pulse will be generated directly before the interrupt.
+ */
+ if (pdata->active_low)
+ config |= PULSE_HI;
+ } else {
+ st->duty = 1;
+ config |= OUT_DIS;
+ }
+
+ set_gptimer_config(st->t->id, config);
dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d",
st->timer_num, st->irq);
platform_set_drvdata(pdev, st);
return 0;
+out_free_irq:
+ free_irq(st->irq, st);
out4:
iio_trigger_unregister(st->trig);
out2:
@@ -215,6 +280,8 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
struct bfin_tmr_state *st = platform_get_drvdata(pdev);
disable_gptimers(st->t->bit);
+ if (st->output_enable)
+ peripheral_free(st->t->pin);
free_irq(st->irq, st);
iio_trigger_unregister(st->trig);
iio_trigger_put(st->trig);
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.h b/drivers/staging/iio/trigger/iio-trig-bfin-timer.h
new file mode 100644
index 0000000..c07321f
--- /dev/null
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.h
@@ -0,0 +1,24 @@
+#ifndef __IIO_BFIN_TIMER_TRIGGER_H__
+#define __IIO_BFIN_TIMER_TRIGGER_H__
+
+/**
+ * struct iio_bfin_timer_trigger_pdata - timer trigger platform data
+ * @output_enable: Enable external trigger pulse generation.
+ * @active_low: Whether the trigger pulse is active low.
+ * @duty_ns: Length of the trigger pulse in nanoseconds.
+ *
+ * This struct is used to configure the output pulse generation of the blackfin
+ * timer trigger. If output_enable is set to true an external trigger signal
+ * will generated on the pin corresponding to the timer. This is useful for
+ * converters which needs an external signal to start conversion. active_low and
+ * duty_ns are used to configure the type of the trigger pulse. If output_enable
+ * is set to false no external trigger pulse will be generated and active_low
+ * and duty_ns are ignored.
+ **/
+struct iio_bfin_timer_trigger_pdata {
+ bool output_enable;
+ bool active_low;
+ unsigned int duty_ns;
+};
+
+#endif
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
index 90b2684..5ff4d7f 100644
--- a/drivers/staging/iio/trigger/iio-trig-gpio.c
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -51,7 +51,7 @@ static const struct iio_trigger_ops iio_gpio_trigger_ops = {
.owner = THIS_MODULE,
};
-static int iio_gpio_trigger_probe(struct platform_device *pdev)
+static int __devinit iio_gpio_trigger_probe(struct platform_device *pdev)
{
struct iio_gpio_trigger_info *trig_info;
struct iio_trigger *trig, *trig2;
@@ -130,7 +130,7 @@ error_free_completed_registrations:
return ret;
}
-static int iio_gpio_trigger_remove(struct platform_device *pdev)
+static int __devexit iio_gpio_trigger_remove(struct platform_device *pdev)
{
struct iio_trigger *trig, *trig2;
struct iio_gpio_trigger_info *trig_info;
@@ -153,7 +153,7 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev)
static struct platform_driver iio_gpio_trigger_driver = {
.probe = iio_gpio_trigger_probe,
- .remove = iio_gpio_trigger_remove,
+ .remove = __devexit_p(iio_gpio_trigger_remove),
.driver = {
.name = "iio_gpio_trigger",
.owner = THIS_MODULE,
@@ -162,6 +162,6 @@ static struct platform_driver iio_gpio_trigger_driver = {
module_platform_driver(iio_gpio_trigger_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 4ceaa18..a3de76d 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -101,7 +101,7 @@ static const struct iio_trigger_ops iio_prtc_trigger_ops = {
.set_trigger_state = &iio_trig_periodic_rtc_set_state,
};
-static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
+static int __devinit iio_trig_periodic_rtc_probe(struct platform_device *dev)
{
char **pdata = dev->dev.platform_data;
struct iio_prtc_trigger_info *trig_info;
@@ -167,7 +167,7 @@ error_free_completed_registrations:
return ret;
}
-static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
+static int __devexit iio_trig_periodic_rtc_remove(struct platform_device *dev)
{
struct iio_trigger *trig, *trig2;
struct iio_prtc_trigger_info *trig_info;
@@ -188,7 +188,7 @@ static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
static struct platform_driver iio_trig_periodic_rtc_driver = {
.probe = iio_trig_periodic_rtc_probe,
- .remove = iio_trig_periodic_rtc_remove,
+ .remove = __devexit_p(iio_trig_periodic_rtc_remove),
.driver = {
.name = "iio_prtc_trigger",
.owner = THIS_MODULE,
@@ -197,6 +197,6 @@ static struct platform_driver iio_trig_periodic_rtc_driver = {
module_platform_driver(iio_trig_periodic_rtc_driver);
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c
index fee4746..3bac972 100644
--- a/drivers/staging/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c
@@ -10,12 +10,14 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/list.h>
+#include <linux/irq_work.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
struct iio_sysfs_trig {
struct iio_trigger *trig;
+ struct irq_work work;
int id;
struct list_head l;
};
@@ -89,11 +91,21 @@ static struct device iio_sysfs_trig_dev = {
.release = &iio_trigger_sysfs_release,
};
+static void iio_sysfs_trigger_work(struct irq_work *work)
+{
+ struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
+ work);
+
+ iio_trigger_poll(trig->trig, 0);
+}
+
static ssize_t iio_sysfs_trigger_poll(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct iio_trigger *trig = to_iio_trigger(dev);
- iio_trigger_poll_chained(trig, 0);
+ struct iio_sysfs_trig *sysfs_trig = trig->private_data;
+
+ irq_work_queue(&sysfs_trig->work);
return count;
}
@@ -148,6 +160,9 @@ static int iio_sysfs_trigger_probe(int id)
t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
t->trig->ops = &iio_sysfs_trigger_ops;
t->trig->dev.parent = &iio_sysfs_trig_dev;
+ t->trig->private_data = t;
+
+ init_irq_work(&t->work, iio_sysfs_trigger_work);
ret = iio_trigger_register(t->trig);
if (ret)