staging:iio: Move adis library out of staging
authorLars-Peter Clausen <lars@metafoo.de>
Tue, 13 Nov 2012 13:28:00 +0000 (13:28 +0000)
committerJonathan Cameron <jic23@kernel.org>
Mon, 19 Nov 2012 22:22:12 +0000 (22:22 +0000)
Now that the adis library no longer depends on the sw_ring buffer implementation
we can move it out of staging.

While we are at it also sort the entries in the iio Kconfig and Makefile to be
in alphabetical order.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
21 files changed:
drivers/iio/Kconfig
drivers/iio/Makefile
drivers/iio/imu/Kconfig [new file with mode: 0644]
drivers/iio/imu/Makefile [new file with mode: 0644]
drivers/iio/imu/adis.c [new file with mode: 0644]
drivers/iio/imu/adis_buffer.c [new file with mode: 0644]
drivers/iio/imu/adis_trigger.c [new file with mode: 0644]
drivers/staging/iio/accel/adis16201_core.c
drivers/staging/iio/accel/adis16203_core.c
drivers/staging/iio/accel/adis16204_core.c
drivers/staging/iio/accel/adis16209_core.c
drivers/staging/iio/accel/adis16220.h
drivers/staging/iio/accel/adis16240_core.c
drivers/staging/iio/gyro/adis16260.h
drivers/staging/iio/imu/Kconfig
drivers/staging/iio/imu/Makefile
drivers/staging/iio/imu/adis.c [deleted file]
drivers/staging/iio/imu/adis.h [deleted file]
drivers/staging/iio/imu/adis_buffer.c [deleted file]
drivers/staging/iio/imu/adis_trigger.c [deleted file]
include/linux/iio/imu/adis.h [new file with mode: 0644]

index 65ae734c607d0fdd162d39db0784d19f70f3902b..b2f963be39937d2f6fe0775f5c9510866e69f4ea 100644 (file)
@@ -63,11 +63,12 @@ config IIO_CONSUMERS_PER_TRIGGER
 source "drivers/iio/accel/Kconfig"
 source "drivers/iio/adc/Kconfig"
 source "drivers/iio/amplifiers/Kconfig"
-source "drivers/iio/light/Kconfig"
-source "drivers/iio/frequency/Kconfig"
-source "drivers/iio/dac/Kconfig"
 source "drivers/iio/common/Kconfig"
+source "drivers/iio/dac/Kconfig"
+source "drivers/iio/frequency/Kconfig"
 source "drivers/iio/gyro/Kconfig"
+source "drivers/iio/imu/Kconfig"
+source "drivers/iio/light/Kconfig"
 source "drivers/iio/magnetometer/Kconfig"
 
 endif # IIO
index 31d76a07ec65056afc59483ae19ee7001423b6c8..a0e8cdd67e4ddef91083600d1ea80b7e1ea069dd 100644 (file)
@@ -14,9 +14,10 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
 obj-y += accel/
 obj-y += adc/
 obj-y += amplifiers/
-obj-y += light/
-obj-y += frequency/
-obj-y += dac/
 obj-y += common/
+obj-y += dac/
 obj-y += gyro/
