* [PATCH 2/7] staging:iio:ad7887: Rework regulator handling
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 3/7] staging:iio:ad7887: Squash everything into one file Lars-Peter Clausen
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
Rework the regulator handling of the ad7887 driver to match more closely what we
do for other drivers. Only request the regulator if a external reference is
used, but treat it as an error if requesting the regulator fails. Also remove
the possibility to specify the reference voltage via platform data and always
use the regulator for this.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/staging/iio/adc/ad7887.h | 3 --
drivers/staging/iio/adc/ad7887_core.c | 52 ++++++++++++++++-------------------
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index 71e5092..25d5b40 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -30,8 +30,6 @@ enum ad7887_channels {
*/
struct ad7887_platform_data {
- /* External Vref voltage applied */
- u16 vref_mv;
/*
* AD7887:
* In single channel mode en_dual = flase, AIN1/Vref pins assumes its
@@ -63,7 +61,6 @@ struct ad7887_state {
struct spi_device *spi;
const struct ad7887_chip_info *chip_info;
struct regulator *reg;
- u16 int_vref_mv;
struct spi_transfer xfer[4];
struct spi_message msg[3];
struct spi_message *ring_msg;
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 5517905..cf33ba6 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -39,7 +39,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7887_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -56,11 +55,18 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
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;
+ if (st->reg) {
+ *val = regulator_get_voltage(st->reg);
+ if (*val < 0)
+ return *val;
+ *val /= 1000;
+ } else {
+ *val = st->chip_info->int_vref_mv;
+ }
+
+ *val2 = st->chip_info->channel[0].scan_type.realbits;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
}
return -EINVAL;
}
@@ -105,21 +111,24 @@ static int __devinit ad7887_probe(struct spi_device *spi)
{
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
- int ret, voltage_uv = 0;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ int ret;
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
+ if (!pdata || !pdata->use_onchip_ref) {
+ st->reg = regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_free;
+ }
+
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
-
- voltage_uv = regulator_get_voltage(st->reg);
}
st->chip_info =
@@ -176,23 +185,9 @@ static int __devinit ad7887_probe(struct spi_device *spi)
spi_message_init(&st->msg[AD7887_CH1]);
spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
- 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");
-
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = 3;
} else {
- if (pdata && pdata->vref_mv)
- st->int_vref_mv = pdata->vref_mv;
- else if (pdata && pdata->use_onchip_ref)
- st->int_vref_mv = st->chip_info->int_vref_mv;
- else
- dev_warn(&spi->dev, "reference voltage unspecified\n");
-
indio_dev->channels = &st->chip_info->channel[1];
indio_dev->num_channels = 2;
}
@@ -209,11 +204,12 @@ static int __devinit ad7887_probe(struct spi_device *spi)
error_unregister_ring:
ad7887_ring_cleanup(indio_dev);
error_disable_reg:
- if (!IS_ERR(st->reg))
+ if (st->reg)
regulator_disable(st->reg);
error_put_reg:
- if (!IS_ERR(st->reg))
+ if (st->reg)
regulator_put(st->reg);
+error_free:
iio_device_free(indio_dev);
return ret;
@@ -226,7 +222,7 @@ static int __devexit ad7887_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad7887_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (st->reg) {
regulator_disable(st->reg);
regulator_put(st->reg);
}
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/7] staging:iio:ad7887: Squash everything into one file
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 2/7] staging:iio:ad7887: Rework regulator handling Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 4/7] staging:iio:ad7887: Use proper kernel doc Lars-Peter Clausen
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
The recent cleanups have decimated the drivers code size by quite a bit. It is
only a few hundred lines in total now and we also always build buffer support,
so there really is no need to spread the driver out over multiple files. Putting
everything into one file also allows to reduce the code size a bit more by
removing a few lines of boilerplate code.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/staging/iio/adc/Makefile | 2 -
.../staging/iio/adc/{ad7887_core.c => ad7887.c} | 133 ++++++++++++++++++++-
drivers/staging/iio/adc/ad7887.h | 66 ----------
drivers/staging/iio/adc/ad7887_ring.c | 111 -----------------
4 files changed, 130 insertions(+), 182 deletions(-)
rename drivers/staging/iio/adc/{ad7887_core.c => ad7887.c} (62%)
delete mode 100644 drivers/staging/iio/adc/ad7887_ring.c
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index ff561c5..8036fd1 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o
ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
obj-$(CONFIG_AD799X) += ad799x.o
-ad7887-y := ad7887_core.o
-ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o
obj-$(CONFIG_AD7887) += ad7887.o
ad7298-y := ad7298_core.o
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887.c
similarity index 62%
rename from drivers/staging/iio/adc/ad7887_core.c
rename to drivers/staging/iio/adc/ad7887.c
index cf33ba6..88ffc46 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887.c
@@ -14,14 +14,140 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#include "ad7887.h"
+#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
+#define AD7887_DUAL (1 << 4) /* dual-channel mode */
+#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
+#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
+#define AD7887_PM_MODE1 (0) /* CS based shutdown */
+#define AD7887_PM_MODE2 (1) /* full on */
+#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
+#define AD7887_PM_MODE4 (3) /* standby mode */
+
+enum ad7887_channels {
+ AD7887_CH0,
+ AD7887_CH0_CH1,
+ AD7887_CH1,
+};
+
+#define RES_MASK(bits) ((1 << (bits)) - 1)
+
+/**
+ * struct ad7887_chip_info - chip specifc information
+ * @int_vref_mv: the internal reference voltage
+ * @channel: channel specification
+ */
+struct ad7887_chip_info {
+ u16 int_vref_mv;
+ struct iio_chan_spec channel[3];
+};
+
+struct ad7887_state {
+ struct spi_device *spi;
+ const struct ad7887_chip_info *chip_info;
+ struct regulator *reg;
+ struct spi_transfer xfer[4];
+ struct spi_message msg[3];
+ struct spi_message *ring_msg;
+ unsigned char tx_cmd_buf[8];
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ * Buffer needs to be large enough to hold two 16 bit samples and a
+ * 64 bit aligned 64 bit timestamp.
+ */
+ unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
+ ____cacheline_aligned;
+};
+
+enum ad7887_supported_device_ids {
+ ID_AD7887
+};
+
+static int ad7887_ring_preenable(struct iio_dev *indio_dev)
+{
+ struct ad7887_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = iio_sw_buffer_preenable(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ /* We know this is a single long so can 'cheat' */
+ switch (*indio_dev->active_scan_mask) {
+ case (1 << 0):
+ st->ring_msg = &st->msg[AD7887_CH0];
+ break;
+ case (1 << 1):
+ st->ring_msg = &st->msg[AD7887_CH1];
+ /* Dummy read: push CH1 setting down to hardware */
+ spi_sync(st->spi, st->ring_msg);
+ break;
+ case ((1 << 1) | (1 << 0)):
+ st->ring_msg = &st->msg[AD7887_CH0_CH1];
+ break;
+ }
+
+ return 0;
+}
+
+static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
+{
+ struct ad7887_state *st = iio_priv(indio_dev);
+
+ /* dummy read: restore default CH0 settin */
+ return spi_sync(st->spi, &st->msg[AD7887_CH0]);
+}
+
+/**
+ * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ **/
+static irqreturn_t ad7887_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ad7887_state *st = iio_priv(indio_dev);
+ s64 time_ns;
+ int b_sent;
+
+ b_sent = spi_sync(st->spi, st->ring_msg);
+ if (b_sent)
+ goto done;
+
+ time_ns = iio_get_time_ns();
+
+ if (indio_dev->scan_timestamp)
+ memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
+ &time_ns, sizeof(time_ns));
+
+ iio_push_to_buffer(indio_dev->buffer, st->data);
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
+ .preenable = &ad7887_ring_preenable,
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = &iio_triggered_buffer_predisable,
+ .postdisable = &ad7887_ring_postdisable,
+};
+
static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
{
int ret = spi_sync(st->spi, &st->msg[ch]);
@@ -192,7 +318,8 @@ static int __devinit ad7887_probe(struct spi_device *spi)
indio_dev->num_channels = 2;
}
- ret = ad7887_register_ring_funcs_and_init(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ &ad7887_trigger_handler, &ad7887_ring_setup_ops);
if (ret)
goto error_disable_reg;
@@ -202,7 +329,7 @@ static int __devinit ad7887_probe(struct spi_device *spi)
return 0;
error_unregister_ring:
- ad7887_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
if (st->reg)
regulator_disable(st->reg);
@@ -221,7 +348,7 @@ static int __devexit ad7887_remove(struct spi_device *spi)
struct ad7887_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7887_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
if (st->reg) {
regulator_disable(st->reg);
regulator_put(st->reg);
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index 25d5b40..b9078fc 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -8,23 +8,6 @@
#ifndef IIO_ADC_AD7887_H_
#define IIO_ADC_AD7887_H_
-#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
-#define AD7887_DUAL (1 << 4) /* dual-channel mode */
-#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
-#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
-#define AD7887_PM_MODE1 (0) /* CS based shutdown */
-#define AD7887_PM_MODE2 (1) /* full on */
-#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
-#define AD7887_PM_MODE4 (3) /* standby mode */
-
-enum ad7887_channels {
- AD7887_CH0,
- AD7887_CH0_CH1,
- AD7887_CH1,
-};
-
-#define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */
-
/*
* TODO: struct ad7887_platform_data needs to go into include/linux/iio
*/
@@ -46,53 +29,4 @@ struct ad7887_platform_data {
bool use_onchip_ref;
};
-/**
- * struct ad7887_chip_info - chip specifc information
- * @int_vref_mv: the internal reference voltage
- * @channel: channel specification
- */
-
-struct ad7887_chip_info {
- u16 int_vref_mv;
- struct iio_chan_spec channel[3];
-};
-
-struct ad7887_state {
- struct spi_device *spi;
- const struct ad7887_chip_info *chip_info;
- struct regulator *reg;
- struct spi_transfer xfer[4];
- struct spi_message msg[3];
- struct spi_message *ring_msg;
- unsigned char tx_cmd_buf[8];
-
- /*
- * DMA (thus cache coherency maintenance) requires the
- * transfer buffers to live in their own cache lines.
- * Buffer needs to be large enough to hold two 16 bit samples and a
- * 64 bit aligned 64 bit timestamp.
- */
- unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
- ____cacheline_aligned;
-};
-
-enum ad7887_supported_device_ids {
- ID_AD7887
-};
-
-#ifdef CONFIG_IIO_BUFFER
-int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad7887_ring_cleanup(struct iio_dev *indio_dev);
-#else /* CONFIG_IIO_BUFFER */
-
-static inline int
-ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_IIO_BUFFER */
#endif /* IIO_ADC_AD7887_H_ */
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
deleted file mode 100644
index f11925e..0000000
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2010-2012 Analog Devices Inc.
- * Copyright (C) 2008 Jonathan Cameron
- *
- * Licensed under the GPL-2.
- *
- * ad7887_ring.c
- */
-
-#include <linux/interrupt.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 "ad7887.h"
-
-/**
- * ad7887_ring_preenable() setup the parameters of the ring before enabling
- *
- * The complex nature of the setting of the nuber of bytes per datum is due
- * to this driver currently ensuring that the timestamp is stored at an 8
- * byte boundary.
- **/
-static int ad7887_ring_preenable(struct iio_dev *indio_dev)
-{
- struct ad7887_state *st = iio_priv(indio_dev);
- int ret;
-
- ret = iio_sw_buffer_preenable(indio_dev);
- if (ret < 0)
- return ret;
-
- /* We know this is a single long so can 'cheat' */
- switch (*indio_dev->active_scan_mask) {
- case (1 << 0):
- st->ring_msg = &st->msg[AD7887_CH0];
- break;
- case (1 << 1):
- st->ring_msg = &st->msg[AD7887_CH1];
- /* Dummy read: push CH1 setting down to hardware */
- spi_sync(st->spi, st->ring_msg);
- break;
- case ((1 << 1) | (1 << 0)):
- st->ring_msg = &st->msg[AD7887_CH0_CH1];
- break;
- }
-
- return 0;
-}
-
-static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
-{
- struct ad7887_state *st = iio_priv(indio_dev);
-
- /* dummy read: restore default CH0 settin */
- return spi_sync(st->spi, &st->msg[AD7887_CH0]);
-}
-
-/**
- * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- **/
-static irqreturn_t ad7887_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct ad7887_state *st = iio_priv(indio_dev);
- s64 time_ns;
- int b_sent;
-
- b_sent = spi_sync(st->spi, st->ring_msg);
- if (b_sent)
- goto done;
-
- time_ns = iio_get_time_ns();
-
- if (indio_dev->scan_timestamp)
- memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
- &time_ns, sizeof(time_ns));
-
- iio_push_to_buffer(indio_dev->buffer, st->data);
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
- .preenable = &ad7887_ring_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
- .postdisable = &ad7887_ring_postdisable,
-};
-
-int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
- &ad7887_trigger_handler, &ad7887_ring_setup_ops);
-}
-
-void ad7887_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/7] staging:iio:ad7887: Use proper kernel doc
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 2/7] staging:iio:ad7887: Rework regulator handling Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 3/7] staging:iio:ad7887: Squash everything into one file Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 5/7] staging:iio:ad7887: Allow to use internal ref in two channel mode Lars-Peter Clausen
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
Use proper kernel doc to document the platform data struct.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/staging/iio/adc/ad7887.h | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index b9078fc..78b06a3 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -12,21 +12,20 @@
* TODO: struct ad7887_platform_data needs to go into include/linux/iio
*/
+
+/**
+ * struct ad7887_platform_data - AD7887 ADC driver platform data
+ * @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the
+ * second input channel, and Vref is internally connected to Vdd. If set to
+ * false the device is used in single channel mode and AIN1/Vref is used as
+ * VREF input.
+ * @use_onchip_ref: Whether to use the onchip reference. If set to true the
+ * internal 2.5V reference is used. If set to false a external reference is
+ * used.
+ */
struct ad7887_platform_data {
- /*
- * AD7887:
- * In single channel mode en_dual = flase, AIN1/Vref pins assumes its
- * Vref function. In dual channel mode en_dual = true, AIN1 becomes the
- * second input channel, and Vref is internally connected to Vdd.
- */
- bool en_dual;
- /*
- * AD7887:
- * use_onchip_ref = true, the Vref is internally connected to the 2.500V
- * Voltage reference. If use_onchip_ref = false, the reference voltage
- * is supplied by AIN1/Vref
- */
- bool use_onchip_ref;
+ bool en_dual;
+ bool use_onchip_ref;
};
#endif /* IIO_ADC_AD7887_H_ */
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 5/7] staging:iio:ad7887: Allow to use internal ref in two channel mode
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
` (2 preceding siblings ...)
2012-11-05 9:56 ` [PATCH 4/7] staging:iio:ad7887: Use proper kernel doc Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 6/7] staging:iio:ad7887: Use passed in chan spec in ad7887_read_raw Lars-Peter Clausen
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
While it is not recommended to use the internal reference in two channel mode in
order to obtain optimal performance it is still possible to use it.
While we are at it also get rid of the duplicate tx_cmd_buf entries. There are
only two unique entries. One for channel 1 and one for channel 2.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/staging/iio/adc/ad7887.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c
index 88ffc46..3ac0c30 100644
--- a/drivers/staging/iio/adc/ad7887.c
+++ b/drivers/staging/iio/adc/ad7887.c
@@ -59,7 +59,7 @@ struct ad7887_state {
struct spi_transfer xfer[4];
struct spi_message msg[3];
struct spi_message *ring_msg;
- unsigned char tx_cmd_buf[8];
+ unsigned char tx_cmd_buf[4];
/*
* DMA (thus cache coherency maintenance) requires the
@@ -238,6 +238,7 @@ static int __devinit ad7887_probe(struct spi_device *spi)
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ uint8_t mode;
int ret;
if (indio_dev == NULL)
@@ -271,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi)
/* Setup default message */
- st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 |
- ((pdata && pdata->use_onchip_ref) ?
- 0 : AD7887_REF_DIS);
+ mode = AD7887_PM_MODE4;
+ if (!pdata || !pdata->use_onchip_ref)
+ mode |= AD7887_REF_DIS;
+ if (pdata && pdata->en_dual)
+ mode |= AD7887_DUAL;
+
+ st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode;
st->xfer[0].rx_buf = &st->data[0];
st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
@@ -283,29 +288,22 @@ static int __devinit ad7887_probe(struct spi_device *spi)
spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
if (pdata && pdata->en_dual) {
- st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS;
-
- st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
- st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
- st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL |
- AD7887_REF_DIS | AD7887_PM_MODE4;
+ st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode;
st->xfer[1].rx_buf = &st->data[0];
st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
st->xfer[1].len = 2;
st->xfer[2].rx_buf = &st->data[2];
- st->xfer[2].tx_buf = &st->tx_cmd_buf[4];
+ st->xfer[2].tx_buf = &st->tx_cmd_buf[0];
st->xfer[2].len = 2;
spi_message_init(&st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
- st->xfer[3].rx_buf = &st->data[0];
- st->xfer[3].tx_buf = &st->tx_cmd_buf[6];
+ st->xfer[3].rx_buf = &st->data[2];
+ st->xfer[3].tx_buf = &st->tx_cmd_buf[2];
st->xfer[3].len = 2;
spi_message_init(&st->msg[AD7887_CH1]);
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 6/7] staging:iio:ad7887: Use passed in chan spec in ad7887_read_raw
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
` (3 preceding siblings ...)
2012-11-05 9:56 ` [PATCH 5/7] staging:iio:ad7887: Allow to use internal ref in two channel mode Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-05 9:56 ` [PATCH 7/7] staging:iio: Move the ad7887 driver out of staging Lars-Peter Clausen
2012-11-10 10:07 ` [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
Use the passed in chan spec in ad7887_read_raw instead of alawys using the first
chan spec entry from the chip info data. Since all channels have the same shift
and realbits from a functional point of view it does not matter which chan spec
is used, but the patch makes the a bit more clear.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/staging/iio/adc/ad7887.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c
index 3ac0c30..72cfe19 100644
--- a/drivers/staging/iio/adc/ad7887.c
+++ b/drivers/staging/iio/adc/ad7887.c
@@ -177,8 +177,8 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
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);
+ *val = ret >> chan->scan_type.shift;
+ *val &= RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (st->reg) {
@@ -190,7 +190,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
*val = st->chip_info->int_vref_mv;
}
- *val2 = st->chip_info->channel[0].scan_type.realbits;
+ *val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
}
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 7/7] staging:iio: Move the ad7887 driver out of staging
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
` (4 preceding siblings ...)
2012-11-05 9:56 ` [PATCH 6/7] staging:iio:ad7887: Use passed in chan spec in ad7887_read_raw Lars-Peter Clausen
@ 2012-11-05 9:56 ` Lars-Peter Clausen
2012-11-10 10:07 ` [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Lars-Peter Clausen @ 2012-11-05 9:56 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, drivers, Lars-Peter Clausen
The driver does not expose any custom API to userspace and none of the standard
static code checker tools report any issues, so move it out of staging.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
drivers/iio/adc/Kconfig | 13 +++++++++++++
drivers/iio/adc/Makefile | 1 +
drivers/{staging => }/iio/adc/ad7887.c | 2 +-
drivers/staging/iio/adc/Kconfig | 13 -------------
drivers/staging/iio/adc/Makefile | 2 --
.../iio/adc => include/linux/platform_data}/ad7887.h | 5 -----
6 files changed, 15 insertions(+), 21 deletions(-)
rename drivers/{staging => }/iio/adc/ad7887.c (99%)
rename {drivers/staging/iio/adc => include/linux/platform_data}/ad7887.h (90%)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 4927581..706386b 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -45,6 +45,19 @@ config AD7476
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
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Analog Devices
+ AD7887 SPI analog to digital converter (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 ad7887.
+
config AT91_ADC
tristate "Atmel AT91 ADC"
depends on ARCH_AT91
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 900995d..034eacb 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o
+obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
similarity index 99%
rename from drivers/staging/iio/adc/ad7887.c
rename to drivers/iio/adc/ad7887.c
index 72cfe19..fd62309 100644
--- a/drivers/staging/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -23,7 +23,7 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
-#include "ad7887.h"
+#include <linux/platform_data/ad7887.h>
#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
#define AD7887_DUAL (1 << 4) /* dual-channel mode */
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 71a515d..eba64fb 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -68,19 +68,6 @@ config AD799X_RING_BUFFER
Say yes here to include ring buffer support in the AD799X
ADC driver.
-config AD7887
- tristate "Analog Devices AD7887 ADC driver"
- depends on SPI
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to build support for Analog Devices
- AD7887 SPI analog to digital converter (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 ad7887.
-
config AD7780
tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 8036fd1..c56b41e 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o
ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
obj-$(CONFIG_AD799X) += ad799x.o
-obj-$(CONFIG_AD7887) += ad7887.o
-
ad7298-y := ad7298_core.o
ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o
obj-$(CONFIG_AD7298) += ad7298.o
diff --git a/drivers/staging/iio/adc/ad7887.h b/include/linux/platform_data/ad7887.h
similarity index 90%
rename from drivers/staging/iio/adc/ad7887.h
rename to include/linux/platform_data/ad7887.h
index 78b06a3..dedb9735 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/include/linux/platform_data/ad7887.h
@@ -8,11 +8,6 @@
#ifndef IIO_ADC_AD7887_H_
#define IIO_ADC_AD7887_H_
-/*
- * TODO: struct ad7887_platform_data needs to go into include/linux/iio
- */
-
-
/**
* struct ad7887_platform_data - AD7887 ADC driver platform data
* @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the
--
1.8.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer
2012-11-05 9:56 [PATCH 1/7] staging:iio:ad7887: Preallocate sample buffer Lars-Peter Clausen
` (5 preceding siblings ...)
2012-11-05 9:56 ` [PATCH 7/7] staging:iio: Move the ad7887 driver out of staging Lars-Peter Clausen
@ 2012-11-10 10:07 ` Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2012-11-10 10:07 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: Jonathan Cameron, linux-iio, drivers
On 11/05/2012 09:56 AM, Lars-Peter Clausen wrote:
> We know that the sample buffer will at most need to hold two 16 bit samples and
> the 64 bit aligned 64 bit timestamp. Preallocate a buffer large enough to hold
> this instead of allocating and freeing it each time a sample is read.
>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
All 7 applied to togreg branch.
A nice series and good to get this one out of staging as it's
been pretty much clean for an awful long time!
Jonathan
p.s. I thought I had sent this the other day but it appears not!
> ---
> drivers/staging/iio/adc/ad7887.h | 6 ++++--
> drivers/staging/iio/adc/ad7887_ring.c | 15 ++-------------
> 2 files changed, 6 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
> index 2e09e54..71e5092 100644
> --- a/drivers/staging/iio/adc/ad7887.h
> +++ b/drivers/staging/iio/adc/ad7887.h
> @@ -72,9 +72,11 @@ struct ad7887_state {
> /*
> * DMA (thus cache coherency maintenance) requires the
> * transfer buffers to live in their own cache lines.
> + * Buffer needs to be large enough to hold two 16 bit samples and a
> + * 64 bit aligned 64 bit timestamp.
> */
> -
> - unsigned char data[4] ____cacheline_aligned;
> + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
> + ____cacheline_aligned;
> };
>
> enum ad7887_supported_device_ids {
> diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
> index b39923b..f11925e 100644
> --- a/drivers/staging/iio/adc/ad7887_ring.c
> +++ b/drivers/staging/iio/adc/ad7887_ring.c
> @@ -73,31 +73,20 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
> struct iio_dev *indio_dev = pf->indio_dev;
> struct ad7887_state *st = iio_priv(indio_dev);
> s64 time_ns;
> - __u8 *buf;
> int b_sent;
>
> - unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
> - indio_dev->masklength) *
> - st->chip_info->channel[0].scan_type.storagebits / 8;
> -
> - buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
> - if (buf == NULL)
> - goto done;
> -
> b_sent = spi_sync(st->spi, st->ring_msg);
> if (b_sent)
> goto done;
>
> time_ns = iio_get_time_ns();
>
> - memcpy(buf, st->data, bytes);
> if (indio_dev->scan_timestamp)
> - memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
> + memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
> &time_ns, sizeof(time_ns));
>
> - iio_push_to_buffer(indio_dev->buffer, buf);
> + iio_push_to_buffer(indio_dev->buffer, st->data);
> done:
> - kfree(buf);
> iio_trigger_notify_done(indio_dev->trig);
>
> return IRQ_HANDLED;
>
^ permalink raw reply [flat|nested] 8+ messages in thread