+obj-y += frequency/
+obj-y += imu/
+obj-y += light/
 obj-y += magnetometer/
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
new file mode 100644 (file)
index 0000000..c24410c
--- /dev/null
@@ -0,0 +1,11 @@
+config IIO_ADIS_LIB
+       tristate
+       help
+         A set of IO helper functions for the Analog Devices ADIS* device family.
+
+config IIO_ADIS_LIB_BUFFER
+       bool
+       select IIO_TRIGGERED_BUFFER
+       help
+         A set of buffer helper functions for the Analog Devices ADIS* device
+         family.
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
new file mode 100644 (file)
index 0000000..97676ab
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for Inertial Measurement Units
+#
+
+adis_lib-y += adis.o
+adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
+adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
new file mode 100644 (file)
index 0000000..8259b77
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *   Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <asm/unaligned.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
+
+#define ADIS_MSC_CTRL_DATA_RDY_EN      BIT(2)
+#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH        BIT(1)
+#define ADIS_MSC_CTRL_DATA_RDY_DIO2    BIT(0)
+#define ADIS_GLOB_CMD_SW_RESET         BIT(7)
+
+/**
+ * adis_write_reg_8() - Write single byte to a register
+ * @adis: The adis device
+ * @reg: The address of the register to be written
+ * @val: The value to write
+ */
+int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val)
+{
+       int ret;
+
+       mutex_lock(&adis->txrx_lock);
+       adis->tx[0] = ADIS_WRITE_REG(reg);
+       adis->tx[1] = val;
+
+       ret = spi_write(adis->spi, adis->tx, 2);
+       mutex_unlock(&adis->txrx_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_write_reg_8);
+
+/**
+ * adis_write_reg_16() - Write 2 bytes to a pair of registers
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: Value to be written
+ */
+int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value)
+{
+       int ret;
+       struct spi_message msg;
+       struct spi_transfer xfers[] = {
+               {
+                       .tx_buf = adis->tx,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .cs_change = 1,
+                       .delay_usecs = adis->data->write_delay,
+               }, {
+                       .tx_buf = adis->tx + 2,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .delay_usecs = adis->data->write_delay,
+               },
+       };
+
+       mutex_lock(&adis->txrx_lock);
+       adis->tx[0] = ADIS_WRITE_REG(reg);
+       adis->tx[1] = value & 0xff;
+       adis->tx[2] = ADIS_WRITE_REG(reg + 1);
+       adis->tx[3] = (value >> 8) & 0xff;
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfers[0], &msg);
+       spi_message_add_tail(&xfers[1], &msg);
+       ret = spi_sync(adis->spi, &msg);
+       mutex_unlock(&adis->txrx_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_write_reg_16);
+
+/**
+ * adis_read_reg_16() - read 2 bytes from a 16-bit register
+ * @adis: The adis device
+ * @reg: The address of the lower of the two registers
+ * @val: The value read back from the device
+ */
+int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val)
+{
+       struct spi_message msg;
+       int ret;
+       struct spi_transfer xfers[] = {
+               {
+                       .tx_buf = adis->tx,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .cs_change = 1,
+                       .delay_usecs = adis->data->read_delay,
+               }, {
+                       .rx_buf = adis->rx,
+                       .bits_per_word = 8,
+                       .len = 2,
+                       .delay_usecs = adis->data->read_delay,
+               },
+       };
+
+       mutex_lock(&adis->txrx_lock);
+       adis->tx[0] = ADIS_READ_REG(reg);
+       adis->tx[1] = 0;
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfers[0], &msg);
+       spi_message_add_tail(&xfers[1], &msg);
+       ret = spi_sync(adis->spi, &msg);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n",
+                               reg, ret);
+               goto error_ret;
+       }
+       *val = get_unaligned_be16(adis->rx);
+
+error_ret:
+       mutex_unlock(&adis->txrx_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_read_reg_16);
+
+/**
+ * adis_enable_irq() - Enable or disable data ready IRQ
+ * @adis: The adis device
+ * @enable: Whether to enable the IRQ
+ *
+ * Returns 0 on success, negative error code otherwise
+ */
+int adis_enable_irq(struct adis *adis, bool enable)
+{
+       int ret = 0;
+       uint16_t msc;
+
+       ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+       if (ret)
+               goto error_ret;
+
+       msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
+       msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
+       if (enable)
+               msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
+       else
+               msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
+
+       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+
+error_ret:
+       return ret;
+}
+EXPORT_SYMBOL(adis_enable_irq);
+
+/**
+ * adis_check_status() - Check the device for error conditions
+ * @adis: The adis device
+ *
+ * Returns 0 on success, a negative error code otherwise
+ */
+int adis_check_status(struct adis *adis)
+{
+       uint16_t status;
+       int ret;
+       int i;
+
+       ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
+       if (ret < 0)
+               return ret;
+
+       status &= adis->data->status_error_mask;
+
+       if (status == 0)
+               return 0;
+
+       for (i = 0; i < 16; ++i) {
+               if (status & BIT(i)) {
+                       dev_err(&adis->spi->dev, "%s.\n",
+                               adis->data->status_error_msgs[i]);
+               }
+       }
+
+       return -EIO;
+}
+EXPORT_SYMBOL_GPL(adis_check_status);
+
+/**
+ * adis_reset() - Reset the device
+ * @adis: The adis device
+ *
+ * Returns 0 on success, a negative error code otherwise
+ */
+int adis_reset(struct adis *adis)
+{
+       int ret;
+
+       ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
+                       ADIS_GLOB_CMD_SW_RESET);
+       if (ret)
+               dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_reset);
+
+static int adis_self_test(struct adis *adis)
+{
+       int ret;
+
+       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
+                       adis->data->self_test_mask);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
+                       ret);
+               return ret;
+       }
+
+       msleep(adis->data->startup_delay);
+
+       return adis_check_status(adis);
+}
+
+/**
+ * adis_inital_startup() - Performs device self-test
+ * @adis: The adis device
+ *
+ * Returns 0 if the device is operational, a negative error code otherwise.
+ *
+ * This function should be called early on in the device initialization sequence
+ * to ensure that the device is in a sane and known state and that it is usable.
+ */
+int adis_initial_startup(struct adis *adis)
+{
+       int ret;
+
+       ret = adis_self_test(adis);
+       if (ret) {
+               dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
+               adis_reset(adis);
+               msleep(adis->data->startup_delay);
+               ret = adis_self_test(adis);
+               if (ret) {
+                       dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(adis_initial_startup);
+
+/**
+ * adis_single_conversion() - Performs a single sample conversion
+ * @indio_dev: The IIO device
+ * @chan: The IIO channel
+ * @error_mask: Mask for the error bit
+ * @val: Result of the conversion
+ *
+ * Returns IIO_VAL_INT on success, a negative error code otherwise.
+ *
+ * The function performs a single conversion on a given channel and post
+ * processes the value accordingly to the channel spec. If a error_mask is given
+ * the function will check if the mask is set in the returned raw value. If it
+ * is set the function will perform a self-check. If the device does not report
+ * a error bit in the channels raw value set error_mask to 0.
+ */
+int adis_single_conversion(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
+{
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       uint16_t val16;
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+
+       ret = adis_read_reg_16(adis, chan->address, &val16);
+       if (ret)
+               goto err_unlock;
+
+       if (val16 & error_mask) {
+               ret = adis_check_status(adis);
+               if (ret)
+                       goto err_unlock;
+       }
+
+       if (chan->scan_type.sign == 's')
+               *val = sign_extend32(val16, chan->scan_type.realbits - 1);
+       else
+               *val = val16 & ((1 << chan->scan_type.realbits) - 1);
+
+       ret = IIO_VAL_INT;
+err_unlock:
+       mutex_unlock(&indio_dev->mlock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_single_conversion);
+
+/**
+ * adis_init() - Initialize adis device structure
+ * @adis:      The adis device
+ * @indio_dev: The iio device
+ * @spi:       The spi device
+ * @data:      Chip specific data
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function must be called, before any other adis helper function may be
+ * called.
+ */
+int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+       struct spi_device *spi, const struct adis_data *data)
+{
+       mutex_init(&adis->txrx_lock);
+       adis->spi = spi;
+       adis->data = data;
+       iio_device_set_drvdata(indio_dev, adis);
+
+       return adis_enable_irq(adis, false);
+}
+EXPORT_SYMBOL_GPL(adis_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");
diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c
new file mode 100644 (file)
index 0000000..a91b4cb
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *   Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/imu/adis.h>
+
+int adis_update_scan_mode(struct iio_dev *indio_dev,
+       const unsigned long *scan_mask)
+{
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       const struct iio_chan_spec *chan;
+       unsigned int scan_count;
+       unsigned int i, j;
+       __be16 *tx, *rx;
+
+       kfree(adis->xfer);
+       kfree(adis->buffer);
+
+       scan_count = indio_dev->scan_bytes / 2;
+
+       adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL);
+       if (!adis->xfer)
+               return -ENOMEM;
+
+       adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL);
+       if (!adis->buffer)
+               return -ENOMEM;
+
+       rx = adis->buffer;
+       tx = rx + indio_dev->scan_bytes;
+
+       spi_message_init(&adis->msg);
+
+       for (j = 0; j <= scan_count; j++) {
+               adis->xfer[j].bits_per_word = 8;
+               if (j != scan_count)
+                       adis->xfer[j].cs_change = 1;
+               adis->xfer[j].len = 2;
+               adis->xfer[j].delay_usecs = adis->data->read_delay;
+               if (j < scan_count)
+                       adis->xfer[j].tx_buf = &tx[j];
+               if (j >= 1)
+                       adis->xfer[j].rx_buf = &rx[j - 1];
+               spi_message_add_tail(&adis->xfer[j], &adis->msg);
+       }
+
+       chan = indio_dev->channels;
+       for (i = 0; i < indio_dev->num_channels; i++, chan++) {
+               if (!test_bit(chan->scan_index, scan_mask))
+                       continue;
+               *tx++ = cpu_to_be16(chan->address << 8);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(adis_update_scan_mode);
+
+static irqreturn_t adis_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct adis *adis = iio_device_get_drvdata(indio_dev);
+       int ret;
+
+       if (!adis->buffer)
+               return -ENOMEM;
+
+       ret = spi_sync(adis->spi, &adis->msg);
+       if (ret)
+               dev_err(&adis->spi->dev, "Failed to read data: %d", ret);
+
+       /* Guaranteed to be aligned with 8 byte boundary */
+       if (indio_dev->scan_timestamp) {
+               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
+               *(s64 *)b = pf->timestamp;
+       }
+
+       iio_push_to_buffers(indio_dev, adis->buffer);
+
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
+ * @adis: The adis device.
+ * @indio_dev: The IIO device.
+ * @trigger_handler: Optional trigger handler, may be NULL.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function sets up the buffer and trigger for a adis devices.  If
+ * 'trigger_handler' is NULL the default trigger handler will be used. The
+ * default trigger handler will simply read the registers assigned to the
+ * currently active channels.
+ *
+ * adis_cleanup_buffer_and_trigger() should be called to free the resources
+ * allocated by this function.
+ */
+int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
+       irqreturn_t (*trigger_handler)(int, void *))
+{
+       int ret;
+
+       if (!trigger_handler)
+               trigger_handler = adis_trigger_handler;
+
+       ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+               trigger_handler, NULL);
+       if (ret)
+               return ret;
+
+       if (adis->spi->irq) {
+               ret = adis_probe_trigger(adis, indio_dev);
+               if (ret)
+                       goto error_buffer_cleanup;
+       }
+       return 0;
+
+error_buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
+
+/**
+ * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
+ * @adis: The adis device.
+ * @indio_dev: The IIO device.
+ *
+ * Frees resources allocated by adis_setup_buffer_and_trigger()
+ */
+void adis_cleanup_buffer_and_trigger(struct adis *adis,
+       struct iio_dev *indio_dev)
+{
+       if (adis->spi->irq)
+               adis_remove_trigger(adis);
+       kfree(adis->buffer);
+       kfree(adis->xfer);
+       iio_triggered_buffer_cleanup(indio_dev);
+}
+EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
new file mode 100644 (file)
index 0000000..5a24c9c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *   Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/export.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/imu/adis.h>
+
+static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
+                                               bool state)
+{
+       struct adis *adis = trig->private_data;
+
+       return adis_enable_irq(adis, state);
+}
+
+static const struct iio_trigger_ops adis_trigger_ops = {
+       .owner = THIS_MODULE,
+       .set_trigger_state = &adis_data_rdy_trigger_set_state,
+};
+
+/**
+ * adis_probe_trigger() - Sets up trigger for a adis device
+ * @adis: The adis device
+ * @indio_dev: The IIO device
+ *
+ * Returns 0 on success or a negative error code
+ *
+ * adis_remove_trigger() should be used to free the trigger.
+ */
+int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
+{
+       int ret;
+
+       adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+                                       indio_dev->id);
+       if (adis->trig == NULL)
+               return -ENOMEM;
+
+       ret = request_irq(adis->spi->irq,
+                         &iio_trigger_generic_data_rdy_poll,
+                         IRQF_TRIGGER_RISING,
+                         indio_dev->name,
+                         adis->trig);
+       if (ret)
+               goto error_free_trig;
+
+       adis->trig->dev.parent = &adis->spi->dev;
+       adis->trig->ops = &adis_trigger_ops;
+       adis->trig->private_data = adis;
+       ret = iio_trigger_register(adis->trig);
+
+       indio_dev->trig = adis->trig;
+       if (ret)
+               goto error_free_irq;
+
+       return 0;
+
+error_free_irq:
+       free_irq(adis->spi->irq, adis->trig);
+error_free_trig:
+       iio_trigger_free(adis->trig);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adis_probe_trigger);
+
+/**
+ * adis_remove_trigger() - Remove trigger for a adis devices
+ * @adis: The adis device
+ *
+ * Removes the trigger previously registered with adis_probe_trigger().
+ */
+void adis_remove_trigger(struct adis *adis)
+{
+       iio_trigger_unregister(adis->trig);
+       free_irq(adis->spi->irq, adis->trig);
+       iio_trigger_free(adis->trig);
+}
+EXPORT_SYMBOL_GPL(adis_remove_trigger);
index 833dd6b73bc3d6a79dd17db56891c5c85ec412e5..ccdc8d23f6a383a336613cdc15091263e7bb4470 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
 
 #include "adis16201.h"
-#include "../imu/adis.h"
 
 static const u8 adis16201_addresses[] = {
        [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS,
index f631e578fbd104ee24cf3059985e083f8ffb0a31..202985ea3531ffe99a2cc739f7a39182cf5cf37e 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
 
 #include "adis16203.h"
-#include "../imu/adis.h"
 
 #define DRIVER_NAME            "adis16203"
 
index dbec841ce30c4fcdf2cd44d4c6c97bad220bc950..6dafad67cd239da86c0a5321bcb625a041817916 100644 (file)
@@ -21,9 +21,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
 
 #include "adis16204.h"
-#include "../imu/adis.h"
 
 /* Unique to this driver currently */
 
index f9f9d582b32d90d73298733833c3b775733da9a5..d2921c30a8bb1f9f05dc02352de9a5c13fff3984 100644 (file)
@@ -19,9 +19,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
 
 #include "adis16209.h"
-#include "../imu/adis.h"
 
 static const u8 adis16209_addresses[8][1] = {
        [ADIS16209_SCAN_SUPPLY] = { },
index 7cc4d2f3ec28264a62839c15a333d47c6ec34741..a894ad7fb26dc7d21ad6278969855f9ec19028ad 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPI_ADIS16220_H_
 #define SPI_ADIS16220_H_
 
-#include "../imu/adis.h"
+#include <linux/iio/imu/adis.h>
 
 #define ADIS16220_STARTUP_DELAY        220 /* ms */
 
index 3d1a8a9921ad9d6b28db046aa4110ac1734a75ad..d098b49cc18b99ecc163486b871e14d94097ca32 100644 (file)
@@ -22,9 +22,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
 
 #include "adis16240.h"
-#include "../imu/adis.h"
 
 static ssize_t adis16240_spi_read_signed(struct device *dev,
                struct device_attribute *attr,
index ea5eba205bbfcba7cfddec3cf77a15a4df7eea76..df3c0b7e954a79c7b7616203eb60f2fd8b55013d 100644 (file)
@@ -2,7 +2,7 @@
 #define SPI_ADIS16260_H_
 
 #include "adis16260_platform_data.h"
-#include "../imu/adis.h"
+#include <linux/iio/imu/adis.h>
 
 #define ADIS16260_STARTUP_DELAY        220 /* ms */
 
index 2c564edeb1720c54420cd6ef462376115f18b70c..2c2f47de2630e1a0b8ded69801282e5f3dbb685e 100644 (file)
@@ -15,15 +15,3 @@ config ADIS16400
          (adis16400 series also have magnetometers).
 
 endmenu
-
-config IIO_ADIS_LIB
-       tristate
-       help
-         A set of IO helper functions for the Analog Devices ADIS* device family.
-
-config IIO_ADIS_LIB_BUFFER
-       bool
-       select IIO_TRIGGERED_BUFFER
-       help
-         A set of buffer helper functions for the Analog Devices ADIS* device
-         family.
index 65dafba1e5dfc643965fad9597c34f21ac6688cd..3400a13d152246bbaad503ee6cf157ffb4468e99 100644 (file)
@@ -5,8 +5,3 @@
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o adis16400_trigger.o
 obj-$(CONFIG_ADIS16400) += adis16400.o
-
-adis_lib-y += adis.o
-adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
-adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
-obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
diff --git a/drivers/staging/iio/imu/adis.c b/drivers/staging/iio/imu/adis.c
deleted file mode 100644 (file)
index 0bd2102..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Common library for ADIS16XXX devices
- *
- * Copyright 2012 Analog Devices Inc.
- *   Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/module.h>
-#include <asm/unaligned.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-
-#include "adis.h"
-
-#define ADIS_MSC_CTRL_DATA_RDY_EN      BIT(2)
-#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH        BIT(1)
-#define ADIS_MSC_CTRL_DATA_RDY_DIO2    BIT(0)
-#define ADIS_GLOB_CMD_SW_RESET         BIT(7)
-
-/**
- * adis_write_reg_8() - Write single byte to a register
- * @adis: The adis device
- * @reg: The address of the register to be written
- * @val: The value to write
- */
-int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val)
-{
-       int ret;
-
-       mutex_lock(&adis->txrx_lock);
-       adis->tx[0] = ADIS_WRITE_REG(reg);
-       adis->tx[1] = val;
-
-       ret = spi_write(adis->spi, adis->tx, 2);
-       mutex_unlock(&adis->txrx_lock);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_write_reg_8);
-
-/**
- * adis_write_reg_16() - Write 2 bytes to a pair of registers
- * @adis: The adis device
- * @reg: The address of the lower of the two registers
- * @val: Value to be written
- */
-int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value)
-{
-       int ret;
-       struct spi_message msg;
-       struct spi_transfer xfers[] = {
-               {
-                       .tx_buf = adis->tx,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .cs_change = 1,
-                       .delay_usecs = adis->data->write_delay,
-               }, {
-                       .tx_buf = adis->tx + 2,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .delay_usecs = adis->data->write_delay,
-               },
-       };
-
-       mutex_lock(&adis->txrx_lock);
-       adis->tx[0] = ADIS_WRITE_REG(reg);
-       adis->tx[1] = value & 0xff;
-       adis->tx[2] = ADIS_WRITE_REG(reg + 1);
-       adis->tx[3] = (value >> 8) & 0xff;
-
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(adis->spi, &msg);
-       mutex_unlock(&adis->txrx_lock);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_write_reg_16);
-
-/**
- * adis_read_reg_16() - read 2 bytes from a 16-bit register
- * @adis: The adis device
- * @reg: The address of the lower of the two registers
- * @val: The value read back from the device
- */
-int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val)
-{
-       struct spi_message msg;
-       int ret;
-       struct spi_transfer xfers[] = {
-               {
-                       .tx_buf = adis->tx,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .cs_change = 1,
-                       .delay_usecs = adis->data->read_delay,
-               }, {
-                       .rx_buf = adis->rx,
-                       .bits_per_word = 8,
-                       .len = 2,
-                       .delay_usecs = adis->data->read_delay,
-               },
-       };
-
-       mutex_lock(&adis->txrx_lock);
-       adis->tx[0] = ADIS_READ_REG(reg);
-       adis->tx[1] = 0;
-
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(adis->spi, &msg);
-       if (ret) {
-               dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n",
-                               reg, ret);
-               goto error_ret;
-       }
-       *val = get_unaligned_be16(adis->rx);
-
-error_ret:
-       mutex_unlock(&adis->txrx_lock);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_read_reg_16);
-
-/**
- * adis_enable_irq() - Enable or disable data ready IRQ
- * @adis: The adis device
- * @enable: Whether to enable the IRQ
- *
- * Returns 0 on success, negative error code otherwise
- */
-int adis_enable_irq(struct adis *adis, bool enable)
-{
-       int ret = 0;
-       uint16_t msc;
-
-       ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
-       if (ret)
-               goto error_ret;
-
-       msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
-       msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
-       if (enable)
-               msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
-       else
-               msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
-
-       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
-
-error_ret:
-       return ret;
-}
-EXPORT_SYMBOL(adis_enable_irq);
-
-/**
- * adis_check_status() - Check the device for error conditions
- * @adis: The adis device
- *
- * Returns 0 on success, a negative error code otherwise
- */
-int adis_check_status(struct adis *adis)
-{
-       uint16_t status;
-       int ret;
-       int i;
-
-       ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
-       if (ret < 0)
-               return ret;
-
-       status &= adis->data->status_error_mask;
-
-       if (status == 0)
-               return 0;
-
-       for (i = 0; i < 16; ++i) {
-               if (status & BIT(i)) {
-                       dev_err(&adis->spi->dev, "%s.\n",
-                               adis->data->status_error_msgs[i]);
-               }
-       }
-
-       return -EIO;
-}
-EXPORT_SYMBOL_GPL(adis_check_status);
-
-/**
- * adis_reset() - Reset the device
- * @adis: The adis device
- *
- * Returns 0 on success, a negative error code otherwise
- */
-int adis_reset(struct adis *adis)
-{
-       int ret;
-
-       ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
-                       ADIS_GLOB_CMD_SW_RESET);
-       if (ret)
-               dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_reset);
-
-static int adis_self_test(struct adis *adis)
-{
-       int ret;
-
-       ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
-                       adis->data->self_test_mask);
-       if (ret) {
-               dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
-                       ret);
-               return ret;
-       }
-
-       msleep(adis->data->startup_delay);
-
-       return adis_check_status(adis);
-}
-
-/**
- * adis_inital_startup() - Performs device self-test
- * @adis: The adis device
- *
- * Returns 0 if the device is operational, a negative error code otherwise.
- *
- * This function should be called early on in the device initialization sequence
- * to ensure that the device is in a sane and known state and that it is usable.
- */
-int adis_initial_startup(struct adis *adis)
-{
-       int ret;
-
-       ret = adis_self_test(adis);
-       if (ret) {
-               dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
-               adis_reset(adis);
-               msleep(adis->data->startup_delay);
-               ret = adis_self_test(adis);
-               if (ret) {
-                       dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(adis_initial_startup);
-
-/**
- * adis_single_conversion() - Performs a single sample conversion
- * @indio_dev: The IIO device
- * @chan: The IIO channel
- * @error_mask: Mask for the error bit
- * @val: Result of the conversion
- *
- * Returns IIO_VAL_INT on success, a negative error code otherwise.
- *
- * The function performs a single conversion on a given channel and post
- * processes the value accordingly to the channel spec. If a error_mask is given
- * the function will check if the mask is set in the returned raw value. If it
- * is set the function will perform a self-check. If the device does not report
- * a error bit in the channels raw value set error_mask to 0.
- */
-int adis_single_conversion(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
-{
-       struct adis *adis = iio_device_get_drvdata(indio_dev);
-       uint16_t val16;
-       int ret;
-
-       mutex_lock(&indio_dev->mlock);
-
-       ret = adis_read_reg_16(adis, chan->address, &val16);
-       if (ret)
-               goto err_unlock;
-
-       if (val16 & error_mask) {
-               ret = adis_check_status(adis);
-               if (ret)
-                       goto err_unlock;
-       }
-
-       if (chan->scan_type.sign == 's')
-               *val = sign_extend32(val16, chan->scan_type.realbits - 1);
-       else
-               *val = val16 & ((1 << chan->scan_type.realbits) - 1);
-
-       ret = IIO_VAL_INT;
-err_unlock:
-       mutex_unlock(&indio_dev->mlock);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_single_conversion);
-
-/**
- * adis_init() - Initialize adis device structure
- * @adis:      The adis device
- * @indio_dev: The iio device
- * @spi:       The spi device
- * @data:      Chip specific data
- *
- * Returns 0 on success, a negative error code otherwise.
- *
- * This function must be called, before any other adis helper function may be
- * called.
- */
-int adis_init(struct adis *adis, struct iio_dev *indio_dev,
-       struct spi_device *spi, const struct adis_data *data)
-{
-       mutex_init(&adis->txrx_lock);
-       adis->spi = spi;
-       adis->data = data;
-       iio_device_set_drvdata(indio_dev, adis);
-
-       return adis_enable_irq(adis, false);
-}
-EXPORT_SYMBOL_GPL(adis_init);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");
diff --git a/drivers/staging/iio/imu/adis.h b/drivers/staging/iio/imu/adis.h
deleted file mode 100644 (file)
index 8c3304d..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Common library for ADIS16XXX devices
- *
- * Copyright 2012 Analog Devices Inc.
- *   Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __IIO_ADIS_H__
-#define __IIO_ADIS_H__
-
-#include <linux/spi/spi.h>
-#include <linux/interrupt.h>
-#include <linux/iio/types.h>
-
-#define ADIS_WRITE_REG(reg) (0x80 | (reg))
-#define ADIS_READ_REG(reg) (reg)
-
-/**
- * struct adis_data - ADIS chip variant specific data
- * @read_delay: SPI delay for read operations in us
- * @write_delay: SPI delay for write operations in us
- * @glob_cmd_reg: Register address of the GLOB_CMD register
- * @msc_ctrl_reg: Register address of the MSC_CTRL register
- * @diag_stat_reg: Register address of the DIAG_STAT register
- * @status_error_msgs: Array of error messgaes
- * @status_error_mask:
- */
-struct adis_data {
-       unsigned int read_delay;
-       unsigned int write_delay;
-
-       unsigned int glob_cmd_reg;
-       unsigned int msc_ctrl_reg;
-       unsigned int diag_stat_reg;
-
-       unsigned int self_test_mask;
-       unsigned int startup_delay;
-
-       const char * const *status_error_msgs;
-       unsigned int status_error_mask;
-};
-
-struct adis {
-       struct spi_device       *spi;
-       struct iio_trigger      *trig;
-
-       const struct adis_data  *data;
-
-       struct mutex            txrx_lock;
-       struct spi_message      msg;
-       struct spi_transfer     *xfer;
-       void                    *buffer;
-
-       uint8_t                 tx[8] ____cacheline_aligned;
-       uint8_t                 rx[4];
-};
-
-int adis_init(struct adis *adis, struct iio_dev *indio_dev,
-       struct spi_device *spi, const struct adis_data *data);
-int adis_reset(struct adis *adis);
-
-int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val);
-int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val);
-int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val);
-
-int adis_enable_irq(struct adis *adis, bool enable);
-int adis_check_status(struct adis *adis);
-
-int adis_initial_startup(struct adis *adis);
-
-int adis_single_conversion(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int error_mask,
-       int *val);
-
-#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .channel = (chan), \
-       .extend_name = name, \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-               IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
-       .address = (addr), \
-       .scan_index = (si), \
-       .scan_type = { \
-               .sign = 'u', \
-               .realbits = (bits), \
-               .storagebits = 16, \
-               .endianness = IIO_BE, \
-       }, \
-}
-
-#define ADIS_SUPPLY_CHAN(addr, si, bits) \
-       ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits)
-
-#define ADIS_AUX_ADC_CHAN(addr, si, bits) \
-       ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits)
-
-#define ADIS_TEMP_CHAN(addr, si, bits) { \
-       .type = IIO_TEMP, \
-       .indexed = 1, \
-       .channel = 0, \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-               IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
-               IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
-       .address = (addr), \
-       .scan_index = (si), \
-       .scan_type = { \
-               .sign = 'u', \
-               .realbits = (bits), \
-               .storagebits = 16, \
-               .endianness = IIO_BE, \
-       }, \
-}
-
-#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \
-       .type = (_type), \
-       .modified = 1, \
-       .channel2 = IIO_MOD_ ## mod, \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-                IIO_CHAN_INFO_SCALE_SHARED_BIT | \
-                info, \
-       .address = (addr), \
-       .scan_index = (si), \
-       .scan_type = { \
-               .sign = 's', \
-               .realbits = (bits), \
-               .storagebits = 16, \
-               .endianness = IIO_BE, \
-       }, \
-}
-
-#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \
-       ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits)
-
-#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \
-       ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits)
-
-#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \
-       ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits)
-
-#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \
-       ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits)
-
-#ifdef CONFIG_IIO_ADIS_LIB_BUFFER
-
-int adis_setup_buffer_and_trigger(struct adis *adis,
-       struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *));
-void adis_cleanup_buffer_and_trigger(struct adis *adis,
-       struct iio_dev *indio_dev);
-
-int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
-void adis_remove_trigger(struct adis *adis);
-
-int adis_update_scan_mode(struct iio_dev *indio_dev,
-       const unsigned long *scan_mask);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline int adis_setup_buffer_and_trigger(struct adis *adis,
-       struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *))
-{
-       return 0;
-}
-
-static inline void adis_cleanup_buffer_and_trigger(struct adis *adis,
-       struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis_probe_trigger(struct adis *adis,
-       struct iio_dev *indio_dev)
-{
-       return 0;
-}
-
-static inline void adis_remove_trigger(struct adis *adis)
-{
-}
-
-#define adis_update_scan_mode NULL
-
-#endif /* CONFIG_IIO_BUFFER */
-
-#endif
diff --git a/drivers/staging/iio/imu/adis_buffer.c b/drivers/staging/iio/imu/adis_buffer.c
deleted file mode 100644 (file)
index 342758c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Common library for ADIS16XXX devices
- *
- * Copyright 2012 Analog Devices Inc.
- *   Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include  "adis.h"
-
-int adis_update_scan_mode(struct iio_dev *indio_dev,
-       const unsigned long *scan_mask)
-{
-       struct adis *adis = iio_device_get_drvdata(indio_dev);
-       const struct iio_chan_spec *chan;
-       unsigned int scan_count;
-       unsigned int i, j;
-       __be16 *tx, *rx;
-
-       kfree(adis->xfer);
-       kfree(adis->buffer);
-
-       scan_count = indio_dev->scan_bytes / 2;
-
-       adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL);
-       if (!adis->xfer)
-               return -ENOMEM;
-
-       adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL);
-       if (!adis->buffer)
-               return -ENOMEM;
-
-       rx = adis->buffer;
-       tx = rx + indio_dev->scan_bytes;
-
-       spi_message_init(&adis->msg);
-
-       for (j = 0; j <= scan_count; j++) {
-               adis->xfer[j].bits_per_word = 8;
-               if (j != scan_count)
-                       adis->xfer[j].cs_change = 1;
-               adis->xfer[j].len = 2;
-               adis->xfer[j].delay_usecs = adis->data->read_delay;
-               if (j < scan_count)
-                       adis->xfer[j].tx_buf = &tx[j];
-               if (j >= 1)
-                       adis->xfer[j].rx_buf = &rx[j - 1];
-               spi_message_add_tail(&adis->xfer[j], &adis->msg);
-       }
-
-       chan = indio_dev->channels;
-       for (i = 0; i < indio_dev->num_channels; i++, chan++) {
-               if (!test_bit(chan->scan_index, scan_mask))
-                       continue;
-               *tx++ = cpu_to_be16(chan->address << 8);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(adis_update_scan_mode);
-
-static irqreturn_t adis_trigger_handler(int irq, void *p)
-{
-       struct iio_poll_func *pf = p;
-       struct iio_dev *indio_dev = pf->indio_dev;
-       struct adis *adis = iio_device_get_drvdata(indio_dev);
-       int ret;
-
-       if (!adis->buffer)
-               return -ENOMEM;
-
-       ret = spi_sync(adis->spi, &adis->msg);
-       if (ret)
-               dev_err(&adis->spi->dev, "Failed to read data: %d", ret);
-
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp) {
-               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
-               *(s64 *)b = pf->timestamp;
-       }
-
-       iio_push_to_buffers(indio_dev, adis->buffer);
-
-       iio_trigger_notify_done(indio_dev->trig);
-
-       return IRQ_HANDLED;
-}
-
-/**
- * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
- * @adis: The adis device.
- * @indio_dev: The IIO device.
- * @trigger_handler: Optional trigger handler, may be NULL.
- *
- * Returns 0 on success, a negative error code otherwise.
- *
- * This function sets up the buffer and trigger for a adis devices.  If
- * 'trigger_handler' is NULL the default trigger handler will be used. The
- * default trigger handler will simply read the registers assigned to the
- * currently active channels.
- *
- * adis_cleanup_buffer_and_trigger() should be called to free the resources
- * allocated by this function.
- */
-int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
-       irqreturn_t (*trigger_handler)(int, void *))
-{
-       int ret;
-
-       if (!trigger_handler)
-               trigger_handler = adis_trigger_handler;
-
-       ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
-               trigger_handler, NULL);
-       if (ret)
-               return ret;
-
-       if (adis->spi->irq) {
-               ret = adis_probe_trigger(adis, indio_dev);
-               if (ret)
-                       goto error_buffer_cleanup;
-       }
-       return 0;
-
-error_buffer_cleanup:
-       iio_triggered_buffer_cleanup(indio_dev);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
-
-/**
- * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
- * @adis: The adis device.
- * @indio_dev: The IIO device.
- *
- * Frees resources allocated by adis_setup_buffer_and_trigger()
- */
-void adis_cleanup_buffer_and_trigger(struct adis *adis,
-       struct iio_dev *indio_dev)
-{
-       if (adis->spi->irq)
-               adis_remove_trigger(adis);
-       kfree(adis->buffer);
-       kfree(adis->xfer);
-       iio_triggered_buffer_cleanup(indio_dev);
-}
-EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);
diff --git a/drivers/staging/iio/imu/adis_trigger.c b/drivers/staging/iio/imu/adis_trigger.c
deleted file mode 100644 (file)
index 3e89b2e..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Common library for ADIS16XXX devices
- *
- * Copyright 2012 Analog Devices Inc.
- *   Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-
-#include "adis.h"
-
-static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
-                                               bool state)
-{
-       struct adis *adis = trig->private_data;
-
-       return adis_enable_irq(adis, state);
-}
-
-static const struct iio_trigger_ops adis_trigger_ops = {
-       .owner = THIS_MODULE,
-       .set_trigger_state = &adis_data_rdy_trigger_set_state,
-};
-
-/**
- * adis_probe_trigger() - Sets up trigger for a adis device
- * @adis: The adis device
- * @indio_dev: The IIO device
- *
- * Returns 0 on success or a negative error code
- *
- * adis_remove_trigger() should be used to free the trigger.
- */
-int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
-{
-       int ret;
-
-       adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
-                                       indio_dev->id);
-       if (adis->trig == NULL)
-               return -ENOMEM;
-
-       ret = request_irq(adis->spi->irq,
-                         &iio_trigger_generic_data_rdy_poll,
-                         IRQF_TRIGGER_RISING,
-                         indio_dev->name,
-                         adis->trig);
-       if (ret)
-               goto error_free_trig;
-
-       adis->trig->dev.parent = &adis->spi->dev;
-       adis->trig->ops = &adis_trigger_ops;
-       adis->trig->private_data = adis;
-       ret = iio_trigger_register(adis->trig);
-
-       indio_dev->trig = adis->trig;
-       if (ret)
-               goto error_free_irq;
-
-       return 0;
-
-error_free_irq:
-       free_irq(adis->spi->irq, adis->trig);
-error_free_trig:
-       iio_trigger_free(adis->trig);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(adis_probe_trigger);
-
-/**
- * adis_remove_trigger() - Remove trigger for a adis devices
- * @adis: The adis device
- *
- * Removes the trigger previously registered with adis_probe_trigger().
- */
-void adis_remove_trigger(struct adis *adis)
-{
-       iio_trigger_unregister(adis->trig);
-       free_irq(adis->spi->irq, adis->trig);
-       iio_trigger_free(adis->trig);
-}
-EXPORT_SYMBOL_GPL(adis_remove_trigger);
diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
new file mode 100644 (file)
index 0000000..8c3304d
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Common library for ADIS16XXX devices
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *   Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __IIO_ADIS_H__
+#define __IIO_ADIS_H__
+
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/iio/types.h>
+
+#define ADIS_WRITE_REG(reg) (0x80 | (reg))
+#define ADIS_READ_REG(reg) (reg)
+
+/**
+ * struct adis_data - ADIS chip variant specific data
+ * @read_delay: SPI delay for read operations in us
+ * @write_delay: SPI delay for write operations in us
+ * @glob_cmd_reg: Register address of the GLOB_CMD register
+ * @msc_ctrl_reg: Register address of the MSC_CTRL register
+ * @diag_stat_reg: Register address of the DIAG_STAT register
+ * @status_error_msgs: Array of error messgaes
+ * @status_error_mask:
+ */
+struct adis_data {
+       unsigned int read_delay;
+       unsigned int write_delay;
+
+       unsigned int glob_cmd_reg;
+       unsigned int msc_ctrl_reg;
+       unsigned int diag_stat_reg;
+
+       unsigned int self_test_mask;
+       unsigned int startup_delay;
+
+       const char * const *status_error_msgs;
+       unsigned int status_error_mask;
+};
+
+struct adis {
+       struct spi_device       *spi;
+       struct iio_trigger      *trig;
+
+       const struct adis_data  *data;
+
+       struct mutex            txrx_lock;
+       struct spi_message      msg;
+       struct spi_transfer     *xfer;
+       void                    *buffer;
+
+       uint8_t                 tx[8] ____cacheline_aligned;
+       uint8_t                 rx[4];
+};
+
+int adis_init(struct adis *adis, struct iio_dev *indio_dev,
+       struct spi_device *spi, const struct adis_data *data);
+int adis_reset(struct adis *adis);
+
+int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val);
+int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val);
+int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val);
+
+int adis_enable_irq(struct adis *adis, bool enable);
+int adis_check_status(struct adis *adis);
+
+int adis_initial_startup(struct adis *adis);
+
+int adis_single_conversion(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int error_mask,
+       int *val);
+
+#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .channel = (chan), \
+       .extend_name = name, \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+               IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+       .address = (addr), \
+       .scan_index = (si), \
+       .scan_type = { \
+               .sign = 'u', \
+               .realbits = (bits), \
+               .storagebits = 16, \
+               .endianness = IIO_BE, \
+       }, \
+}
+
+#define ADIS_SUPPLY_CHAN(addr, si, bits) \
+       ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits)
+
+#define ADIS_AUX_ADC_CHAN(addr, si, bits) \
+       ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits)
+
+#define ADIS_TEMP_CHAN(addr, si, bits) { \
+       .type = IIO_TEMP, \
+       .indexed = 1, \
+       .channel = 0, \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+               IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
+               IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
+       .address = (addr), \
+       .scan_index = (si), \
+       .scan_type = { \
+               .sign = 'u', \
+               .realbits = (bits), \
+               .storagebits = 16, \
+               .endianness = IIO_BE, \
+       }, \
+}
+
+#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \
+       .type = (_type), \
+       .modified = 1, \
+       .channel2 = IIO_MOD_ ## mod, \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+                IIO_CHAN_INFO_SCALE_SHARED_BIT | \
+                info, \
+       .address = (addr), \
+       .scan_index = (si), \
+       .scan_type = { \
+               .sign = 's', \
+               .realbits = (bits), \
+               .storagebits = 16, \
+               .endianness = IIO_BE, \
+       }, \
+}
+
+#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \
+       ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits)
+
+#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \
+       ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits)
+
+#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \
+       ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits)
+
+#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \
+       ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits)
+
+#ifdef CONFIG_IIO_ADIS_LIB_BUFFER
+
+int adis_setup_buffer_and_trigger(struct adis *adis,
+       struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *));
+void adis_cleanup_buffer_and_trigger(struct adis *adis,
+       struct iio_dev *indio_dev);
+
+int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
+void adis_remove_trigger(struct adis *adis);
+
+int adis_update_scan_mode(struct iio_dev *indio_dev,
+       const unsigned long *scan_mask);
+
+#else /* CONFIG_IIO_BUFFER */
+
+static inline int adis_setup_buffer_and_trigger(struct adis *adis,
+       struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *))
+{
+       return 0;
+}
+
+static inline void adis_cleanup_buffer_and_trigger(struct adis *adis,
+       struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis_probe_trigger(struct adis *adis,
+       struct iio_dev *indio_dev)
+{
+       return 0;
+}
+
+static inline void adis_remove_trigger(struct adis *adis)
+{
+}
+
+#define adis_update_scan_mode NULL
+
+#endif /* CONFIG_IIO_BUFFER */
+
+#endif