summaryrefslogtreecommitdiff
path: root/drivers/staging/iio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:11:44 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:11:44 (GMT)
commitb5c78e04dd061b776978dad61dd85357081147b0 (patch)
tree2416b2dc61c452c3aeb2a32bcedf15e6257be638 /drivers/staging/iio
parent06991c28f37ad68e5c03777f5c3b679b56e3dac1 (diff)
parent951348b377385475aa256c27e1c9e2564c9ec160 (diff)
downloadlinux-fsl-qoriq-b5c78e04dd061b776978dad61dd85357081147b0.tar.xz
Merge tag 'staging-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree update from Greg Kroah-Hartman: "Here's the big staging tree merge for 3.9-rc1 Lots of cleanups and updates for drivers all through the staging tree. We are pretty much "code neutral" here, adding just about as many lines as we removed. All of these have been in linux-next for a while." * tag 'staging-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (804 commits) staging: comedi: vmk80xx: wait for URBs to complete staging: comedi: drivers: addi-data: hwdrv_apci3200.c: Add a missing semicolon staging: et131x: Update TODO list staging: et131x: Remove assignment of skb->dev staging: wlan-ng: hfa384x.h: fix for error reported by smatch staging/zache checkpatch ERROR: spaces prohibited around that staging/ozwpan: Mark read only parameters and structs as const staging/ozwpan: Remove empty and unused function oz_cdev_heartbeat staging/ozwpan: Mark local functions as static (fix sparse warnings) staging/ozwpan: Add missing header includes staging/usbip: Mark local functions as static (fix sparse warnings) staging/xgifb: Remove duplicated code in loops. staging/xgifb: Consolidate return paths staging/xgifb: Remove code without effect staging/xgifb: Remove unnecessary casts staging/xgifb: Consolidate if/else if with identical code branches staging: vt6656: replaced custom TRUE definition with true staging: vt6656: replaced custom FALSE definition with false staging: vt6656: replace custom BOOL definition with bool staging/rtl8187se: Mark functions as static to silence sparse ...
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Kconfig14
-rw-r--r--drivers/staging/iio/Makefile3
-rw-r--r--drivers/staging/iio/accel/Kconfig30
-rw-r--r--drivers/staging/iio/accel/Makefile2
-rw-r--r--drivers/staging/iio/accel/kxsd9.c291
-rw-r--r--drivers/staging/iio/accel/lis3l02dq.h8
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c18
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c12
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c13
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c6
-rw-r--r--drivers/staging/iio/adc/Kconfig4
-rw-r--r--drivers/staging/iio/adc/ad7280a.c6
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c525
-rw-r--r--drivers/staging/iio/frequency/ad5930.c5
-rw-r--r--drivers/staging/iio/frequency/ad9850.c5
-rw-r--r--drivers/staging/iio/frequency/ad9852.c5
-rw-r--r--drivers/staging/iio/gyro/Kconfig17
-rw-r--r--drivers/staging/iio/gyro/Makefile9
-rw-r--r--drivers/staging/iio/gyro/adis16080_core.c201
-rw-r--r--drivers/staging/iio/gyro/adxrs450.h62
-rw-r--r--drivers/staging/iio/gyro/adxrs450_core.c440
-rw-r--r--drivers/staging/iio/iio_hwmon.c83
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c4
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c2
-rw-r--r--drivers/staging/iio/impedance-analyzer/Kconfig2
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c8
-rw-r--r--drivers/staging/iio/imu/Kconfig17
-rw-r--r--drivers/staging/iio/imu/Makefile7
-rw-r--r--drivers/staging/iio/imu/adis16400.h239
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c1320
-rw-r--r--drivers/staging/iio/imu/adis16400_ring.c204
-rw-r--r--drivers/staging/iio/imu/adis16400_trigger.c74
-rw-r--r--drivers/staging/iio/light/Kconfig10
-rw-r--r--drivers/staging/iio/light/Makefile1
-rw-r--r--drivers/staging/iio/light/tsl2563.c899
-rw-r--r--drivers/staging/iio/light/tsl2563.h9
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c78
-rw-r--r--drivers/staging/iio/meter/Kconfig2
-rw-r--r--drivers/staging/iio/meter/ade7753.c6
-rw-r--r--drivers/staging/iio/meter/ade7754.c5
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c28
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c12
-rw-r--r--drivers/staging/iio/meter/ade7759.c5
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c44
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c5
-rw-r--r--drivers/staging/iio/ring_sw.c366
-rw-r--r--drivers/staging/iio/ring_sw.h30
47 files changed, 588 insertions, 4548 deletions
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index ca56c75..dc26717 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -12,19 +12,6 @@ config IIO_ST_HWMON
map allows IIO devices to provide basic hwmon functionality
for those channels specified in the map.
-if IIO_BUFFER
-
-config IIO_SW_RING
- select IIO_TRIGGER
- tristate "Industrial I/O lock free software ring"
- help
- Example software ring buffer implementation. The design aim
- of this particular realization was to minimize write locking
- with the intention that some devices would be able to write
- in interrupt context.
-
-endif # IIO_BUFFER
-
source "drivers/staging/iio/accel/Kconfig"
source "drivers/staging/iio/adc/Kconfig"
source "drivers/staging/iio/addac/Kconfig"
@@ -32,7 +19,6 @@ source "drivers/staging/iio/cdc/Kconfig"
source "drivers/staging/iio/frequency/Kconfig"
source "drivers/staging/iio/gyro/Kconfig"
source "drivers/staging/iio/impedance-analyzer/Kconfig"
-source "drivers/staging/iio/imu/Kconfig"
source "drivers/staging/iio/light/Kconfig"
source "drivers/staging/iio/magnetometer/Kconfig"
source "drivers/staging/iio/meter/Kconfig"
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index fa6937d..158e0a0 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -2,8 +2,6 @@
# Makefile for the industrial I/O core.
#
-obj-$(CONFIG_IIO_SW_RING) += ring_sw.o
-
obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o
iio_dummy-y := iio_simple_dummy.o
iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o
@@ -20,7 +18,6 @@ obj-y += cdc/
obj-y += frequency/
obj-y += gyro/
obj-y += impedance-analyzer/
-obj-y += imu/
obj-y += light/
obj-y += magnetometer/
obj-y += meter/
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
index 2b54430..e2e786d 100644
--- a/drivers/staging/iio/accel/Kconfig
+++ b/drivers/staging/iio/accel/Kconfig
@@ -56,45 +56,17 @@ config ADIS16240
Say yes here to build support for Analog Devices adis16240 programmable
impact Sensor and recorder.
-config KXSD9
- tristate "Kionix KXSD9 Accelerometer Driver"
- depends on SPI
- help
- Say yes here to build support for the Kionix KXSD9 accelerometer.
- Currently this only supports the device via an SPI interface.
-
config LIS3L02DQ
tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver"
depends on SPI
select IIO_TRIGGER if IIO_BUFFER
- depends on !IIO_BUFFER || IIO_KFIFO_BUF || IIO_SW_RING
+ depends on !IIO_BUFFER || IIO_KFIFO_BUF
depends on GENERIC_GPIO
help
Say yes here to build SPI support for the ST microelectronics
accelerometer. The driver supplies direct access via sysfs files
and an event interface via a character device.
-choice
- prompt "Buffer type"
- depends on LIS3L02DQ && IIO_BUFFER
-
-config LIS3L02DQ_BUF_KFIFO
- depends on IIO_KFIFO_BUF
- bool "Simple FIFO"
- help
- Kfifo based FIFO. Does not provide any events so it is up
- to userspace to ensure it reads often enough that data is not
- lost.
-
-config LIS3L02DQ_BUF_RING_SW
- depends on IIO_SW_RING
- bool "IIO Software Ring"
- help
- Original IIO ring buffer implementation. Provides simple
- buffer events, half full etc.
-
-endchoice
-
config SCA3000
depends on IIO_BUFFER
depends on SPI
diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
index 8e7ee03..1ed137f 100644
--- a/drivers/staging/iio/accel/Makefile
+++ b/drivers/staging/iio/accel/Makefile
@@ -20,8 +20,6 @@ obj-$(CONFIG_ADIS16220) += adis16220.o
adis16240-y := adis16240_core.o
obj-$(CONFIG_ADIS16240) += adis16240.o
-obj-$(CONFIG_KXSD9) += kxsd9.o
-
lis3l02dq-y := lis3l02dq_core.o
lis3l02dq-$(CONFIG_IIO_BUFFER) += lis3l02dq_ring.o
obj-$(CONFIG_LIS3L02DQ) += lis3l02dq.o
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
deleted file mode 100644
index 318331f..0000000
--- a/drivers/staging/iio/accel/kxsd9.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * kxsd9.c simple support for the Kionix KXSD9 3D
- * accelerometer.
- *
- * 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
- * published by the Free Software Foundation.
- *
- * The i2c interface is very similar, so shouldn't be a problem once
- * I have a suitable wire made up.
- *
- * TODO: Support the motion detector
- * Uses register address incrementing so could have a
- * heavily optimized ring buffer access function.
- */
-
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/sysfs.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define KXSD9_REG_X 0x00
-#define KXSD9_REG_Y 0x02
-#define KXSD9_REG_Z 0x04
-#define KXSD9_REG_AUX 0x06
-#define KXSD9_REG_RESET 0x0a
-#define KXSD9_REG_CTRL_C 0x0c
-
-#define KXSD9_FS_MASK 0x03
-
-#define KXSD9_REG_CTRL_B 0x0d
-#define KXSD9_REG_CTRL_A 0x0e
-
-#define KXSD9_READ(a) (0x80 | (a))
-#define KXSD9_WRITE(a) (a)
-
-#define KXSD9_STATE_RX_SIZE 2
-#define KXSD9_STATE_TX_SIZE 2
-/**
- * struct kxsd9_state - device related storage
- * @buf_lock: protect the rx and tx buffers.
- * @us: spi device
- * @rx: single rx buffer storage
- * @tx: single tx buffer storage
- **/
-struct kxsd9_state {
- struct mutex buf_lock;
- struct spi_device *us;
- u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
- u8 tx[KXSD9_STATE_TX_SIZE];
-};
-
-#define KXSD9_SCALE_2G "0.011978"
-#define KXSD9_SCALE_4G "0.023927"
-#define KXSD9_SCALE_6G "0.035934"
-#define KXSD9_SCALE_8G "0.047853"
-
-/* reverse order */
-static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
-
-static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
-{
- int ret, i;
- struct kxsd9_state *st = iio_priv(indio_dev);
- bool foundit = false;
-
- for (i = 0; i < 4; i++)
- if (micro == kxsd9_micro_scales[i]) {
- foundit = true;
- break;
- }
- if (!foundit)
- return -EINVAL;
-
- mutex_lock(&st->buf_lock);
- ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
- if (ret)
- goto error_ret;
- st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
- st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
-
- ret = spi_write(st->us, st->tx, 2);
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
-{
- struct spi_message msg;
- int ret;
- struct kxsd9_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .bits_per_word = 8,
- .len = 1,
- .delay_usecs = 200,
- .tx_buf = st->tx,
- }, {
- .bits_per_word = 8,
- .len = 2,
- .rx_buf = st->rx,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = KXSD9_READ(address);
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret)
- return ret;
- return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
-}
-
-static IIO_CONST_ATTR(accel_scale_available,
- KXSD9_SCALE_2G " "
- KXSD9_SCALE_4G " "
- KXSD9_SCALE_6G " "
- KXSD9_SCALE_8G);
-
-static struct attribute *kxsd9_attributes[] = {
- &iio_const_attr_accel_scale_available.dev_attr.attr,
- NULL,
-};
-
-static int kxsd9_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- int ret = -EINVAL;
-
- if (mask == IIO_CHAN_INFO_SCALE) {
- /* Check no integer component */
- if (val)
- return -EINVAL;
- ret = kxsd9_write_scale(indio_dev, val2);
- }
-
- return ret;
-}
-
-static int kxsd9_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
-{
- int ret = -EINVAL;
- struct kxsd9_state *st = iio_priv(indio_dev);
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- ret = kxsd9_read(indio_dev, chan->address);
- if (ret < 0)
- goto error_ret;
- *val = ret;
- break;
- case IIO_CHAN_INFO_SCALE:
- ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
- if (ret)
- goto error_ret;
- *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
- ret = IIO_VAL_INT_PLUS_MICRO;
- break;
- }
-
-error_ret:
- return ret;
-};
-#define KXSD9_ACCEL_CHAN(axis) \
- { \
- .type = IIO_ACCEL, \
- .modified = 1, \
- .channel2 = IIO_MOD_##axis, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
- .address = KXSD9_REG_##axis, \
- }
-
-static const struct iio_chan_spec kxsd9_channels[] = {
- KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z),
- {
- .type = IIO_VOLTAGE,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .indexed = 1,
- .address = KXSD9_REG_AUX,
- }
-};
-
-static const struct attribute_group kxsd9_attribute_group = {
- .attrs = kxsd9_attributes,
-};
-
-static int kxsd9_power_up(struct kxsd9_state *st)
-{
- int ret;
-
- st->tx[0] = 0x0d;
- st->tx[1] = 0x40;
- ret = spi_write(st->us, st->tx, 2);
- if (ret)
- return ret;
-
- st->tx[0] = 0x0c;
- st->tx[1] = 0x9b;
- return spi_write(st->us, st->tx, 2);
-};
-
-static const struct iio_info kxsd9_info = {
- .read_raw = &kxsd9_read_raw,
- .write_raw = &kxsd9_write_raw,
- .attrs = &kxsd9_attribute_group,
- .driver_module = THIS_MODULE,
-};
-
-static int kxsd9_probe(struct spi_device *spi)
-{
- struct iio_dev *indio_dev;
- struct kxsd9_state *st;
- int ret = 0;
-
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- spi_set_drvdata(spi, indio_dev);
-
- st->us = spi;
- mutex_init(&st->buf_lock);
- indio_dev->channels = kxsd9_channels;
- indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->dev.parent = &spi->dev;
- indio_dev->info = &kxsd9_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_free_dev;
-
- spi->mode = SPI_MODE_0;
- spi_setup(spi);
- kxsd9_power_up(st);
-
- return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-static int kxsd9_remove(struct spi_device *spi)
-{
- iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
-
- return 0;
-}
-
-static const struct spi_device_id kxsd9_id[] = {
- {"kxsd9", 0},
- { },
-};
-MODULE_DEVICE_TABLE(spi, kxsd9_id);
-
-static struct spi_driver kxsd9_driver = {
- .driver = {
- .name = "kxsd9",
- .owner = THIS_MODULE,
- },
- .probe = kxsd9_probe,
- .remove = kxsd9_remove,
- .id_table = kxsd9_id,
-};
-module_spi_driver(kxsd9_driver);
-
-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 2bac722..0a8ea82 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -185,14 +185,6 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
int lis3l02dq_configure_buffer(struct iio_dev *indio_dev);
void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
-#ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
-#define lis3l02dq_free_buf iio_sw_rb_free
-#define lis3l02dq_alloc_buf iio_sw_rb_allocate
-#endif
-#ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
-#define lis3l02dq_free_buf iio_kfifo_free
-#define lis3l02dq_alloc_buf iio_kfifo_allocate
-#endif
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 37ed1b8..0e01930 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -53,7 +53,6 @@ int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
u8 reg_address, u8 *val)
{
struct lis3l02dq_state *st = iio_priv(indio_dev);
- struct spi_message msg;
int ret;
struct spi_transfer xfer = {
.tx_buf = st->tx,
@@ -66,9 +65,7 @@ int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
st->tx[1] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, &xfer, 1);
*val = st->rx[1];
mutex_unlock(&st->buf_lock);
@@ -109,7 +106,6 @@ static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
s16 value)
{
int ret;
- struct spi_message msg;
struct lis3l02dq_state *st = iio_priv(indio_dev);
struct spi_transfer xfers[] = { {
.tx_buf = st->tx,
@@ -129,10 +125,7 @@ static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
st->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(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
mutex_unlock(&st->buf_lock);
return ret;
@@ -143,8 +136,6 @@ static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
int *val)
{
struct lis3l02dq_state *st = iio_priv(indio_dev);
-
- struct spi_message msg;
int ret;
s16 tempval;
struct spi_transfer xfers[] = { {
@@ -167,10 +158,7 @@ static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
st->tx[3] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 16 bit register");
goto error_ret;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index bc38651..e676403 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -7,7 +7,6 @@
#include <linux/export.h>
#include <linux/iio/iio.h>
-#include "../ring_sw.h"
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
@@ -141,11 +140,8 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
char *data;
data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(indio_dev->dev.parent,
- "memory alloc failed in buffer bh");
+ if (data == NULL)
goto done;
- }
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
len = lis3l02dq_get_buffer_element(indio_dev, data);
@@ -318,7 +314,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev)
{
iio_dealloc_pollfunc(indio_dev->pollfunc);
- lis3l02dq_free_buf(indio_dev->buffer);
+ iio_kfifo_free(indio_dev->buffer);
}
static int lis3l02dq_buffer_postenable(struct iio_dev *indio_dev)
@@ -401,7 +397,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
int ret;
struct iio_buffer *buffer;
- buffer = lis3l02dq_alloc_buf(indio_dev);
+ buffer = iio_kfifo_allocate(indio_dev);
if (!buffer)
return -ENOMEM;
@@ -427,6 +423,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
return 0;
error_iio_sw_rb_free:
- lis3l02dq_free_buf(indio_dev->buffer);
+ iio_kfifo_free(indio_dev->buffer);
return ret;
}
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 414d3ca..14683f5 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -90,7 +90,6 @@ int sca3000_read_data_short(struct sca3000_state *st,
uint8_t reg_address_high,
int len)
{
- struct spi_message msg;
struct spi_transfer xfer[2] = {
{
.len = 1,
@@ -101,11 +100,8 @@ int sca3000_read_data_short(struct sca3000_state *st,
}
};
st->tx[0] = SCA3000_READ_REG(reg_address_high);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer[0], &msg);
- spi_message_add_tail(&xfer[1], &msg);
- return spi_sync(st->us, &msg);
+ return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
}
/**
@@ -133,7 +129,6 @@ static int sca3000_reg_lock_on(struct sca3000_state *st)
**/
static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
{
- struct spi_message msg;
struct spi_transfer xfer[3] = {
{
.len = 2,
@@ -154,12 +149,8 @@ static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
st->tx[3] = 0x50;
st->tx[4] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
st->tx[5] = 0xA0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer[0], &msg);
- spi_message_add_tail(&xfer[1], &msg);
- spi_message_add_tail(&xfer[2], &msg);
- return spi_sync(st->us, &msg);
+ return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
}
/**
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index cbec2f1..3e5e860 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -39,7 +39,6 @@ static int sca3000_read_data(struct sca3000_state *st,
int len)
{
int ret;
- struct spi_message msg;
struct spi_transfer xfer[2] = {
{
.len = 1,
@@ -55,10 +54,7 @@ static int sca3000_read_data(struct sca3000_state *st,
}
xfer[1].rx_buf = *rx_p;
st->tx[0] = SCA3000_READ_REG(reg_address_high);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer[0], &msg);
- spi_message_add_tail(&xfer[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
if (ret) {
dev_err(get_device(&st->us->dev), "problem reading register");
goto error_free_rx;
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index fb8c239..7b2a01d 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -119,12 +119,12 @@ config LPC32XX_ADC
via sysfs.
config MXS_LRADC
- tristate "Freescale i.MX28 LRADC"
+ tristate "Freescale i.MX23/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
+ Say yes here to build support for i.MX23/i.MX28 LRADC convertor
built into these chips.
To compile this driver as a module, choose M here: the
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index fa81a49..1f190c1 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -199,12 +199,8 @@ static int __ad7280_read32(struct spi_device *spi, unsigned *val)
.rx_buf = &rx_buf,
.len = 4,
};
- struct spi_message m;
- spi_message_init(&m);
- spi_message_add_tail(&t, &m);
-
- ret = spi_sync(spi, &m);
+ ret = spi_sync_transfer(spi, &t, 1);
if (ret)
return ret;
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 3d562da..55a459b 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -33,6 +33,8 @@
#include <linux/stmp_device.h>
#include <linux/bitops.h>
#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/input.h>
#include <mach/mxs.h>
#include <mach/common.h>
@@ -60,7 +62,39 @@
#define LRADC_DELAY_TIMER_PER 200
#define LRADC_DELAY_TIMER_LOOP 5
-static const char * const mxs_lradc_irq_name[] = {
+/*
+ * Once the pen touches the touchscreen, the touchscreen switches from
+ * IRQ-driven mode to polling mode to prevent interrupt storm. The polling
+ * is realized by worker thread, which is called every 20 or so milliseconds.
+ * This gives the touchscreen enough fluence and does not strain the system
+ * too much.
+ */
+#define LRADC_TS_SAMPLE_DELAY_MS 5
+
+/*
+ * The LRADC reads the following amount of samples from each touchscreen
+ * channel and the driver then computes avarage of these.
+ */
+#define LRADC_TS_SAMPLE_AMOUNT 4
+
+enum mxs_lradc_id {
+ IMX23_LRADC,
+ IMX28_LRADC,
+};
+
+static const char * const mx23_lradc_irq_names[] = {
+ "mxs-lradc-touchscreen",
+ "mxs-lradc-channel0",
+ "mxs-lradc-channel1",
+ "mxs-lradc-channel2",
+ "mxs-lradc-channel3",
+ "mxs-lradc-channel4",
+ "mxs-lradc-channel5",
+ "mxs-lradc-channel6",
+ "mxs-lradc-channel7",
+};
+
+static const char * const mx28_lradc_irq_names[] = {
"mxs-lradc-touchscreen",
"mxs-lradc-thresh0",
"mxs-lradc-thresh1",
@@ -76,9 +110,26 @@ static const char * const mxs_lradc_irq_name[] = {
"mxs-lradc-button1",
};
-struct mxs_lradc_chan {
- uint8_t slot;
- uint8_t flags;
+struct mxs_lradc_of_config {
+ const int irq_count;
+ const char * const *irq_name;
+};
+
+static const struct mxs_lradc_of_config mxs_lradc_of_config[] = {
+ [IMX23_LRADC] = {
+ .irq_count = ARRAY_SIZE(mx23_lradc_irq_names),
+ .irq_name = mx23_lradc_irq_names,
+ },
+ [IMX28_LRADC] = {
+ .irq_count = ARRAY_SIZE(mx28_lradc_irq_names),
+ .irq_name = mx28_lradc_irq_names,
+ },
+};
+
+enum mxs_lradc_ts {
+ MXS_LRADC_TOUCHSCREEN_NONE = 0,
+ MXS_LRADC_TOUCHSCREEN_4WIRE,
+ MXS_LRADC_TOUCHSCREEN_5WIRE,
};
struct mxs_lradc {
@@ -91,24 +142,70 @@ struct mxs_lradc {
struct mutex lock;
- uint8_t enable;
-
struct completion completion;
+
+ /*
+ * Touchscreen LRADC channels receives a private slot in the CTRL4
+ * register, the slot #7. Therefore only 7 slots instead of 8 in the
+ * CTRL4 register can be mapped to LRADC channels when using the
+ * touchscreen.
+ *
+ * Furthermore, certain LRADC channels are shared between touchscreen
+ * and/or touch-buttons and generic LRADC block. Therefore when using
+ * either of these, these channels are not available for the regular
+ * sampling. The shared channels are as follows:
+ *
+ * CH0 -- Touch button #0
+ * CH1 -- Touch button #1
+ * CH2 -- Touch screen XPUL
+ * CH3 -- Touch screen YPLL
+ * CH4 -- Touch screen XNUL
+ * CH5 -- Touch screen YNLR
+ * CH6 -- Touch screen WIPER (5-wire only)
+ *
+ * The bitfields below represents which parts of the LRADC block are
+ * switched into special mode of operation. These channels can not
+ * be sampled as regular LRADC channels. The driver will refuse any
+ * attempt to sample these channels.
+ */
+#define CHAN_MASK_TOUCHBUTTON (0x3 << 0)
+#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2)
+#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2)
+ enum mxs_lradc_ts use_touchscreen;
+ bool stop_touchscreen;
+ bool use_touchbutton;
+
+ struct input_dev *ts_input;
+ struct work_struct ts_work;
};
#define LRADC_CTRL0 0x00
-#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23)
-#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22)
+#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23)
+#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22)
+#define LRADC_CTRL0_YNNSW /* YM */ (1 << 21)
+#define LRADC_CTRL0_YPNSW /* YP */ (1 << 20)
+#define LRADC_CTRL0_YPPSW /* YP */ (1 << 19)
+#define LRADC_CTRL0_XNNSW /* XM */ (1 << 18)
+#define LRADC_CTRL0_XNPSW /* XM */ (1 << 17)
+#define LRADC_CTRL0_XPPSW /* XP */ (1 << 16)
+#define LRADC_CTRL0_PLATE_MASK (0x3f << 16)
#define LRADC_CTRL1 0x10
-#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
-#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff
+#define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN (1 << 24)
#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16)
+#define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16
+#define LRADC_CTRL1_TOUCH_DETECT_IRQ (1 << 8)
+#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
+#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff
+#define LRADC_CTRL1_LRADC_IRQ_OFFSET 0
#define LRADC_CTRL2 0x20
#define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15)
+#define LRADC_STATUS 0x40
+#define LRADC_STATUS_TOUCH_DETECT_RAW (1 << 0)
+
#define LRADC_CH(n) (0x50 + (0x10 * (n)))
#define LRADC_CH_ACCUMULATE (1 << 29)
#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
@@ -140,6 +237,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
{
struct mxs_lradc *lradc = iio_priv(iio_dev);
int ret;
+ unsigned long mask;
if (m != IIO_CHAN_INFO_RAW)
return -EINVAL;
@@ -148,6 +246,12 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
if (chan->channel > LRADC_MAX_TOTAL_CHANS)
return -EINVAL;
+ /* Validate the channel if it doesn't intersect with reserved chans. */
+ bitmap_set(&mask, chan->channel, 1);
+ ret = iio_validate_scan_mask_onehot(iio_dev, &mask);
+ if (ret)
+ 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
@@ -169,7 +273,11 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
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);
+ /* Clean the slot's previous content, then set new one. */
+ writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+
writel(0, lradc->base + LRADC_CH(0));
/* Enable the IRQ and start sampling the channel. */
@@ -203,6 +311,269 @@ static const struct iio_info mxs_lradc_iio_info = {
};
/*
+ * Touchscreen handling
+ */
+enum lradc_ts_plate {
+ LRADC_SAMPLE_X,
+ LRADC_SAMPLE_Y,
+ LRADC_SAMPLE_PRESSURE,
+};
+
+static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
+{
+ uint32_t reg;
+
+ /* Enable touch detection. */
+ writel(LRADC_CTRL0_PLATE_MASK,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ msleep(LRADC_TS_SAMPLE_DELAY_MS);
+
+ reg = readl(lradc->base + LRADC_STATUS);
+
+ return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
+}
+
+static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
+ enum lradc_ts_plate plate, int change)
+{
+ unsigned long delay, jiff;
+ uint32_t reg, ctrl0 = 0, chan = 0;
+ /* The touchscreen always uses CTRL4 slot #7. */
+ const uint8_t slot = 7;
+ uint32_t val;
+
+ /*
+ * There are three correct configurations of the controller sampling
+ * the touchscreen, each of these configuration provides different
+ * information from the touchscreen.
+ *
+ * The following table describes the sampling configurations:
+ * +-------------+-------+-------+-------+
+ * | Wire \ Axis | X | Y | Z |
+ * +---------------------+-------+-------+
+ * | X+ (CH2) | HI | TS | TS |
+ * +-------------+-------+-------+-------+
+ * | X- (CH4) | LO | SH | HI |
+ * +-------------+-------+-------+-------+
+ * | Y+ (CH3) | SH | HI | HI |
+ * +-------------+-------+-------+-------+
+ * | Y- (CH5) | TS | LO | SH |
+ * +-------------+-------+-------+-------+
+ *
+ * HI ... strong '1' ; LO ... strong '0'
+ * SH ... sample here ; TS ... tri-state
+ *
+ * There are a few other ways of obtaining the Z coordinate
+ * (aka. pressure), but the one in the table seems to be the
+ * most reliable one.
+ */
+ switch (plate) {
+ case LRADC_SAMPLE_X:
+ ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
+ chan = 3;
+ break;
+ case LRADC_SAMPLE_Y:
+ ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
+ chan = 4;
+ break;
+ case LRADC_SAMPLE_PRESSURE:
+ ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
+ chan = 5;
+ break;
+ }
+
+ if (change) {
+ writel(LRADC_CTRL0_PLATE_MASK,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+ }
+
+ writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
+ writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
+ do {
+ jiff = jiffies;
+ reg = readl_relaxed(lradc->base + LRADC_CTRL1);
+ if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
+ break;
+ } while (time_before(jiff, delay));
+
+ writel(LRADC_CTRL1_LRADC_IRQ(slot),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ if (time_after_eq(jiff, delay))
+ return -ETIMEDOUT;
+
+ val = readl(lradc->base + LRADC_CH(slot));
+ val &= LRADC_CH_VALUE_MASK;
+
+ return val;
+}
+
+static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
+ enum lradc_ts_plate plate)
+{
+ int32_t val, tot = 0;
+ int i;
+
+ val = mxs_lradc_ts_sample(lradc, plate, 1);
+
+ /* Delay a bit so the touchscreen is stable. */
+ mdelay(2);
+
+ for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
+ val = mxs_lradc_ts_sample(lradc, plate, 0);
+ tot += val;
+ }
+
+ return tot / LRADC_TS_SAMPLE_AMOUNT;
+}
+
+static void mxs_lradc_ts_work(struct work_struct *ts_work)
+{
+ struct mxs_lradc *lradc = container_of(ts_work,
+ struct mxs_lradc, ts_work);
+ int val_x, val_y, val_p;
+ bool valid = false;
+
+ while (mxs_lradc_ts_touched(lradc)) {
+ /* Disable touch detector so we can sample the touchscreen. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+
+ if (likely(valid)) {
+ input_report_abs(lradc->ts_input, ABS_X, val_x);
+ input_report_abs(lradc->ts_input, ABS_Y, val_y);
+ input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
+ input_report_key(lradc->ts_input, BTN_TOUCH, 1);
+ input_sync(lradc->ts_input);
+ }
+
+ valid = false;
+
+ val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
+ if (val_x < 0)
+ continue;
+ val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
+ if (val_y < 0)
+ continue;
+ val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
+ if (val_p < 0)
+ continue;
+
+ valid = true;
+ }
+
+ input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
+ input_report_key(lradc->ts_input, BTN_TOUCH, 0);
+ input_sync(lradc->ts_input);
+
+ /* Do not restart the TS IRQ if the driver is shutting down. */
+ if (lradc->stop_touchscreen)
+ return;
+
+ /* Restart the touchscreen interrupts. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+}
+
+static int mxs_lradc_ts_open(struct input_dev *dev)
+{
+ struct mxs_lradc *lradc = input_get_drvdata(dev);
+
+ /* The touchscreen is starting. */
+ lradc->stop_touchscreen = false;
+
+ /* Enable the touch-detect circuitry. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ /* Enable the touch-detect IRQ. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+
+ return 0;
+}
+
+static void mxs_lradc_ts_close(struct input_dev *dev)
+{
+ struct mxs_lradc *lradc = input_get_drvdata(dev);
+
+ /* Indicate the touchscreen is stopping. */
+ lradc->stop_touchscreen = true;
+ mb();
+
+ /* Wait until touchscreen thread finishes any possible remnants. */
+ cancel_work_sync(&lradc->ts_work);
+
+ /* Disable touchscreen touch-detect IRQ. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ /* Power-down touchscreen touch-detect circuitry. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+}
+
+static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
+{
+ struct input_dev *input;
+ struct device *dev = lradc->dev;
+ int ret;
+
+ if (!lradc->use_touchscreen)
+ return 0;
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(dev, "Failed to allocate TS device!\n");
+ return -ENOMEM;
+ }
+
+ input->name = DRIVER_NAME;
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = dev;
+ input->open = mxs_lradc_ts_open;
+ input->close = mxs_lradc_ts_close;
+
+ __set_bit(EV_ABS, input->evbit);
+ __set_bit(EV_KEY, input->evbit);
+ __set_bit(BTN_TOUCH, input->keybit);
+ input_set_abs_params(input, ABS_X, 0, LRADC_CH_VALUE_MASK, 0, 0);
+ input_set_abs_params(input, ABS_Y, 0, LRADC_CH_VALUE_MASK, 0, 0);
+ input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_CH_VALUE_MASK, 0, 0);
+
+ lradc->ts_input = input;
+ input_set_drvdata(input, lradc);
+ ret = input_register_device(input);
+ if (ret)
+ input_free_device(lradc->ts_input);
+
+ return ret;
+}
+
+static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
+{
+ if (!lradc->use_touchscreen)
+ return;
+
+ cancel_work_sync(&lradc->ts_work);
+
+ input_unregister_device(lradc->ts_input);
+}
+
+/*
* IRQ Handling
*/
static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
@@ -210,14 +581,24 @@ 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);
+ const uint32_t ts_irq_mask =
+ LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+ LRADC_CTRL1_TOUCH_DETECT_IRQ;
if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
return IRQ_NONE;
/*
- * Touchscreen IRQ handling code shall probably have priority
- * and therefore shall be placed here.
+ * Touchscreen IRQ handling code has priority and therefore
+ * is placed here. In case touchscreen IRQ arrives, disable
+ * it ASAP
*/
+ if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
+ writel(ts_irq_mask,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ if (!lradc->stop_touchscreen)
+ schedule_work(&lradc->ts_work);
+ }
if (iio_buffer_enabled(iio))
iio_trigger_poll(iio->trig, iio_get_time_ns());
@@ -313,8 +694,10 @@ 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;
+ int ret = 0, chan, ofs = 0;
+ unsigned long enable = 0;
+ uint32_t ctrl4_set = 0;
+ uint32_t ctrl4_clr = 0;
uint32_t ctrl1_irq = 0;
const uint32_t chan_value = LRADC_CH_ACCUMULATE |
((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
@@ -346,17 +729,20 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
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);
+ ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
+ ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
writel(chan_value, lradc->base + LRADC_CH(ofs));
- enable |= 1 << ofs;
+ bitmap_set(&enable, ofs, 1);
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(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+
writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
@@ -391,9 +777,33 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
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;
+ struct mxs_lradc *lradc = iio_priv(iio);
+ const int len = iio->masklength;
+ const int map_chans = bitmap_weight(mask, len);
+ int rsvd_chans = 0;
+ unsigned long rsvd_mask = 0;
+
+ if (lradc->use_touchbutton)
+ rsvd_mask |= CHAN_MASK_TOUCHBUTTON;
+ if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_4WIRE)
+ rsvd_mask |= CHAN_MASK_TOUCHSCREEN_4WIRE;
+ if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
+ rsvd_mask |= CHAN_MASK_TOUCHSCREEN_5WIRE;
+
+ if (lradc->use_touchbutton)
+ rsvd_chans++;
+ if (lradc->use_touchscreen)
+ rsvd_chans++;
+
+ /* Test for attempts to map channels with special mode of operation. */
+ if (bitmap_intersects(mask, &rsvd_mask, len))
+ return false;
+
+ /* Test for attempts to map more channels then available slots. */
+ if (map_chans + rsvd_chans > LRADC_MAX_MAPPED_CHANS)
+ return false;
+
+ return true;
}
static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
@@ -442,15 +852,29 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
{
- int i;
- const uint32_t cfg =
+ /* The ADC always uses DELAY CHANNEL 0. */
+ const uint32_t adc_cfg =
+ (1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
(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));
+ /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
+ writel(adc_cfg, lradc->base + LRADC_DELAY(0));
+
+ /* Disable remaining DELAY CHANNELs */
+ writel(0, lradc->base + LRADC_DELAY(1));
+ writel(0, lradc->base + LRADC_DELAY(2));
+ writel(0, lradc->base + LRADC_DELAY(3));
+
+ /* Configure the touchscreen type */
+ writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+
+ if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) {
+ writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ }
/* Start internal temperature sensing. */
writel(0, lradc->base + LRADC_CTRL2);
@@ -467,12 +891,25 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
writel(0, lradc->base + LRADC_DELAY(i));
}
+static const struct of_device_id mxs_lradc_dt_ids[] = {
+ { .compatible = "fsl,imx23-lradc", .data = (void *)IMX23_LRADC, },
+ { .compatible = "fsl,imx28-lradc", .data = (void *)IMX28_LRADC, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
+
static int mxs_lradc_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id =
+ of_match_device(mxs_lradc_dt_ids, &pdev->dev);
+ const struct mxs_lradc_of_config *of_cfg =
+ &mxs_lradc_of_config[(enum mxs_lradc_id)of_id->data];
struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
struct mxs_lradc *lradc;
struct iio_dev *iio;
struct resource *iores;
+ uint32_t ts_wires = 0;
int ret = 0;
int i;
@@ -494,8 +931,23 @@ static int mxs_lradc_probe(struct platform_device *pdev)
goto err_addr;
}
+ INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
+
+ /* Check if touchscreen is enabled in DT. */
+ ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
+ &ts_wires);
+ if (ret)
+ dev_info(dev, "Touchscreen not enabled.\n");
+ else if (ts_wires == 4)
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
+ else if (ts_wires == 5)
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
+ else
+ dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
+ ts_wires);
+
/* Grab all IRQ sources */
- for (i = 0; i < 13; i++) {
+ for (i = 0; i < of_cfg->irq_count; i++) {
lradc->irq[i] = platform_get_irq(pdev, i);
if (lradc->irq[i] < 0) {
ret = -EINVAL;
@@ -504,7 +956,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, lradc->irq[i],
mxs_lradc_handle_irq, 0,
- mxs_lradc_irq_name[i], iio);
+ of_cfg->irq_name[i], iio);
if (ret)
goto err_addr;
}
@@ -531,11 +983,16 @@ static int mxs_lradc_probe(struct platform_device *pdev)
if (ret)
goto err_trig;
+ /* Register the touchscreen input device. */
+ ret = mxs_lradc_ts_register(lradc);
+ if (ret)
+ goto err_dev;
+
/* Register IIO device. */
ret = iio_device_register(iio);
if (ret) {
dev_err(dev, "Failed to register IIO device\n");
- goto err_dev;
+ goto err_ts;
}
/* Configure the hardware. */
@@ -543,6 +1000,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
return 0;
+err_ts:
+ mxs_lradc_ts_unregister(lradc);
err_dev:
mxs_lradc_trigger_remove(iio);
err_trig:
@@ -557,6 +1016,8 @@ static int mxs_lradc_remove(struct platform_device *pdev)
struct iio_dev *iio = platform_get_drvdata(pdev);
struct mxs_lradc *lradc = iio_priv(iio);
+ mxs_lradc_ts_unregister(lradc);
+
mxs_lradc_hw_stop(lradc);
iio_device_unregister(iio);
@@ -567,12 +1028,6 @@ static int mxs_lradc_remove(struct platform_device *pdev)
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,
diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c
index 23777be..69e90e9 100644
--- a/drivers/staging/iio/frequency/ad5930.c
+++ b/drivers/staging/iio/frequency/ad5930.c
@@ -44,7 +44,6 @@ static ssize_t ad5930_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad5903_config *config = (struct ad5903_config *)buf;
@@ -64,9 +63,7 @@ static ssize_t ad5930_set_parameter(struct device *dev,
xfer.tx_buf = config;
mutex_lock(&st->lock);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
error_ret:
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index 104f7a4..01a8a93 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -39,7 +39,6 @@ static ssize_t ad9850_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9850_config *config = (struct ad9850_config *)buf;
@@ -50,9 +49,7 @@ static ssize_t ad9850_set_parameter(struct device *dev,
xfer.tx_buf = config;
mutex_lock(&st->lock);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
error_ret:
diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c
index 17ac825..1344031 100644
--- a/drivers/staging/iio/frequency/ad9852.c
+++ b/drivers/staging/iio/frequency/ad9852.c
@@ -183,7 +183,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0);
static void ad9852_init(struct ad9852_state *st)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
u8 config[5];
@@ -199,9 +198,7 @@ static void ad9852_init(struct ad9852_state *st)
xfer.len = 5;
xfer.tx_buf = &config;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index 87979a0..8360662 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -10,13 +10,6 @@ config ADIS16060
Say yes here to build support for Analog Devices adis16060 wide bandwidth
yaw rate gyroscope with SPI.
-config ADIS16080
- tristate "Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"
- depends on SPI
- help
- Say yes here to build support for Analog Devices adis16080/100 Yaw Rate
- Gyroscope with SPI.
-
config ADIS16130
tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"
depends on SPI
@@ -36,14 +29,4 @@ config ADIS16260
This driver can also be built as a module. If so, the module
will be called adis16260.
-config ADXRS450
- tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
- depends on SPI
- help
- Say yes here to build support for Analog Devices ADXRS450 and ADXRS453
- programmable digital output gyroscope.
-
- This driver can also be built as a module. If so, the module
- will be called adxrs450.
-
endmenu
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index 1303569..98e6500 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -5,17 +5,8 @@
adis16060-y := adis16060_core.o
obj-$(CONFIG_ADIS16060) += adis16060.o
-adis16080-y := adis16080_core.o
-obj-$(CONFIG_ADIS16080) += adis16080.o
-
adis16130-y := adis16130_core.o
obj-$(CONFIG_ADIS16130) += adis16130.o
adis16260-y := adis16260_core.o
obj-$(CONFIG_ADIS16260) += adis16260.o
-
-adis16251-y := adis16251_core.o
-obj-$(CONFIG_ADIS16251) += adis16251.o
-
-adxrs450-y := adxrs450_core.o
-obj-$(CONFIG_ADXRS450) += adxrs450.o
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
deleted file mode 100644
index 41d7350..0000000
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * ADIS16080/100 Yaw Rate Gyroscope with SPI driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * 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 <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */
-#define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */
-#define ADIS16080_DIN_AIN1 (2 << 10)
-#define ADIS16080_DIN_AIN2 (3 << 10)
-
-/*
- * 1: Write contents on DIN to control register.
- * 0: No changes to control register.
- */
-
-#define ADIS16080_DIN_WRITE (1 << 15)
-
-/**
- * struct adis16080_state - device instance specific data
- * @us: actual spi_device to write data
- * @buf: transmit or receive buffer
- * @buf_lock: mutex to protect tx and rx
- **/
-struct adis16080_state {
- struct spi_device *us;
- struct mutex buf_lock;
-
- u8 buf[2] ____cacheline_aligned;
-};
-
-static int adis16080_spi_write(struct iio_dev *indio_dev,
- u16 val)
-{
- int ret;
- struct adis16080_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->buf[0] = val >> 8;
- st->buf[1] = val;
-
- ret = spi_write(st->us, st->buf, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-static int adis16080_spi_read(struct iio_dev *indio_dev,
- u16 *val)
-{
- int ret;
- struct adis16080_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
-
- ret = spi_read(st->us, st->buf, 2);
-
- if (ret == 0)
- *val = sign_extend32(((st->buf[0] & 0xF) << 8) | st->buf[1], 11);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-static int adis16080_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- int ret = -EINVAL;
- u16 ut = 0;
- /* Take the iio_dev status lock */
-
- mutex_lock(&indio_dev->mlock);
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- ret = adis16080_spi_write(indio_dev,
- chan->address |
- ADIS16080_DIN_WRITE);
- if (ret < 0)
- break;
- ret = adis16080_spi_read(indio_dev, &ut);
- if (ret < 0)
- break;
- *val = ut;
- ret = IIO_VAL_INT;
- break;
- }
- mutex_unlock(&indio_dev->mlock);
-
- return ret;
-}
-
-static const struct iio_chan_spec adis16080_channels[] = {
- {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .address = ADIS16080_DIN_GYRO,
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .address = ADIS16080_DIN_AIN1,
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .address = ADIS16080_DIN_AIN2,
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
- .address = ADIS16080_DIN_TEMP,
- }
-};
-
-static const struct iio_info adis16080_info = {
- .read_raw = &adis16080_read_raw,
- .driver_module = THIS_MODULE,
-};
-
-static int adis16080_probe(struct spi_device *spi)
-{
- int ret;
- struct adis16080_state *st;
- struct iio_dev *indio_dev;
-
- /* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- /* this is only used for removal purposes */
- spi_set_drvdata(spi, indio_dev);
-
- /* Allocate the comms buffers */
- st->us = spi;
- mutex_init(&st->buf_lock);
-
- indio_dev->name = spi->dev.driver->name;
- indio_dev->channels = adis16080_channels;
- indio_dev->num_channels = ARRAY_SIZE(adis16080_channels);
- indio_dev->dev.parent = &spi->dev;
- indio_dev->info = &adis16080_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_free_dev;
- return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-/* fixme, confirm ordering in this function */
-static int adis16080_remove(struct spi_device *spi)
-{
- iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
-
- return 0;
-}
-
-static struct spi_driver adis16080_driver = {
- .driver = {
- .name = "adis16080",
- .owner = THIS_MODULE,
- },
- .probe = adis16080_probe,
- .remove = adis16080_remove,
-};
-module_spi_driver(adis16080_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:adis16080");
diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h
deleted file mode 100644
index f8cf21f..0000000
--- a/drivers/staging/iio/gyro/adxrs450.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef SPI_ADXRS450_H_
-#define SPI_ADXRS450_H_
-
-#define ADXRS450_STARTUP_DELAY 50 /* ms */
-
-/* The MSB for the spi commands */
-#define ADXRS450_SENSOR_DATA 0x20
-#define ADXRS450_WRITE_DATA 0x40
-#define ADXRS450_READ_DATA 0x80
-
-#define ADXRS450_RATE1 0x00 /* Rate Registers */
-#define ADXRS450_TEMP1 0x02 /* Temperature Registers */
-#define ADXRS450_LOCST1 0x04 /* Low CST Memory Registers */
-#define ADXRS450_HICST1 0x06 /* High CST Memory Registers */
-#define ADXRS450_QUAD1 0x08 /* Quad Memory Registers */
-#define ADXRS450_FAULT1 0x0A /* Fault Registers */
-#define ADXRS450_PID1 0x0C /* Part ID Register 1 */
-#define ADXRS450_SNH 0x0E /* Serial Number Registers, 4 bytes */
-#define ADXRS450_SNL 0x10
-#define ADXRS450_DNC1 0x12 /* Dynamic Null Correction Registers */
-/* Check bits */
-#define ADXRS450_P 0x01
-#define ADXRS450_CHK 0x02
-#define ADXRS450_CST 0x04
-#define ADXRS450_PWR 0x08
-#define ADXRS450_POR 0x10
-#define ADXRS450_NVM 0x20
-#define ADXRS450_Q 0x40
-#define ADXRS450_PLL 0x80
-#define ADXRS450_UV 0x100
-#define ADXRS450_OV 0x200
-#define ADXRS450_AMP 0x400
-#define ADXRS450_FAIL 0x800
-
-#define ADXRS450_WRERR_MASK (0x7 << 29)
-
-#define ADXRS450_MAX_RX 4
-#define ADXRS450_MAX_TX 4
-
-#define ADXRS450_GET_ST(a) ((a >> 26) & 0x3)
-
-enum {
- ID_ADXRS450,
- ID_ADXRS453,
-};
-
-/**
- * struct adxrs450_state - device instance specific data
- * @us: actual spi_device
- * @buf_lock: mutex to protect tx and rx
- * @tx: transmit buffer
- * @rx: receive buffer
- **/
-struct adxrs450_state {
- struct spi_device *us;
- struct mutex buf_lock;
- u8 tx[ADXRS450_MAX_RX] ____cacheline_aligned;
- u8 rx[ADXRS450_MAX_TX];
-
-};
-
-#endif /* SPI_ADXRS450_H_ */
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c
deleted file mode 100644
index f0ce81d..0000000
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * ADXRS450/ADXRS453 Digital Output Gyroscope Driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#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/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#include "adxrs450.h"
-
-/**
- * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair
- * @dev: device associated with child of actual iio_dev
- * @reg_address: the address of the lower of the two registers,which should be an even address,
- * Second register's address is reg_address + 1.
- * @val: somewhere to pass back the value read
- **/
-static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 reg_address,
- u16 *val)
-{
- struct adxrs450_state *st = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADXRS450_READ_DATA | (reg_address >> 7);
- st->tx[1] = reg_address << 1;
- st->tx[2] = 0;
- st->tx[3] = 0;
-
- if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1))
- st->tx[3] |= ADXRS450_P;
-
- ret = spi_write(st->us, st->tx, 4);
- if (ret) {
- dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
- reg_address);
- goto error_ret;
- }
- ret = spi_read(st->us, st->rx, 4);
- if (ret) {
- dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
- reg_address);
- goto error_ret;
- }
-
- *val = (be32_to_cpu(*(u32 *)st->rx) >> 5) & 0xFFFF;
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-/**
- * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair
- * @dev: device associated with child of actual actual iio_dev
- * @reg_address: the address of the lower of the two registers,which should be an even address,
- * Second register's address is reg_address + 1.
- * @val: value to be written.
- **/
-static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 reg_address,
- u16 val)
-{
- struct adxrs450_state *st = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADXRS450_WRITE_DATA | reg_address >> 7;
- st->tx[1] = reg_address << 1 | val >> 15;
- st->tx[2] = val >> 7;
- st->tx[3] = val << 1;
-
- if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1))
- st->tx[3] |= ADXRS450_P;
-
- ret = spi_write(st->us, st->tx, 4);
- if (ret)
- dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n",
- reg_address);
- msleep(1); /* enforce sequential transfer delay 0.1ms */
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-/**
- * adxrs450_spi_sensor_data() - read 2 bytes sensor data
- * @dev: device associated with child of actual iio_dev
- * @val: somewhere to pass back the value read
- **/
-static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
-{
- struct adxrs450_state *st = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADXRS450_SENSOR_DATA;
- st->tx[1] = 0;
- st->tx[2] = 0;
- st->tx[3] = 0;
-
- ret = spi_write(st->us, st->tx, 4);
- if (ret) {
- dev_err(&st->us->dev, "Problem while reading sensor data\n");
- goto error_ret;
- }
-
- ret = spi_read(st->us, st->rx, 4);
- if (ret) {
- dev_err(&st->us->dev, "Problem while reading sensor data\n");
- goto error_ret;
- }
-
- *val = (be32_to_cpu(*(u32 *)st->rx) >> 10) & 0xFFFF;
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-/**
- * adxrs450_spi_initial() - use for initializing procedure.
- * @st: device instance specific data
- * @val: somewhere to pass back the value read
- **/
-static int adxrs450_spi_initial(struct adxrs450_state *st,
- u32 *val, char chk)
-{
- struct spi_message msg;
- int ret;
- struct spi_transfer xfers = {
- .tx_buf = st->tx,
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 4,
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADXRS450_SENSOR_DATA;
- st->tx[1] = 0;
- st->tx[2] = 0;
- st->tx[3] = 0;
- if (chk)
- st->tx[3] |= (ADXRS450_CHK | ADXRS450_P);
- spi_message_init(&msg);
- spi_message_add_tail(&xfers, &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev, "Problem while reading initializing data\n");
- goto error_ret;
- }
-
- *val = be32_to_cpu(*(u32 *)st->rx);
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-/* Recommended Startup Sequence by spec */
-static int adxrs450_initial_setup(struct iio_dev *indio_dev)
-{
- u32 t;
- u16 data;
- int ret;
- struct adxrs450_state *st = iio_priv(indio_dev);
-
- msleep(ADXRS450_STARTUP_DELAY*2);
- ret = adxrs450_spi_initial(st, &t, 1);
- if (ret)
- return ret;
- if (t != 0x01)
- dev_warn(&st->us->dev, "The initial power on response "
- "is not correct! Restart without reset?\n");
-
- msleep(ADXRS450_STARTUP_DELAY);
- ret = adxrs450_spi_initial(st, &t, 0);
- if (ret)
- return ret;
-
- msleep(ADXRS450_STARTUP_DELAY);
- ret = adxrs450_spi_initial(st, &t, 0);
- if (ret)
- return ret;
- if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) {
- dev_err(&st->us->dev, "The second response is not correct!\n");
- return -EIO;
-
- }
- ret = adxrs450_spi_initial(st, &t, 0);
- if (ret)
- return ret;
- if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) {
- dev_err(&st->us->dev, "The third response is not correct!\n");
- return -EIO;
-
- }
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_FAULT1, &data);
- if (ret)
- return ret;
- if (data & 0x0fff) {
- dev_err(&st->us->dev, "The device is not in normal status!\n");
- return -EINVAL;
- }
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_PID1, &data);
- if (ret)
- return ret;
- dev_info(&st->us->dev, "The Part ID is 0x%x\n", data);
-
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNL, &data);
- if (ret)
- return ret;
- t = data;
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNH, &data);
- if (ret)
- return ret;
- t |= data << 16;
- dev_info(&st->us->dev, "The Serial Number is 0x%x\n", t);
-
- return 0;
-}
-
-static int adxrs450_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- int ret;
- switch (mask) {
- case IIO_CHAN_INFO_CALIBBIAS:
- ret = adxrs450_spi_write_reg_16(indio_dev,
- ADXRS450_DNC1,
- val & 0x3FF);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int adxrs450_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- int ret;
- s16 t;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- ret = adxrs450_spi_sensor_data(indio_dev, &t);
- if (ret)
- break;
- *val = t;
- ret = IIO_VAL_INT;
- break;
- case IIO_TEMP:
- ret = adxrs450_spi_read_reg_16(indio_dev,
- ADXRS450_TEMP1, &t);
- if (ret)
- break;
- *val = (t >> 6) + 225;
- ret = IIO_VAL_INT;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- break;
- case IIO_CHAN_INFO_SCALE:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- *val = 0;
- *val2 = 218166;
- return IIO_VAL_INT_PLUS_NANO;
- case IIO_TEMP:
- *val = 200;
- *val2 = 0;
- return IIO_VAL_INT;
- default:
- return -EINVAL;
- }
- break;
- case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
- if (ret)
- break;
- *val = t;
- ret = IIO_VAL_INT;
- break;
- case IIO_CHAN_INFO_CALIBBIAS:
- ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_DNC1, &t);
- if (ret)
- break;
- *val = t;
- ret = IIO_VAL_INT;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static const struct iio_chan_spec adxrs450_channels[2][2] = {
- [ID_ADXRS450] = {
- {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- }
- },
- [ID_ADXRS453] = {
- {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT,
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- }
- },
-};
-
-static const struct iio_info adxrs450_info = {
- .driver_module = THIS_MODULE,
- .read_raw = &adxrs450_read_raw,
- .write_raw = &adxrs450_write_raw,
-};
-
-static int adxrs450_probe(struct spi_device *spi)
-{
- int ret;
- struct adxrs450_state *st;
- struct iio_dev *indio_dev;
-
- /* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- st->us = spi;
- mutex_init(&st->buf_lock);
- /* This is only used for removal purposes */
- spi_set_drvdata(spi, indio_dev);
-
- indio_dev->dev.parent = &spi->dev;
- indio_dev->info = &adxrs450_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels =
- adxrs450_channels[spi_get_device_id(spi)->driver_data];
- indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels);
- indio_dev->name = spi->dev.driver->name;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_free_dev;
-
- /* Get the device into a sane initial state */
- ret = adxrs450_initial_setup(indio_dev);
- if (ret)
- goto error_initial;
- return 0;
-error_initial:
- iio_device_unregister(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-
-error_ret:
- return ret;
-}
-
-static int adxrs450_remove(struct spi_device *spi)
-{
- iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
-
- return 0;
-}
-
-static const struct spi_device_id adxrs450_id[] = {
- {"adxrs450", ID_ADXRS450},
- {"adxrs453", ID_ADXRS453},
- {}
-};
-MODULE_DEVICE_TABLE(spi, adxrs450_id);
-
-static struct spi_driver adxrs450_driver = {
- .driver = {
- .name = "adxrs450",
- .owner = THIS_MODULE,
- },
- .probe = adxrs450_probe,
- .remove = adxrs450_remove,
- .id_table = adxrs450_id,
-};
-module_spi_driver(adxrs450_driver);
-
-MODULE_AUTHOR("Cliff Cai <cliff.cai@xxxxxxxxxx>");
-MODULE_DESCRIPTION("Analog Devices ADXRS450/ADXRS453 Gyroscope SPI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c
index c7a5f97..93af756 100644
--- a/drivers/staging/iio/iio_hwmon.c
+++ b/drivers/staging/iio/iio_hwmon.c
@@ -55,63 +55,58 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
return sprintf(buf, "%d\n", result);
}
-static void iio_hwmon_free_attrs(struct iio_hwmon_state *st)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- int i;
- struct sensor_device_attribute *a;
- for (i = 0; i < st->num_channels; i++)
- if (st->attrs[i]) {
- a = to_sensor_dev_attr(
- container_of(st->attrs[i],
- struct device_attribute,
- attr));
- kfree(a);
- }
+ return sprintf(buf, "iio_hwmon\n");
}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
static int iio_hwmon_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct iio_hwmon_state *st;
struct sensor_device_attribute *a;
int ret, i;
int in_i = 1, temp_i = 1, curr_i = 1;
enum iio_chan_type type;
+ struct iio_channel *channels;
- st = kzalloc(sizeof(*st), GFP_KERNEL);
- if (st == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ channels = iio_channel_get_all(dev);
+ if (IS_ERR(channels))
+ return PTR_ERR(channels);
- st->channels = iio_channel_get_all(dev_name(&pdev->dev));
- if (IS_ERR(st->channels)) {
- ret = PTR_ERR(st->channels);
- goto error_free_state;
- }
+ st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
+
+ st->channels = channels;
/* count how many attributes we have */
while (st->channels[st->num_channels].indio_dev)
st->num_channels++;
- st->attrs = kzalloc(sizeof(st->attrs) * (st->num_channels + 1),
- GFP_KERNEL);
+ st->attrs = devm_kzalloc(dev,
+ sizeof(*st->attrs) * (st->num_channels + 2),
+ GFP_KERNEL);
if (st->attrs == NULL) {
ret = -ENOMEM;
goto error_release_channels;
}
+
for (i = 0; i < st->num_channels; i++) {
- a = kzalloc(sizeof(*a), GFP_KERNEL);
+ a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL);
if (a == NULL) {
ret = -ENOMEM;
- goto error_free_attrs;
+ goto error_release_channels;
}
sysfs_attr_init(&a->dev_attr.attr);
ret = iio_get_channel_type(&st->channels[i], &type);
- if (ret < 0) {
- kfree(a);
- goto error_free_attrs;
- }
+ if (ret < 0)
+ goto error_release_channels;
+
switch (type) {
case IIO_VOLTAGE:
a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
@@ -130,27 +125,25 @@ static int iio_hwmon_probe(struct platform_device *pdev)
break;
default:
ret = -EINVAL;
- kfree(a);
- goto error_free_attrs;
+ goto error_release_channels;
}
if (a->dev_attr.attr.name == NULL) {
- kfree(a);
ret = -ENOMEM;
- goto error_free_attrs;
+ goto error_release_channels;
}
a->dev_attr.show = iio_hwmon_read_val;
a->dev_attr.attr.mode = S_IRUGO;
a->index = i;
st->attrs[i] = &a->dev_attr.attr;
}
-
+ st->attrs[st->num_channels] = &dev_attr_name.attr;
st->attr_group.attrs = st->attrs;
platform_set_drvdata(pdev, st);
- ret = sysfs_create_group(&pdev->dev.kobj, &st->attr_group);
+ ret = sysfs_create_group(&dev->kobj, &st->attr_group);
if (ret < 0)
- goto error_free_attrs;
+ goto error_release_channels;
- st->hwmon_dev = hwmon_device_register(&pdev->dev);
+ st->hwmon_dev = hwmon_device_register(dev);
if (IS_ERR(st->hwmon_dev)) {
ret = PTR_ERR(st->hwmon_dev);
goto error_remove_group;
@@ -158,15 +151,9 @@ static int iio_hwmon_probe(struct platform_device *pdev)
return 0;
error_remove_group:
- sysfs_remove_group(&pdev->dev.kobj, &st->attr_group);
-error_free_attrs:
- iio_hwmon_free_attrs(st);
- kfree(st->attrs);
+ sysfs_remove_group(&dev->kobj, &st->attr_group);
error_release_channels:
iio_channel_release_all(st->channels);
-error_free_state:
- kfree(st);
-error_ret:
return ret;
}
@@ -176,17 +163,21 @@ static int iio_hwmon_remove(struct platform_device *pdev)
hwmon_device_unregister(st->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &st->attr_group);
- iio_hwmon_free_attrs(st);
- kfree(st->attrs);
iio_channel_release_all(st->channels);
return 0;
}
+static struct of_device_id iio_hwmon_of_match[] = {
+ { .compatible = "iio-hwmon", },
+ { }
+};
+
static struct platform_driver __refdata iio_hwmon_driver = {
.driver = {
.name = "iio_hwmon",
.owner = THIS_MODULE,
+ .of_match_table = iio_hwmon_of_match,
},
.probe = iio_hwmon_probe,
.remove = iio_hwmon_remove,
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index a865adf..aee76c7 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -54,7 +54,7 @@ struct iio_dummy_accel_calibscale {
static const struct iio_dummy_accel_calibscale dummy_scales[] = {
{ 0, 100, 0x8 }, /* 0.000100 */
{ 0, 133, 0x7 }, /* 0.000133 */
- { 733, 13, 0x9 }, /* 733.00013 */
+ { 733, 13, 0x9 }, /* 733.000013 */
};
/*
@@ -284,7 +284,7 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
/**
* iio_dummy_write_raw() - data write function.
* @indio_dev: the struct iio_dev associated with this device instance
- * @chan: the channel whose data is to be read
+ * @chan: the channel whose data is to be written
* @val: first element of value to set (typically INT)
* @val2: second element of value to set (typically MICRO)
* @mask: what we actually want to write. 0 is the channel, everything else
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index dee16f0..72f400c 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -155,7 +155,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
* occurs, this function is run. Typically this grabs data
* from the device.
*
- * NULL for the top half. This is normally implemented only if we
+ * NULL for the bottom half. This is normally implemented only if we
* either want to ping a capture now pin (no sleeping) or grab
* a timestamp as close as possible to a data ready trigger firing.
*
diff --git a/drivers/staging/iio/impedance-analyzer/Kconfig b/drivers/staging/iio/impedance-analyzer/Kconfig
index ad0ff76..dd97b6b 100644
--- a/drivers/staging/iio/impedance-analyzer/Kconfig
+++ b/drivers/staging/iio/impedance-analyzer/Kconfig
@@ -7,7 +7,7 @@ config AD5933
tristate "Analog Devices AD5933, AD5934 driver"
depends on I2C
select IIO_BUFFER
- select IIO_SW_RING
+ select IIO_KFIFO_BUF
help
Say yes here to build support for Analog Devices Impedance Converter,
Network Analyzer, AD5933/4, provides direct access via sysfs.
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 779243d..440e226 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -22,7 +22,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
-#include "../ring_sw.h"
+#include <linux/iio/kfifo_buf.h>
#include "ad5933.h"
@@ -630,7 +630,7 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
- indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
+ indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer)
return -ENOMEM;
@@ -774,7 +774,7 @@ static int ad5933_probe(struct i2c_client *client,
error_uninitialize_ring:
iio_buffer_unregister(indio_dev);
error_unreg_ring:
- iio_sw_rb_free(indio_dev->buffer);
+ iio_kfifo_free(indio_dev->buffer);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
@@ -794,7 +794,7 @@ static int ad5933_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
- iio_sw_rb_free(indio_dev->buffer);
+ iio_kfifo_free(indio_dev->buffer);
if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
regulator_put(st->reg);
diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
deleted file mode 100644
index 2c2f47d..0000000
--- a/drivers/staging/iio/imu/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# IIO imu drivers configuration
-#
-menu "Inertial measurement units"
-
-config ADIS16400
- tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
- depends on SPI
- select IIO_SW_RING if IIO_BUFFER
- select IIO_TRIGGER if IIO_BUFFER
- help
- Say yes here to build support for Analog Devices adis16300, adis16344,
- adis16350, adis16354, adis16355, adis16360, adis16362, adis16364,
- adis16365, adis16400 and adis16405 triaxial inertial sensors
- (adis16400 series also have magnetometers).
-
-endmenu
diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile
deleted file mode 100644
index 3400a13..0000000
--- a/drivers/staging/iio/imu/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for Inertial Measurement Units
-#
-
-adis16400-y := adis16400_core.o
-adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o adis16400_trigger.o
-obj-$(CONFIG_ADIS16400) += adis16400.o
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
deleted file mode 100644
index 7a105e9..0000000
--- a/drivers/staging/iio/imu/adis16400.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * adis16400.h support Analog Devices ADIS16400
- * 3d 18g accelerometers,
- * 3d gyroscopes,
- * 3d 2.5gauss magnetometers via SPI
- *
- * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
- * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
- *
- * Loosely based upon lis3l02dq.h
- *
- * 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
- * published by the Free Software Foundation.
- */
-
-#ifndef SPI_ADIS16400_H_
-#define SPI_ADIS16400_H_
-
-#define ADIS16400_STARTUP_DELAY 290 /* ms */
-#define ADIS16400_MTEST_DELAY 90 /* ms */
-
-#define ADIS16400_READ_REG(a) a
-#define ADIS16400_WRITE_REG(a) ((a) | 0x80)
-
-#define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */
-#define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16400_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
-#define ADIS16400_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
-#define ADIS16400_XACCL_OUT 0x0A /* X-axis accelerometer output */
-#define ADIS16400_YACCL_OUT 0x0C /* Y-axis accelerometer output */
-#define ADIS16400_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
-#define ADIS16400_XMAGN_OUT 0x10 /* X-axis magnetometer measurement */
-#define ADIS16400_YMAGN_OUT 0x12 /* Y-axis magnetometer measurement */
-#define ADIS16400_ZMAGN_OUT 0x14 /* Z-axis magnetometer measurement */
-#define ADIS16400_TEMP_OUT 0x16 /* Temperature output */
-#define ADIS16400_AUX_ADC 0x18 /* Auxiliary ADC measurement */
-
-#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
-#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
-#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
-
-#define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */
-#define ADIS16300_ROLL_OUT 0x14 /* Y axis inclinometer output measurement */
-#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */
-
-/* Calibration parameters */
-#define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
-#define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
-#define ADIS16400_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
-#define ADIS16400_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
-#define ADIS16400_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
-#define ADIS16400_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
-#define ADIS16400_XMAGN_HIF 0x26 /* X-axis magnetometer, hard-iron factor */
-#define ADIS16400_YMAGN_HIF 0x28 /* Y-axis magnetometer, hard-iron factor */
-#define ADIS16400_ZMAGN_HIF 0x2A /* Z-axis magnetometer, hard-iron factor */
-#define ADIS16400_XMAGN_SIF 0x2C /* X-axis magnetometer, soft-iron factor */
-#define ADIS16400_YMAGN_SIF 0x2E /* Y-axis magnetometer, soft-iron factor */
-#define ADIS16400_ZMAGN_SIF 0x30 /* Z-axis magnetometer, soft-iron factor */
-
-#define ADIS16400_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
-#define ADIS16400_MSC_CTRL 0x34 /* Miscellaneous control */
-#define ADIS16400_SMPL_PRD 0x36 /* Internal sample period (rate) control */
-#define ADIS16400_SENS_AVG 0x38 /* Dynamic range and digital filter control */
-#define ADIS16400_SLP_CNT 0x3A /* Sleep mode control */
-#define ADIS16400_DIAG_STAT 0x3C /* System status */
-
-/* Alarm functions */
-#define ADIS16400_GLOB_CMD 0x3E /* System command */
-#define ADIS16400_ALM_MAG1 0x40 /* Alarm 1 amplitude threshold */
-#define ADIS16400_ALM_MAG2 0x42 /* Alarm 2 amplitude threshold */
-#define ADIS16400_ALM_SMPL1 0x44 /* Alarm 1 sample size */
-#define ADIS16400_ALM_SMPL2 0x46 /* Alarm 2 sample size */
-#define ADIS16400_ALM_CTRL 0x48 /* Alarm control */
-#define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */
-
-#define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
-
-#define ADIS16400_ERROR_ACTIVE (1<<14)
-#define ADIS16400_NEW_DATA (1<<14)
-
-/* MSC_CTRL */
-#define ADIS16400_MSC_CTRL_MEM_TEST (1<<11)
-#define ADIS16400_MSC_CTRL_INT_SELF_TEST (1<<10)
-#define ADIS16400_MSC_CTRL_NEG_SELF_TEST (1<<9)
-#define ADIS16400_MSC_CTRL_POS_SELF_TEST (1<<8)
-#define ADIS16400_MSC_CTRL_GYRO_BIAS (1<<7)
-#define ADIS16400_MSC_CTRL_ACCL_ALIGN (1<<6)
-#define ADIS16400_MSC_CTRL_DATA_RDY_EN (1<<2)
-#define ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
-#define ADIS16400_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
-
-/* SMPL_PRD */
-#define ADIS16400_SMPL_PRD_TIME_BASE (1<<7)
-#define ADIS16400_SMPL_PRD_DIV_MASK 0x7F
-
-/* DIAG_STAT */
-#define ADIS16400_DIAG_STAT_ZACCL_FAIL (1<<15)
-#define ADIS16400_DIAG_STAT_YACCL_FAIL (1<<14)
-#define ADIS16400_DIAG_STAT_XACCL_FAIL (1<<13)
-#define ADIS16400_DIAG_STAT_XGYRO_FAIL (1<<12)
-#define ADIS16400_DIAG_STAT_YGYRO_FAIL (1<<11)
-#define ADIS16400_DIAG_STAT_ZGYRO_FAIL (1<<10)
-#define ADIS16400_DIAG_STAT_ALARM2 (1<<9)
-#define ADIS16400_DIAG_STAT_ALARM1 (1<<8)
-#define ADIS16400_DIAG_STAT_FLASH_CHK (1<<6)
-#define ADIS16400_DIAG_STAT_SELF_TEST (1<<5)
-#define ADIS16400_DIAG_STAT_OVERFLOW (1<<4)
-#define ADIS16400_DIAG_STAT_SPI_FAIL (1<<3)
-#define ADIS16400_DIAG_STAT_FLASH_UPT (1<<2)
-#define ADIS16400_DIAG_STAT_POWER_HIGH (1<<1)
-#define ADIS16400_DIAG_STAT_POWER_LOW (1<<0)
-
-/* GLOB_CMD */
-#define ADIS16400_GLOB_CMD_SW_RESET (1<<7)
-#define ADIS16400_GLOB_CMD_P_AUTO_NULL (1<<4)
-#define ADIS16400_GLOB_CMD_FLASH_UPD (1<<3)
-#define ADIS16400_GLOB_CMD_DAC_LATCH (1<<2)
-#define ADIS16400_GLOB_CMD_FAC_CALIB (1<<1)
-#define ADIS16400_GLOB_CMD_AUTO_NULL (1<<0)
-
-/* SLP_CNT */
-#define ADIS16400_SLP_CNT_POWER_OFF (1<<8)
-
-#define ADIS16334_RATE_DIV_SHIFT 8
-#define ADIS16334_RATE_INT_CLK BIT(0)
-
-#define ADIS16400_MAX_TX 24
-#define ADIS16400_MAX_RX 24
-
-#define ADIS16400_SPI_SLOW (u32)(300 * 1000)
-#define ADIS16400_SPI_BURST (u32)(1000 * 1000)
-#define ADIS16400_SPI_FAST (u32)(2000 * 1000)
-
-#define ADIS16400_HAS_PROD_ID BIT(0)
-#define ADIS16400_NO_BURST BIT(1)
-#define ADIS16400_HAS_SLOW_MODE BIT(2)
-
-struct adis16400_chip_info {
- const struct iio_chan_spec *channels;
- const int num_channels;
- const long flags;
- unsigned int gyro_scale_micro;
- unsigned int accel_scale_micro;
- int temp_scale_nano;
- int temp_offset;
- unsigned long default_scan_mask;
- int (*set_freq)(struct iio_dev *indio_dev, unsigned int freq);
- int (*get_freq)(struct iio_dev *indio_dev);
-};
-
-/**
- * struct adis16400_state - device instance specific data
- * @us: actual spi_device
- * @trig: data ready trigger registered with iio
- * @tx: transmit buffer
- * @rx: receive buffer
- * @buf_lock: mutex to protect tx and rx
- * @filt_int: integer part of requested filter frequency
- **/
-struct adis16400_state {
- struct spi_device *us;
- struct iio_trigger *trig;
- struct mutex buf_lock;
- struct adis16400_chip_info *variant;
- int filt_int;
-
- u8 tx[ADIS16400_MAX_TX] ____cacheline_aligned;
- u8 rx[ADIS16400_MAX_RX] ____cacheline_aligned;
-};
-
-int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
-
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16400_SCAN_SUPPLY 0
-#define ADIS16400_SCAN_GYRO_X 1
-#define ADIS16400_SCAN_GYRO_Y 2
-#define ADIS16400_SCAN_GYRO_Z 3
-#define ADIS16400_SCAN_ACC_X 4
-#define ADIS16400_SCAN_ACC_Y 5
-#define ADIS16400_SCAN_ACC_Z 6
-#define ADIS16400_SCAN_MAGN_X 7
-#define ADIS16350_SCAN_TEMP_X 7
-#define ADIS16400_SCAN_MAGN_Y 8
-#define ADIS16350_SCAN_TEMP_Y 8
-#define ADIS16400_SCAN_MAGN_Z 9
-#define ADIS16350_SCAN_TEMP_Z 9
-#define ADIS16400_SCAN_TEMP 10
-#define ADIS16350_SCAN_ADC_0 10
-#define ADIS16400_SCAN_ADC_0 11
-#define ADIS16300_SCAN_INCLI_X 12
-#define ADIS16300_SCAN_INCLI_Y 13
-
-#ifdef CONFIG_IIO_BUFFER
-void adis16400_remove_trigger(struct iio_dev *indio_dev);
-int adis16400_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16400_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-
-
-int adis16400_configure_ring(struct iio_dev *indio_dev);
-void adis16400_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void adis16400_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16400_probe_trigger(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline ssize_t
-adis16400_read_data_from_ring(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static int adis16400_configure_ring(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
-#endif /* SPI_ADIS16400_H_ */
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
deleted file mode 100644
index 9c8f5ab..0000000
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ /dev/null
@@ -1,1320 +0,0 @@
-/*
- * adis16400.c support Analog Devices ADIS16400/5
- * 3d 2g Linear Accelerometers,
- * 3d Gyroscopes,
- * 3d Magnetometers via SPI
- *
- * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
- * 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
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#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/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-#include "adis16400.h"
-
-enum adis16400_chip_variant {
- ADIS16300,
- ADIS16334,
- ADIS16350,
- ADIS16360,
- ADIS16362,
- ADIS16364,
- ADIS16400,
-};
-
-/**
- * adis16400_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- */
-static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
- u8 reg_address,
- u8 val)
-{
- int ret;
- struct adis16400_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16400_WRITE_REG(reg_address);
- st->tx[1] = val;
-
- ret = spi_write(st->us, st->tx, 2);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16400_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: value to be written
- *
- * At the moment the spi framework doesn't allow global setting of cs_change.
- * This means that use cannot be made of spi_write.
- */
-static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 value)
-{
- int ret;
- struct spi_message msg;
- struct adis16400_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .tx_buf = st->tx + 2,
- .bits_per_word = 8,
- .len = 2,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16400_WRITE_REG(lower_reg_address);
- st->tx[1] = value & 0xFF;
- st->tx[2] = ADIS16400_WRITE_REG(lower_reg_address + 1);
- st->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(st->us, &msg);
- mutex_unlock(&st->buf_lock);
-
- return ret;
-}
-
-/**
- * adis16400_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @indio_dev: iio device
- * @reg_address: the address of the lower of the two registers. Second register
- * is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- *
- * At the moment the spi framework doesn't allow global setting of cs_change.
- * This means that use cannot be made of spi_read.
- **/
-static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
- u8 lower_reg_address,
- u16 *val)
-{
- struct spi_message msg;
- struct adis16400_state *st = iio_priv(indio_dev);
- int ret;
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- .cs_change = 1,
- }, {
- .rx_buf = st->rx,
- .bits_per_word = 8,
- .len = 2,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16400_READ_REG(lower_reg_address);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
- if (ret) {
- dev_err(&st->us->dev,
- "problem when reading 16 bit register 0x%02X",
- lower_reg_address);
- goto error_ret;
- }
- *val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static int adis16334_get_freq(struct iio_dev *indio_dev)
-{
- int ret;
- u16 t;
-
- ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t);
- if (ret < 0)
- return ret;
-
- t >>= ADIS16334_RATE_DIV_SHIFT;
-
- return (8192 >> t) / 10;
-}
-
-static int adis16334_set_freq(struct iio_dev *indio_dev, unsigned int freq)
-{
- unsigned int t;
-
- t = ilog2(8192 / (freq * 10));
-
- if (t > 0x31)
- t = 0x31;
-
- t <<= ADIS16334_RATE_DIV_SHIFT;
- t |= ADIS16334_RATE_INT_CLK;
-
- return adis16400_spi_write_reg_16(indio_dev, ADIS16400_SMPL_PRD, t);
-}
-
-static int adis16400_get_freq(struct iio_dev *indio_dev)
-{
- int sps, ret;
- u16 t;
-
- ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t);
- if (ret < 0)
- return ret;
- sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638;
- sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
-
- return sps;
-}
-
-static int adis16400_set_freq(struct iio_dev *indio_dev, unsigned int freq)
-{
- struct adis16400_state *st = iio_priv(indio_dev);
- unsigned int t;
-
- t = 1638 / freq;
- if (t > 0)
- t--;
- t &= ADIS16400_SMPL_PRD_DIV_MASK;
- if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
- st->us->max_speed_hz = ADIS16400_SPI_SLOW;
- else
- st->us->max_speed_hz = ADIS16400_SPI_FAST;
-
- return adis16400_spi_write_reg_8(indio_dev,
- ADIS16400_SMPL_PRD, t);
-}
-
-static ssize_t adis16400_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16400_state *st = iio_priv(indio_dev);
- int ret, len = 0;
-
- ret = st->variant->get_freq(indio_dev);
- if (ret < 0)
- return ret;
- len = sprintf(buf, "%d SPS\n", ret);
- return len;
-}
-
-static const unsigned adis16400_3db_divisors[] = {
- [0] = 2, /* Special case */
- [1] = 5,
- [2] = 10,
- [3] = 50,
- [4] = 200,
-};
-
-static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
-{
- int i, ret;
- u16 val16;
- for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 0; i--)
- if (sps/adis16400_3db_divisors[i] > val)
- break;
- if (i == -1)
- ret = -EINVAL;
- else {
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_SENS_AVG,
- &val16);
- if (ret < 0)
- goto error_ret;
-
- ret = adis16400_spi_write_reg_16(indio_dev,
- ADIS16400_SENS_AVG,
- (val16 & ~0x03) | i);
- }
-error_ret:
- return ret;
-}
-
-static ssize_t adis16400_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16400_state *st = iio_priv(indio_dev);
- long val;
- int ret;
-
- ret = strict_strtol(buf, 10, &val);
- if (ret)
- return ret;
- if (val == 0)
- return -EINVAL;
-
- mutex_lock(&indio_dev->mlock);
-
- st->variant->set_freq(indio_dev, val);
-
- /* Also update the filter */
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-static int adis16400_reset(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16400_spi_write_reg_8(indio_dev,
- ADIS16400_GLOB_CMD,
- ADIS16400_GLOB_CMD_SW_RESET);
- if (ret)
- dev_err(&indio_dev->dev, "problem resetting device");
-
- return ret;
-}
-
-int adis16400_set_irq(struct iio_dev *indio_dev, bool enable)
-{
- int ret;
- u16 msc;
-
- ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_MSC_CTRL, &msc);
- if (ret)
- goto error_ret;
-
- msc |= ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH;
- if (enable)
- msc |= ADIS16400_MSC_CTRL_DATA_RDY_EN;
- else
- msc &= ~ADIS16400_MSC_CTRL_DATA_RDY_EN;
-
- ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_MSC_CTRL, msc);
- if (ret)
- goto error_ret;
-
-error_ret:
- return ret;
-}
-
-/* Power down the device */
-static int adis16400_stop_device(struct iio_dev *indio_dev)
-{
- int ret;
- u16 val = ADIS16400_SLP_CNT_POWER_OFF;
-
- ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_SLP_CNT, val);
- if (ret)
- dev_err(&indio_dev->dev,
- "problem with turning device off: SLP_CNT");
-
- return ret;
-}
-
-static int adis16400_check_status(struct iio_dev *indio_dev)
-{
- u16 status;
- int ret;
- struct device *dev = &indio_dev->dev;
-
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_DIAG_STAT, &status);
-
- if (ret < 0) {
- dev_err(dev, "Reading status failed\n");
- goto error_ret;
- }
- ret = status;
- if (status & ADIS16400_DIAG_STAT_ZACCL_FAIL)
- dev_err(dev, "Z-axis accelerometer self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_YACCL_FAIL)
- dev_err(dev, "Y-axis accelerometer self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_XACCL_FAIL)
- dev_err(dev, "X-axis accelerometer self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_XGYRO_FAIL)
- dev_err(dev, "X-axis gyroscope self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_YGYRO_FAIL)
- dev_err(dev, "Y-axis gyroscope self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_ZGYRO_FAIL)
- dev_err(dev, "Z-axis gyroscope self-test failure\n");
- if (status & ADIS16400_DIAG_STAT_ALARM2)
- dev_err(dev, "Alarm 2 active\n");
- if (status & ADIS16400_DIAG_STAT_ALARM1)
- dev_err(dev, "Alarm 1 active\n");
- if (status & ADIS16400_DIAG_STAT_FLASH_CHK)
- dev_err(dev, "Flash checksum error\n");
- if (status & ADIS16400_DIAG_STAT_SELF_TEST)
- dev_err(dev, "Self test error\n");
- if (status & ADIS16400_DIAG_STAT_OVERFLOW)
- dev_err(dev, "Sensor overrange\n");
- if (status & ADIS16400_DIAG_STAT_SPI_FAIL)
- dev_err(dev, "SPI failure\n");
- if (status & ADIS16400_DIAG_STAT_FLASH_UPT)
- dev_err(dev, "Flash update failed\n");
- if (status & ADIS16400_DIAG_STAT_POWER_HIGH)
- dev_err(dev, "Power supply above 5.25V\n");
- if (status & ADIS16400_DIAG_STAT_POWER_LOW)
- dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
- return ret;
-}
-
-static int adis16400_self_test(struct iio_dev *indio_dev)
-{
- int ret;
- ret = adis16400_spi_write_reg_16(indio_dev,
- ADIS16400_MSC_CTRL,
- ADIS16400_MSC_CTRL_MEM_TEST);
- if (ret) {
- dev_err(&indio_dev->dev, "problem starting self test");
- goto err_ret;
- }
-
- msleep(ADIS16400_MTEST_DELAY);
- adis16400_check_status(indio_dev);
-
-err_ret:
- return ret;
-}
-
-static int adis16400_initial_setup(struct iio_dev *indio_dev)
-{
- int ret;
- u16 prod_id, smp_prd;
- unsigned int device_id;
- struct adis16400_state *st = iio_priv(indio_dev);
-
- /* use low spi speed for init if the device has a slow mode */
- if (st->variant->flags & ADIS16400_HAS_SLOW_MODE)
- st->us->max_speed_hz = ADIS16400_SPI_SLOW;
- else
- st->us->max_speed_hz = ADIS16400_SPI_FAST;
- st->us->mode = SPI_MODE_3;
- spi_setup(st->us);
-
- ret = adis16400_set_irq(indio_dev, false);
- if (ret) {
- dev_err(&indio_dev->dev, "disable irq failed");
- goto err_ret;
- }
-
- ret = adis16400_self_test(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "self test failure");
- goto err_ret;
- }
-
- ret = adis16400_check_status(indio_dev);
- if (ret) {
- adis16400_reset(indio_dev);
- dev_err(&indio_dev->dev, "device not playing ball -> reset");
- msleep(ADIS16400_STARTUP_DELAY);
- ret = adis16400_check_status(indio_dev);
- if (ret) {
- dev_err(&indio_dev->dev, "giving up");
- goto err_ret;
- }
- }
- if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_PRODUCT_ID, &prod_id);
- if (ret)
- goto err_ret;
-
- sscanf(indio_dev->name, "adis%u\n", &device_id);
-
- if (prod_id != device_id)
- dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
- device_id, prod_id);
-
- dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
- indio_dev->name, prod_id,
- st->us->chip_select, st->us->irq);
- }
- /* use high spi speed if possible */
- if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_SMPL_PRD, &smp_prd);
- if (ret)
- goto err_ret;
-
- if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
- st->us->max_speed_hz = ADIS16400_SPI_FAST;
- spi_setup(st->us);
- }
- }
-
-err_ret:
- return ret;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- adis16400_read_frequency,
- adis16400_write_frequency);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-
-enum adis16400_chan {
- in_supply,
- gyro_x,
- gyro_y,
- gyro_z,
- accel_x,
- accel_y,
- accel_z,
- magn_x,
- magn_y,
- magn_z,
- temp,
- temp0, temp1, temp2,
- in1,
- in2,
- incli_x,
- incli_y,
-};
-
-static u8 adis16400_addresses[18][2] = {
- [in_supply] = { ADIS16400_SUPPLY_OUT },
- [gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF },
- [gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF },
- [gyro_z] = { ADIS16400_ZGYRO_OUT, ADIS16400_ZGYRO_OFF },
- [accel_x] = { ADIS16400_XACCL_OUT, ADIS16400_XACCL_OFF },
- [accel_y] = { ADIS16400_YACCL_OUT, ADIS16400_YACCL_OFF },
- [accel_z] = { ADIS16400_ZACCL_OUT, ADIS16400_ZACCL_OFF },
- [magn_x] = { ADIS16400_XMAGN_OUT },
- [magn_y] = { ADIS16400_YMAGN_OUT },
- [magn_z] = { ADIS16400_ZMAGN_OUT },
- [temp] = { ADIS16400_TEMP_OUT },
- [temp0] = { ADIS16350_XTEMP_OUT },
- [temp1] = { ADIS16350_YTEMP_OUT },
- [temp2] = { ADIS16350_ZTEMP_OUT },
- [in1] = { ADIS16300_AUX_ADC },
- [in2] = { ADIS16400_AUX_ADC },
- [incli_x] = { ADIS16300_PITCH_OUT },
- [incli_y] = { ADIS16300_ROLL_OUT }
-};
-
-
-static int adis16400_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- struct adis16400_state *st = iio_priv(indio_dev);
- int ret, sps;
-
- switch (mask) {
- case IIO_CHAN_INFO_CALIBBIAS:
- mutex_lock(&indio_dev->mlock);
- ret = adis16400_spi_write_reg_16(indio_dev,
- adis16400_addresses[chan->address][1],
- val);
- mutex_unlock(&indio_dev->mlock);
- return ret;
- case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
- /* Need to cache values so we can update if the frequency
- changes */
- mutex_lock(&indio_dev->mlock);
- st->filt_int = val;
- /* Work out update to current value */
- sps = st->variant->get_freq(indio_dev);
- if (sps < 0) {
- mutex_unlock(&indio_dev->mlock);
- return sps;
- }
-
- ret = adis16400_set_filter(indio_dev, sps, val);
- mutex_unlock(&indio_dev->mlock);
- return ret;
- default:
- return -EINVAL;
- }
-}
-
-static int adis16400_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- struct adis16400_state *st = iio_priv(indio_dev);
- int ret, shift;
- s16 val16;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- ret = adis16400_spi_read_reg_16(indio_dev,
- adis16400_addresses[chan->address][0],
- &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- val16 &= (1 << chan->scan_type.realbits) - 1;
- if (chan->scan_type.sign == 's') {
- shift = 16 - chan->scan_type.realbits;
- val16 = (s16)(val16 << shift) >> shift;
- }
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- *val = 0;
- *val2 = st->variant->gyro_scale_micro;
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_VOLTAGE:
- *val = 0;
- if (chan->channel == 0) {
- *val = 2;
- *val2 = 418000; /* 2.418 mV */
- } else {
- *val = 0;
- *val2 = 805800; /* 805.8 uV */
- }
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_ACCEL:
- *val = 0;
- *val2 = st->variant->accel_scale_micro;
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_MAGN:
- *val = 0;
- *val2 = 500; /* 0.5 mgauss */
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_TEMP:
- *val = st->variant->temp_scale_nano / 1000000;
- *val2 = (st->variant->temp_scale_nano % 1000000);
- return IIO_VAL_INT_PLUS_MICRO;
- default:
- return -EINVAL;
- }
- case IIO_CHAN_INFO_CALIBBIAS:
- mutex_lock(&indio_dev->mlock);
- ret = adis16400_spi_read_reg_16(indio_dev,
- adis16400_addresses[chan->address][1],
- &val16);
- mutex_unlock(&indio_dev->mlock);
- if (ret)
- return ret;
- val16 = ((val16 & 0xFFF) << 4) >> 4;
- *val = val16;
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_OFFSET:
- /* currently only temperature */
- *val = st->variant->temp_offset;
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
- mutex_lock(&indio_dev->mlock);
- /* Need both the number of taps and the sampling frequency */
- ret = adis16400_spi_read_reg_16(indio_dev,
- ADIS16400_SENS_AVG,
- &val16);
- if (ret < 0) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- val16 = st->variant->get_freq(indio_dev);
- if (ret > 0)
- *val = ret/adis16400_3db_divisors[val16 & 0x03];
- *val2 = 0;
- mutex_unlock(&indio_dev->mlock);
- if (ret < 0)
- return ret;
- return IIO_VAL_INT_PLUS_MICRO;
- default:
- return -EINVAL;
- }
-}
-
-static const struct iio_chan_spec adis16400_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_x,
- .scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_y,
- .scan_index = ADIS16400_SCAN_GYRO_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_z,
- .scan_index = ADIS16400_SCAN_GYRO_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_x,
- .scan_index = ADIS16400_SCAN_ACC_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_y,
- .scan_index = ADIS16400_SCAN_ACC_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_z,
- .scan_index = ADIS16400_SCAN_ACC_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_MAGN,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = magn_x,
- .scan_index = ADIS16400_SCAN_MAGN_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_MAGN,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = magn_y,
- .scan_index = ADIS16400_SCAN_MAGN_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_MAGN,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = magn_z,
- .scan_index = ADIS16400_SCAN_MAGN_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = temp,
- .scan_index = ADIS16400_SCAN_TEMP,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in2,
- .scan_index = ADIS16400_SCAN_ADC_0,
- .scan_type = IIO_ST('s', 12, 16, 0),
- },
- IIO_CHAN_SOFT_TIMESTAMP(12)
-};
-
-static const struct iio_chan_spec adis16350_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 12, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_x,
- .scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_y,
- .scan_index = ADIS16400_SCAN_GYRO_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_z,
- .scan_index = ADIS16400_SCAN_GYRO_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_x,
- .scan_index = ADIS16400_SCAN_ACC_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_y,
- .scan_index = ADIS16400_SCAN_ACC_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_z,
- .scan_index = ADIS16400_SCAN_ACC_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .extend_name = "x",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = temp0,
- .scan_index = ADIS16350_SCAN_TEMP_X,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 1,
- .extend_name = "y",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = temp1,
- .scan_index = ADIS16350_SCAN_TEMP_Y,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 2,
- .extend_name = "z",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = temp2,
- .scan_index = ADIS16350_SCAN_TEMP_Z,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in1,
- .scan_index = ADIS16350_SCAN_ADC_0,
- .scan_type = IIO_ST('s', 12, 16, 0),
- },
- IIO_CHAN_SOFT_TIMESTAMP(11)
-};
-
-static const struct iio_chan_spec adis16300_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .extend_name = "supply",
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in_supply,
- .scan_index = ADIS16400_SCAN_SUPPLY,
- .scan_type = IIO_ST('u', 12, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_x,
- .scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_x,
- .scan_index = ADIS16400_SCAN_ACC_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_y,
- .scan_index = ADIS16400_SCAN_ACC_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_z,
- .scan_index = ADIS16400_SCAN_ACC_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = temp0,
- .scan_index = ADIS16400_SCAN_TEMP,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
- .address = in1,
- .scan_index = ADIS16350_SCAN_ADC_0,
- .scan_type = IIO_ST('s', 12, 16, 0),
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = incli_x,
- .scan_index = ADIS16300_SCAN_INCLI_X,
- .scan_type = IIO_ST('s', 13, 16, 0),
- }, {
- .type = IIO_INCLI,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = incli_y,
- .scan_index = ADIS16300_SCAN_INCLI_Y,
- .scan_type = IIO_ST('s', 13, 16, 0),
- },
- IIO_CHAN_SOFT_TIMESTAMP(14)
-};
-
-static const struct iio_chan_spec adis16334_channels[] = {
- {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_x,
- .scan_index = ADIS16400_SCAN_GYRO_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_y,
- .scan_index = ADIS16400_SCAN_GYRO_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ANGL_VEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = gyro_z,
- .scan_index = ADIS16400_SCAN_GYRO_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_x,
- .scan_index = ADIS16400_SCAN_ACC_X,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_y,
- .scan_index = ADIS16400_SCAN_ACC_Y,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
- .address = accel_z,
- .scan_index = ADIS16400_SCAN_ACC_Z,
- .scan_type = IIO_ST('s', 14, 16, 0),
- }, {
- .type = IIO_TEMP,
- .indexed = 1,
- .channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
- .address = temp0,
- .scan_index = ADIS16400_SCAN_TEMP,
- .scan_type = IIO_ST('s', 14, 16, 0),
- },
- IIO_CHAN_SOFT_TIMESTAMP(12)
-};
-
-static struct attribute *adis16400_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group adis16400_attribute_group = {
- .attrs = adis16400_attributes,
-};
-
-static struct adis16400_chip_info adis16400_chips[] = {
- [ADIS16300] = {
- .channels = adis16300_channels,
- .num_channels = ARRAY_SIZE(adis16300_channels),
- .flags = ADIS16400_HAS_SLOW_MODE,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = 5884,
- .temp_scale_nano = 140000000, /* 0.14 C */
- .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
- .default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) |
- (1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) |
- (1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) |
- (1 << ADIS16400_SCAN_TEMP) | (1 << ADIS16400_SCAN_ADC_0) |
- (1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) |
- (1 << 14),
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- },
- [ADIS16334] = {
- .channels = adis16334_channels,
- .num_channels = ARRAY_SIZE(adis16334_channels),
- .flags = ADIS16400_HAS_PROD_ID,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
- .temp_scale_nano = 67850000, /* 0.06785 C */
- .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
- .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) |
- (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) |
- (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) |
- (1 << ADIS16400_SCAN_ACC_Z),
- .set_freq = adis16334_set_freq,
- .get_freq = adis16334_get_freq,
- },
- [ADIS16350] = {
- .channels = adis16350_channels,
- .num_channels = ARRAY_SIZE(adis16350_channels),
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */
- .temp_scale_nano = 145300000, /* 0.1453 C */
- .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
- .default_scan_mask = 0x7FF,
- .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- },
- [ADIS16360] = {
- .channels = adis16350_channels,
- .num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
- .temp_scale_nano = 136000000, /* 0.136 C */
- .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
- .default_scan_mask = 0x7FF,
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- },
- [ADIS16362] = {
- .channels = adis16350_channels,
- .num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
- .temp_scale_nano = 136000000, /* 0.136 C */
- .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
- .default_scan_mask = 0x7FF,
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- },
- [ADIS16364] = {
- .channels = adis16350_channels,
- .num_channels = ARRAY_SIZE(adis16350_channels),
- .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
- .temp_scale_nano = 136000000, /* 0.136 C */
- .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
- .default_scan_mask = 0x7FF,
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- },
- [ADIS16400] = {
- .channels = adis16400_channels,
- .num_channels = ARRAY_SIZE(adis16400_channels),
- .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
- .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
- .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
- .default_scan_mask = 0xFFF,
- .temp_scale_nano = 140000000, /* 0.14 C */
- .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
- .set_freq = adis16400_set_freq,
- .get_freq = adis16400_get_freq,
- }
-};
-
-static const struct iio_info adis16400_info = {
- .driver_module = THIS_MODULE,
- .read_raw = &adis16400_read_raw,
- .write_raw = &adis16400_write_raw,
- .attrs = &adis16400_attribute_group,
-};
-
-static int adis16400_probe(struct spi_device *spi)
-{
- int ret;
- struct adis16400_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- /* this is only used for removal purposes */
- spi_set_drvdata(spi, indio_dev);
-
- st->us = spi;
- mutex_init(&st->buf_lock);
-
- /* setup the industrialio driver allocated elements */
- st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
- indio_dev->dev.parent = &spi->dev;
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->channels = st->variant->channels;
- indio_dev->num_channels = st->variant->num_channels;
- indio_dev->info = &adis16400_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- ret = adis16400_configure_ring(indio_dev);
- if (ret)
- goto error_free_dev;
-
- ret = iio_buffer_register(indio_dev,
- st->variant->channels,
- st->variant->num_channels);
- if (ret) {
- dev_err(&spi->dev, "failed to initialize the ring\n");
- goto error_unreg_ring_funcs;
- }
-
- if (spi->irq) {
- ret = adis16400_probe_trigger(indio_dev);
- if (ret)
- goto error_uninitialize_ring;
- }
-
- /* Get the device into a sane initial state */
- ret = adis16400_initial_setup(indio_dev);
- if (ret)
- goto error_remove_trigger;
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_remove_trigger;
-
- return 0;
-
-error_remove_trigger:
- if (spi->irq)
- adis16400_remove_trigger(indio_dev);
-error_uninitialize_ring:
- iio_buffer_unregister(indio_dev);
-error_unreg_ring_funcs:
- adis16400_unconfigure_ring(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-/* fixme, confirm ordering in this function */
-static int adis16400_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
- iio_device_unregister(indio_dev);
- adis16400_stop_device(indio_dev);
-
- adis16400_remove_trigger(indio_dev);
- iio_buffer_unregister(indio_dev);
- adis16400_unconfigure_ring(indio_dev);
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-static const struct spi_device_id adis16400_id[] = {
- {"adis16300", ADIS16300},
- {"adis16334", ADIS16334},
- {"adis16350", ADIS16350},
- {"adis16354", ADIS16350},
- {"adis16355", ADIS16350},
- {"adis16360", ADIS16360},
- {"adis16362", ADIS16362},
- {"adis16364", ADIS16364},
- {"adis16365", ADIS16360},
- {"adis16400", ADIS16400},
- {"adis16405", ADIS16400},
- {}
-};
-MODULE_DEVICE_TABLE(spi, adis16400_id);
-
-static struct spi_driver adis16400_driver = {
- .driver = {
- .name = "adis16400",
- .owner = THIS_MODULE,
- },
- .id_table = adis16400_id,
- .probe = adis16400_probe,
- .remove = adis16400_remove,
-};
-module_spi_driver(adis16400_driver);
-
-MODULE_AUTHOR("Manuel Stahl <manuel.stahl@iis.fraunhofer.de>");
-MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
deleted file mode 100644
index d46c1e3..0000000
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ /dev/null
@@ -1,204 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include "../ring_sw.h"
-#include <linux/iio/trigger_consumer.h>
-#include "adis16400.h"
-
-/**
- * adis16400_spi_read_burst() - read all data registers
- * @indio_dev: the IIO device
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int adis16400_spi_read_burst(struct iio_dev *indio_dev, u8 *rx)
-{
- struct spi_message msg;
- struct adis16400_state *st = iio_priv(indio_dev);
- u32 old_speed_hz = st->us->max_speed_hz;
- int ret;
-
- struct spi_transfer xfers[] = {
- {
- .tx_buf = st->tx,
- .bits_per_word = 8,
- .len = 2,
- }, {
- .rx_buf = rx,
- .bits_per_word = 8,
- .len = 24,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = ADIS16400_READ_REG(ADIS16400_GLOB_CMD);
- st->tx[1] = 0;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
-
- st->us->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz);
- spi_setup(st->us);
-
- ret = spi_sync(st->us, &msg);
- if (ret)
- dev_err(&st->us->dev, "problem when burst reading");
-
- st->us->max_speed_hz = old_speed_hz;
- spi_setup(st->us);
- mutex_unlock(&st->buf_lock);
- return ret;
-}
-
-static const u16 read_all_tx_array[] = {
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_SUPPLY_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XGYRO_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YGYRO_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZGYRO_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XACCL_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YACCL_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZACCL_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16350_XTEMP_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16350_YTEMP_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16350_ZTEMP_OUT)),
- cpu_to_be16(ADIS16400_READ_REG(ADIS16400_AUX_ADC)),
-};
-
-static int adis16350_spi_read_all(struct iio_dev *indio_dev, u8 *rx)
-{
- struct adis16400_state *st = iio_priv(indio_dev);
-
- struct spi_message msg;
- int i, j = 0, ret;
- struct spi_transfer *xfers;
- int scan_count = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength);
-
- xfers = kzalloc(sizeof(*xfers)*(scan_count + 1),
- GFP_KERNEL);
- if (xfers == NULL)
- return -ENOMEM;
-
- for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
- if (test_bit(i, indio_dev->active_scan_mask)) {
- xfers[j].tx_buf = &read_all_tx_array[i];
- xfers[j].bits_per_word = 16;
- xfers[j].len = 2;
- xfers[j + 1].rx_buf = rx + j*2;
- j++;
- }
- xfers[j].bits_per_word = 16;
- xfers[j].len = 2;
-
- spi_message_init(&msg);
- for (j = 0; j < scan_count + 1; j++)
- spi_message_add_tail(&xfers[j], &msg);
-
- ret = spi_sync(st->us, &msg);
- kfree(xfers);
-
- return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static irqreturn_t adis16400_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct adis16400_state *st = iio_priv(indio_dev);
- int i = 0, j, ret = 0;
- s16 *data;
-
- /* Asumption that long is enough for maximum channels */
- unsigned long mask = *indio_dev->active_scan_mask;
- int scan_count = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength);
- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&st->us->dev, "memory alloc failed in ring bh");
- goto done;
- }
-
- if (scan_count) {
- if (st->variant->flags & ADIS16400_NO_BURST) {
- ret = adis16350_spi_read_all(indio_dev, st->rx);
- if (ret < 0)
- goto done;
- for (; i < scan_count; i++)
- data[i] = *(s16 *)(st->rx + i*2);
- } else {
- ret = adis16400_spi_read_burst(indio_dev, st->rx);
- if (ret < 0)
- goto done;
- for (; i < scan_count; i++) {
- j = __ffs(mask);
- mask &= ~(1 << j);
- data[i] = be16_to_cpup(
- (__be16 *)&(st->rx[j*2]));
- }
- }
- }
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- iio_push_to_buffers(indio_dev, (u8 *) data);
-
-done:
- kfree(data);
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
-}
-
-static const struct iio_buffer_setup_ops adis16400_ring_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
-};
-
-int adis16400_configure_ring(struct iio_dev *indio_dev)
-{
- int ret = 0;
- struct iio_buffer *ring;
-
- ring = iio_sw_rb_allocate(indio_dev);
- if (!ring) {
- ret = -ENOMEM;
- return ret;
- }
- indio_dev->buffer = ring;
- ring->scan_timestamp = true;
- indio_dev->setup_ops = &adis16400_ring_setup_ops;
-
- indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
- &adis16400_trigger_handler,
- IRQF_ONESHOT,
- indio_dev,
- "%s_consumer%d",
- indio_dev->name,
- indio_dev->id);
- if (indio_dev->pollfunc == NULL) {
- ret = -ENOMEM;
- goto error_iio_sw_rb_free;
- }
-
- indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
- return 0;
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
- return ret;
-}
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
deleted file mode 100644
index 42a678e..0000000
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#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 "adis16400.h"
-
-/**
- * adis16400_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
-{
- struct iio_dev *indio_dev = trig->private_data;
-
- dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
- return adis16400_set_irq(indio_dev, state);
-}
-
-static const struct iio_trigger_ops adis16400_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &adis16400_data_rdy_trigger_set_state,
-};
-
-int adis16400_probe_trigger(struct iio_dev *indio_dev)
-{
- int ret;
- struct adis16400_state *st = iio_priv(indio_dev);
-
- st->trig = iio_trigger_alloc("%s-dev%d",
- indio_dev->name,
- indio_dev->id);
- if (st->trig == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- ret = request_irq(st->us->irq,
- &iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING,
- "adis16400",
- st->trig);
- if (ret)
- goto error_free_trig;
- st->trig->dev.parent = &st->us->dev;
- st->trig->private_data = indio_dev;
- st->trig->ops = &adis16400_trigger_ops;
- 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->us->irq, st->trig);
-error_free_trig:
- iio_trigger_free(st->trig);
-error_ret:
- return ret;
-}
-
-void adis16400_remove_trigger(struct iio_dev *indio_dev)
-{
- struct adis16400_state *st = iio_priv(indio_dev);
-
- iio_trigger_unregister(st->trig);
- free_irq(st->us->irq, st->trig);
- iio_trigger_free(st->trig);
-}
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
index 4bed30e..ca8d6e6 100644
--- a/drivers/staging/iio/light/Kconfig
+++ b/drivers/staging/iio/light/Kconfig
@@ -25,16 +25,6 @@ config SENSORS_ISL29028
Proximity value via iio. The ISL29028 provides the concurrent sensing
of ambient light and proximity.
-config SENSORS_TSL2563
- tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
- depends on I2C
- help
- If you say yes here you get support for the Taos TSL2560,
- TSL2561, TSL2562 and TSL2563 ambient light sensors.
-
- This driver can also be built as a module. If so, the module
- will be called tsl2563.
-
config TSL2583
tristate "TAOS TSL2580, TSL2581 and TSL2583 light-to-digital converters"
depends on I2C
diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile
index 141af1e..9960fdf 100644
--- a/drivers/staging/iio/light/Makefile
+++ b/drivers/staging/iio/light/Makefile
@@ -2,7 +2,6 @@
# Makefile for industrial I/O Light sensors
#
-obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
obj-$(CONFIG_TSL2583) += tsl2583.o
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
deleted file mode 100644
index 1a9adc0..0000000
--- a/drivers/staging/iio/light/tsl2563.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * drivers/i2c/chips/tsl2563.c
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Written by Timo O. Karjalainen <timo.o.karjalainen@nokia.com>
- * Contact: Amit Kucheria <amit.kucheria@verdurent.com>
- *
- * Converted to IIO driver
- * Amit Kucheria <amit.kucheria@verdurent.com>
- *
- * 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 published by the Free Software Foundation.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include "tsl2563.h"
-
-/* Use this many bits for fraction part. */
-#define ADC_FRAC_BITS (14)
-
-/* Given number of 1/10000's in ADC_FRAC_BITS precision. */
-#define FRAC10K(f) (((f) * (1L << (ADC_FRAC_BITS))) / (10000))
-
-/* Bits used for fraction in calibration coefficients.*/
-#define CALIB_FRAC_BITS (10)
-/* 0.5 in CALIB_FRAC_BITS precision */
-#define CALIB_FRAC_HALF (1 << (CALIB_FRAC_BITS - 1))
-/* Make a fraction from a number n that was multiplied with b. */
-#define CALIB_FRAC(n, b) (((n) << CALIB_FRAC_BITS) / (b))
-/* Decimal 10^(digits in sysfs presentation) */
-#define CALIB_BASE_SYSFS (1000)
-
-#define TSL2563_CMD (0x80)
-#define TSL2563_CLEARINT (0x40)
-
-#define TSL2563_REG_CTRL (0x00)
-#define TSL2563_REG_TIMING (0x01)
-#define TSL2563_REG_LOWLOW (0x02) /* data0 low threshold, 2 bytes */
-#define TSL2563_REG_LOWHIGH (0x03)
-#define TSL2563_REG_HIGHLOW (0x04) /* data0 high threshold, 2 bytes */
-#define TSL2563_REG_HIGHHIGH (0x05)
-#define TSL2563_REG_INT (0x06)
-#define TSL2563_REG_ID (0x0a)
-#define TSL2563_REG_DATA0LOW (0x0c) /* broadband sensor value, 2 bytes */
-#define TSL2563_REG_DATA0HIGH (0x0d)
-#define TSL2563_REG_DATA1LOW (0x0e) /* infrared sensor value, 2 bytes */
-#define TSL2563_REG_DATA1HIGH (0x0f)
-
-#define TSL2563_CMD_POWER_ON (0x03)
-#define TSL2563_CMD_POWER_OFF (0x00)
-#define TSL2563_CTRL_POWER_MASK (0x03)
-
-#define TSL2563_TIMING_13MS (0x00)
-#define TSL2563_TIMING_100MS (0x01)
-#define TSL2563_TIMING_400MS (0x02)
-#define TSL2563_TIMING_MASK (0x03)
-#define TSL2563_TIMING_GAIN16 (0x10)
-#define TSL2563_TIMING_GAIN1 (0x00)
-
-#define TSL2563_INT_DISBLED (0x00)
-#define TSL2563_INT_LEVEL (0x10)
-#define TSL2563_INT_PERSIST(n) ((n) & 0x0F)
-
-struct tsl2563_gainlevel_coeff {
- u8 gaintime;
- u16 min;
- u16 max;
-};
-
-static const struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
- {
- .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN16,
- .min = 0,
- .max = 65534,
- }, {
- .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN1,
- .min = 2048,
- .max = 65534,
- }, {
- .gaintime = TSL2563_TIMING_100MS | TSL2563_TIMING_GAIN1,
- .min = 4095,
- .max = 37177,
- }, {
- .gaintime = TSL2563_TIMING_13MS | TSL2563_TIMING_GAIN1,
- .min = 3000,
- .max = 65535,
- },
-};
-
-struct tsl2563_chip {
- struct mutex lock;
- struct i2c_client *client;
- struct delayed_work poweroff_work;
-
- /* Remember state for suspend and resume functions */
- bool suspended;
-
- struct tsl2563_gainlevel_coeff const *gainlevel;
-
- u16 low_thres;
- u16 high_thres;
- u8 intr;
- bool int_enabled;
-
- /* Calibration coefficients */
- u32 calib0;
- u32 calib1;
- int cover_comp_gain;
-
- /* Cache current values, to be returned while suspended */
- u32 data0;
- u32 data1;
-};
-
-static int tsl2563_set_power(struct tsl2563_chip *chip, int on)
-{
- struct i2c_client *client = chip->client;
- u8 cmd;
-
- cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF;
- return i2c_smbus_write_byte_data(client,
- TSL2563_CMD | TSL2563_REG_CTRL, cmd);
-}
-
-/*
- * Return value is 0 for off, 1 for on, or a negative error
- * code if reading failed.
- */
-static int tsl2563_get_power(struct tsl2563_chip *chip)
-{
- struct i2c_client *client = chip->client;
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_CTRL);
- if (ret < 0)
- return ret;
-
- return (ret & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON;
-}
-
-static int tsl2563_configure(struct tsl2563_chip *chip)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_TIMING,
- chip->gainlevel->gaintime);
- if (ret)
- goto error_ret;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_HIGHLOW,
- chip->high_thres & 0xFF);
- if (ret)
- goto error_ret;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_HIGHHIGH,
- (chip->high_thres >> 8) & 0xFF);
- if (ret)
- goto error_ret;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_LOWLOW,
- chip->low_thres & 0xFF);
- if (ret)
- goto error_ret;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_LOWHIGH,
- (chip->low_thres >> 8) & 0xFF);
-/* Interrupt register is automatically written anyway if it is relevant
- so is not here */
-error_ret:
- return ret;
-}
-
-static void tsl2563_poweroff_work(struct work_struct *work)
-{
- struct tsl2563_chip *chip =
- container_of(work, struct tsl2563_chip, poweroff_work.work);
- tsl2563_set_power(chip, 0);
-}
-
-static int tsl2563_detect(struct tsl2563_chip *chip)
-{
- int ret;
-
- ret = tsl2563_set_power(chip, 1);
- if (ret)
- return ret;
-
- ret = tsl2563_get_power(chip);
- if (ret < 0)
- return ret;
-
- return ret ? 0 : -ENODEV;
-}
-
-static int tsl2563_read_id(struct tsl2563_chip *chip, u8 *id)
-{
- struct i2c_client *client = chip->client;
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_ID);
- if (ret < 0)
- return ret;
-
- *id = ret;
-
- return 0;
-}
-
-/*
- * "Normalized" ADC value is one obtained with 400ms of integration time and
- * 16x gain. This function returns the number of bits of shift needed to
- * convert between normalized values and HW values obtained using given
- * timing and gain settings.
- */
-static int adc_shiftbits(u8 timing)
-{
- int shift = 0;
-
- switch (timing & TSL2563_TIMING_MASK) {
- case TSL2563_TIMING_13MS:
- shift += 5;
- break;
- case TSL2563_TIMING_100MS:
- shift += 2;
- break;
- case TSL2563_TIMING_400MS:
- /* no-op */
- break;
- }
-
- if (!(timing & TSL2563_TIMING_GAIN16))
- shift += 4;
-
- return shift;
-}
-
-/* Convert a HW ADC value to normalized scale. */
-static u32 normalize_adc(u16 adc, u8 timing)
-{
- return adc << adc_shiftbits(timing);
-}
-
-static void tsl2563_wait_adc(struct tsl2563_chip *chip)
-{
- unsigned int delay;
-
- switch (chip->gainlevel->gaintime & TSL2563_TIMING_MASK) {
- case TSL2563_TIMING_13MS:
- delay = 14;
- break;
- case TSL2563_TIMING_100MS:
- delay = 101;
- break;
- default:
- delay = 402;
- }
- /*
- * TODO: Make sure that we wait at least required delay but why we
- * have to extend it one tick more?
- */
- schedule_timeout_interruptible(msecs_to_jiffies(delay) + 2);
-}
-
-static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc)
-{
- struct i2c_client *client = chip->client;
-
- if (adc > chip->gainlevel->max || adc < chip->gainlevel->min) {
-
- (adc > chip->gainlevel->max) ?
- chip->gainlevel++ : chip->gainlevel--;
-
- i2c_smbus_write_byte_data(client,
- TSL2563_CMD | TSL2563_REG_TIMING,
- chip->gainlevel->gaintime);
-
- tsl2563_wait_adc(chip);
- tsl2563_wait_adc(chip);
-
- return 1;
- } else
- return 0;
-}
-
-static int tsl2563_get_adc(struct tsl2563_chip *chip)
-{
- struct i2c_client *client = chip->client;
- u16 adc0, adc1;
- int retry = 1;
- int ret = 0;
-
- if (chip->suspended)
- goto out;
-
- if (!chip->int_enabled) {
- cancel_delayed_work(&chip->poweroff_work);
-
- if (!tsl2563_get_power(chip)) {
- ret = tsl2563_set_power(chip, 1);
- if (ret)
- goto out;
- ret = tsl2563_configure(chip);
- if (ret)
- goto out;
- tsl2563_wait_adc(chip);
- }
- }
-
- while (retry) {
- ret = i2c_smbus_read_word_data(client,
- TSL2563_CMD | TSL2563_REG_DATA0LOW);
- if (ret < 0)
- goto out;
- adc0 = ret;
-
- ret = i2c_smbus_read_word_data(client,
- TSL2563_CMD | TSL2563_REG_DATA1LOW);
- if (ret < 0)
- goto out;
- adc1 = ret;
-
- retry = tsl2563_adjust_gainlevel(chip, adc0);
- }
-
- chip->data0 = normalize_adc(adc0, chip->gainlevel->gaintime);
- chip->data1 = normalize_adc(adc1, chip->gainlevel->gaintime);
-
- if (!chip->int_enabled)
- schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
-
- ret = 0;
-out:
- return ret;
-}
-
-static inline int calib_to_sysfs(u32 calib)
-{
- return (int) (((calib * CALIB_BASE_SYSFS) +
- CALIB_FRAC_HALF) >> CALIB_FRAC_BITS);
-}
-
-static inline u32 calib_from_sysfs(int value)
-{
- return (((u32) value) << CALIB_FRAC_BITS) / CALIB_BASE_SYSFS;
-}
-
-/*
- * Conversions between lux and ADC values.
- *
- * The basic formula is lux = c0 * adc0 - c1 * adc1, where c0 and c1 are
- * appropriate constants. Different constants are needed for different
- * kinds of light, determined by the ratio adc1/adc0 (basically the ratio
- * of the intensities in infrared and visible wavelengths). lux_table below
- * lists the upper threshold of the adc1/adc0 ratio and the corresponding
- * constants.
- */
-
-struct tsl2563_lux_coeff {
- unsigned long ch_ratio;
- unsigned long ch0_coeff;
- unsigned long ch1_coeff;
-};
-
-static const struct tsl2563_lux_coeff lux_table[] = {
- {
- .ch_ratio = FRAC10K(1300),
- .ch0_coeff = FRAC10K(315),
- .ch1_coeff = FRAC10K(262),
- }, {
- .ch_ratio = FRAC10K(2600),
- .ch0_coeff = FRAC10K(337),
- .ch1_coeff = FRAC10K(430),
- }, {
- .ch_ratio = FRAC10K(3900),
- .ch0_coeff = FRAC10K(363),
- .ch1_coeff = FRAC10K(529),
- }, {
- .ch_ratio = FRAC10K(5200),
- .ch0_coeff = FRAC10K(392),
- .ch1_coeff = FRAC10K(605),
- }, {
- .ch_ratio = FRAC10K(6500),
- .ch0_coeff = FRAC10K(229),
- .ch1_coeff = FRAC10K(291),
- }, {
- .ch_ratio = FRAC10K(8000),
- .ch0_coeff = FRAC10K(157),
- .ch1_coeff = FRAC10K(180),
- }, {
- .ch_ratio = FRAC10K(13000),
- .ch0_coeff = FRAC10K(34),
- .ch1_coeff = FRAC10K(26),
- }, {
- .ch_ratio = ULONG_MAX,
- .ch0_coeff = 0,
- .ch1_coeff = 0,
- },
-};
-
-/*
- * Convert normalized, scaled ADC values to lux.
- */
-static unsigned int adc_to_lux(u32 adc0, u32 adc1)
-{
- const struct tsl2563_lux_coeff *lp = lux_table;
- unsigned long ratio, lux, ch0 = adc0, ch1 = adc1;
-
- ratio = ch0 ? ((ch1 << ADC_FRAC_BITS) / ch0) : ULONG_MAX;
-
- while (lp->ch_ratio < ratio)
- lp++;
-
- lux = ch0 * lp->ch0_coeff - ch1 * lp->ch1_coeff;
-
- return (unsigned int) (lux >> ADC_FRAC_BITS);
-}
-
-/*--------------------------------------------------------------*/
-/* Sysfs interface */
-/*--------------------------------------------------------------*/
-
-
-/* Apply calibration coefficient to ADC count. */
-static u32 calib_adc(u32 adc, u32 calib)
-{
- unsigned long scaled = adc;
-
- scaled *= calib;
- scaled >>= CALIB_FRAC_BITS;
-
- return (u32) scaled;
-}
-
-static int tsl2563_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- struct tsl2563_chip *chip = iio_priv(indio_dev);
-
- if (chan->channel == IIO_MOD_LIGHT_BOTH)
- chip->calib0 = calib_from_sysfs(val);
- else
- chip->calib1 = calib_from_sysfs(val);
-
- return 0;
-}
-
-static int tsl2563_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long m)
-{
- int ret = -EINVAL;
- u32 calib0, calib1;
- struct tsl2563_chip *chip = iio_priv(indio_dev);
-
- mutex_lock(&chip->lock);
- switch (m) {
- case IIO_CHAN_INFO_RAW:
- case IIO_CHAN_INFO_PROCESSED:
- switch (chan->type) {
- case IIO_LIGHT:
- ret = tsl2563_get_adc(chip);
- if (ret)
- goto error_ret;
- calib0 = calib_adc(chip->data0, chip->calib0) *
- chip->cover_comp_gain;
- calib1 = calib_adc(chip->data1, chip->calib1) *
- chip->cover_comp_gain;
- *val = adc_to_lux(calib0, calib1);
- ret = IIO_VAL_INT;
- break;
- case IIO_INTENSITY:
- ret = tsl2563_get_adc(chip);
- if (ret)
- goto error_ret;
- if (chan->channel == 0)
- *val = chip->data0;
- else
- *val = chip->data1;
- ret = IIO_VAL_INT;
- break;
- default:
- break;
- }
- break;
-
- case IIO_CHAN_INFO_CALIBSCALE:
- if (chan->channel == 0)
- *val = calib_to_sysfs(chip->calib0);
- else
- *val = calib_to_sysfs(chip->calib1);
- ret = IIO_VAL_INT;
- break;
- default:
- ret = -EINVAL;
- goto error_ret;
- }
-
-error_ret:
- mutex_unlock(&chip->lock);
- return ret;
-}
-
-static const struct iio_chan_spec tsl2563_channels[] = {
- {
- .type = IIO_LIGHT,
- .indexed = 1,
- .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT,
- .channel = 0,
- }, {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_BOTH,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
- .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_FALLING)),
- }, {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_IR,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
- }
-};
-
-static int tsl2563_read_thresh(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
-{
- struct tsl2563_chip *chip = iio_priv(indio_dev);
-
- switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
- case IIO_EV_DIR_RISING:
- *val = chip->high_thres;
- break;
- case IIO_EV_DIR_FALLING:
- *val = chip->low_thres;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int tsl2563_write_thresh(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
-{
- struct tsl2563_chip *chip = iio_priv(indio_dev);
- int ret;
- u8 address;
-
- if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
- address = TSL2563_REG_HIGHLOW;
- else
- address = TSL2563_REG_LOWLOW;
- mutex_lock(&chip->lock);
- ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | address,
- val & 0xFF);
- if (ret)
- goto error_ret;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | (address + 1),
- (val >> 8) & 0xFF);
- if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
- chip->high_thres = val;
- else
- chip->low_thres = val;
-
-error_ret:
- mutex_unlock(&chip->lock);
-
- return ret;
-}
-
-static irqreturn_t tsl2563_event_handler(int irq, void *private)
-{
- struct iio_dev *dev_info = private;
- struct tsl2563_chip *chip = iio_priv(dev_info);
-
- iio_push_event(dev_info,
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
- 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_EITHER),
- iio_get_time_ns());
-
- /* clear the interrupt and push the event */
- i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT);
- return IRQ_HANDLED;
-}
-
-static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
- u64 event_code,
- int state)
-{
- struct tsl2563_chip *chip = iio_priv(indio_dev);
- int ret = 0;
-
- mutex_lock(&chip->lock);
- if (state && !(chip->intr & 0x30)) {
- chip->intr &= ~0x30;
- chip->intr |= 0x10;
- /* ensure the chip is actually on */
- cancel_delayed_work(&chip->poweroff_work);
- if (!tsl2563_get_power(chip)) {
- ret = tsl2563_set_power(chip, 1);
- if (ret)
- goto out;
- ret = tsl2563_configure(chip);
- if (ret)
- goto out;
- }
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_INT,
- chip->intr);
- chip->int_enabled = true;
- }
-
- if (!state && (chip->intr & 0x30)) {
- chip->intr &= ~0x30;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_INT,
- chip->intr);
- chip->int_enabled = false;
- /* now the interrupt is not enabled, we can go to sleep */
- schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
- }
-out:
- mutex_unlock(&chip->lock);
-
- return ret;
-}
-
-static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
- u64 event_code)
-{
- struct tsl2563_chip *chip = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&chip->lock);
- ret = i2c_smbus_read_byte_data(chip->client,
- TSL2563_CMD | TSL2563_REG_INT);
- mutex_unlock(&chip->lock);
- if (ret < 0)
- goto error_ret;
- ret = !!(ret & 0x30);
-error_ret:
-
- return ret;
-}
-
-/*--------------------------------------------------------------*/
-/* Probe, Attach, Remove */
-/*--------------------------------------------------------------*/
-static struct i2c_driver tsl2563_i2c_driver;
-
-static const struct iio_info tsl2563_info_no_irq = {
- .driver_module = THIS_MODULE,
- .read_raw = &tsl2563_read_raw,
- .write_raw = &tsl2563_write_raw,
-};
-
-static const struct iio_info tsl2563_info = {
- .driver_module = THIS_MODULE,
- .read_raw = &tsl2563_read_raw,
- .write_raw = &tsl2563_write_raw,
- .read_event_value = &tsl2563_read_thresh,
- .write_event_value = &tsl2563_write_thresh,
- .read_event_config = &tsl2563_read_interrupt_config,
- .write_event_config = &tsl2563_write_interrupt_config,
-};
-
-static int tsl2563_probe(struct i2c_client *client,
- const struct i2c_device_id *device_id)
-{
- struct iio_dev *indio_dev;
- struct tsl2563_chip *chip;
- struct tsl2563_platform_data *pdata = client->dev.platform_data;
- int err = 0;
- u8 id = 0;
-
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
-
- chip = iio_priv(indio_dev);
-
- i2c_set_clientdata(client, chip);
- chip->client = client;
-
- err = tsl2563_detect(chip);
- if (err) {
- dev_err(&client->dev, "detect error %d\n", -err);
- goto fail1;
- }
-
- err = tsl2563_read_id(chip, &id);
- if (err) {
- dev_err(&client->dev, "read id error %d\n", -err);
- goto fail1;
- }
-
- mutex_init(&chip->lock);
-
- /* Default values used until userspace says otherwise */
- chip->low_thres = 0x0;
- chip->high_thres = 0xffff;
- chip->gainlevel = tsl2563_gainlevel_table;
- chip->intr = TSL2563_INT_PERSIST(4);
- chip->calib0 = calib_from_sysfs(CALIB_BASE_SYSFS);
- chip->calib1 = calib_from_sysfs(CALIB_BASE_SYSFS);
-
- if (pdata)
- chip->cover_comp_gain = pdata->cover_comp_gain;
- else
- chip->cover_comp_gain = 1;
-
- dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
- indio_dev->name = client->name;
- indio_dev->channels = tsl2563_channels;
- indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
- indio_dev->dev.parent = &client->dev;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- if (client->irq)
- indio_dev->info = &tsl2563_info;
- else
- indio_dev->info = &tsl2563_info_no_irq;
-
- if (client->irq) {
- err = request_threaded_irq(client->irq,
- NULL,
- &tsl2563_event_handler,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT,
- "tsl2563_event",
- indio_dev);
- if (err) {
- dev_err(&client->dev, "irq request error %d\n", -err);
- goto fail1;
- }
- }
-
- err = tsl2563_configure(chip);
- if (err) {
- dev_err(&client->dev, "configure error %d\n", -err);
- goto fail2;
- }
-
- INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
-
- /* The interrupt cannot yet be enabled so this is fine without lock */
- schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
-
- err = iio_device_register(indio_dev);
- if (err) {
- dev_err(&client->dev, "iio registration error %d\n", -err);
- goto fail3;
- }
-
- return 0;
-
-fail3:
- cancel_delayed_work(&chip->poweroff_work);
- flush_scheduled_work();
-fail2:
- if (client->irq)
- free_irq(client->irq, indio_dev);
-fail1:
- iio_device_free(indio_dev);
- return err;
-}
-
-static int tsl2563_remove(struct i2c_client *client)
-{
- struct tsl2563_chip *chip = i2c_get_clientdata(client);
- struct iio_dev *indio_dev = iio_priv_to_dev(chip);
-
- iio_device_unregister(indio_dev);
- if (!chip->int_enabled)
- cancel_delayed_work(&chip->poweroff_work);
- /* Ensure that interrupts are disabled - then flush any bottom halves */
- chip->intr &= ~0x30;
- i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT,
- chip->intr);
- flush_scheduled_work();
- tsl2563_set_power(chip, 0);
- if (client->irq)
- free_irq(client->irq, indio_dev);
-
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int tsl2563_suspend(struct device *dev)
-{
- struct tsl2563_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
- int ret;
-
- mutex_lock(&chip->lock);
-
- ret = tsl2563_set_power(chip, 0);
- if (ret)
- goto out;
-
- chip->suspended = true;
-
-out:
- mutex_unlock(&chip->lock);
- return ret;
-}
-
-static int tsl2563_resume(struct device *dev)
-{
- struct tsl2563_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
- int ret;
-
- mutex_lock(&chip->lock);
-
- ret = tsl2563_set_power(chip, 1);
- if (ret)
- goto out;
-
- ret = tsl2563_configure(chip);
- if (ret)
- goto out;
-
- chip->suspended = false;
-
-out:
- mutex_unlock(&chip->lock);
- return ret;
-}
-
-static SIMPLE_DEV_PM_OPS(tsl2563_pm_ops, tsl2563_suspend, tsl2563_resume);
-#define TSL2563_PM_OPS (&tsl2563_pm_ops)
-#else
-#define TSL2563_PM_OPS NULL
-#endif
-
-static const struct i2c_device_id tsl2563_id[] = {
- { "tsl2560", 0 },
- { "tsl2561", 1 },
- { "tsl2562", 2 },
- { "tsl2563", 3 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, tsl2563_id);
-
-static struct i2c_driver tsl2563_i2c_driver = {
- .driver = {
- .name = "tsl2563",
- .pm = TSL2563_PM_OPS,
- },
- .probe = tsl2563_probe,
- .remove = tsl2563_remove,
- .id_table = tsl2563_id,
-};
-module_i2c_driver(tsl2563_i2c_driver);
-
-MODULE_AUTHOR("Nokia Corporation");
-MODULE_DESCRIPTION("tsl2563 light sensor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/light/tsl2563.h b/drivers/staging/iio/light/tsl2563.h
deleted file mode 100644
index b97368b..0000000
--- a/drivers/staging/iio/light/tsl2563.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __LINUX_TSL2563_H
-#define __LINUX_TSL2563_H
-
-struct tsl2563_platform_data {
- int cover_comp_gain;
-};
-
-#endif /* __LINUX_TSL2563_H */
-
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 9e50fbb..a58731e 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -292,59 +292,6 @@ static const u8 device_channel_config[] = {
};
/**
- * tsl2x7x_parse_buffer() - parse a decimal result from a buffer.
- * @*buf: pointer to char buffer to parse
- * @*result: pointer to buffer to contain
- * resulting interger / decimal as ints.
- *
- */
-static int
-tsl2x7x_parse_buffer(const char *buf, struct tsl2x7x_parse_result *result)
-{
- int integer = 0, fract = 0, fract_mult = 100000;
- bool integer_part = true, negative = false;
-
- if (buf[0] == '-') {
- negative = true;
- buf++;
- }
-
- while (*buf) {
- if ('0' <= *buf && *buf <= '9') {
- if (integer_part)
- integer = integer*10 + *buf - '0';
- else {
- fract += fract_mult*(*buf - '0');
- if (fract_mult == 1)
- break;
- fract_mult /= 10;
- }
- } else if (*buf == '\n') {
- if (*(buf + 1) == '\0')
- break;
- else
- return -EINVAL;
- } else if (*buf == '.') {
- integer_part = false;
- } else {
- return -EINVAL;
- }
- buf++;
- }
- if (negative) {
- if (integer)
- integer = -integer;
- else
- fract = -fract;
- }
-
- result->integer = integer;
- result->fract = fract;
-
- return 0;
-}
-
-/**
* tsl2x7x_i2c_read() - Read a byte from a register.
* @client: i2c client
* @reg: device register to read from
@@ -1036,13 +983,12 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
+ int ret;
- result.integer = 0;
- result.fract = 0;
-
- tsl2x7x_parse_buffer(buf, &result);
+ ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
+ if (ret)
+ return ret;
- result.fract /= 1000;
result.fract /= 3;
chip->tsl2x7x_settings.als_time =
(TSL2X7X_MAX_TIMER_CNT - (u8)result.fract);
@@ -1109,12 +1055,12 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
int y, z, filter_delay;
+ int ret;
- result.integer = 0;
- result.fract = 0;
- tsl2x7x_parse_buffer(buf, &result);
+ ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
+ if (ret)
+ return ret;
- result.fract /= 1000;
y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1;
z = y * TSL2X7X_MIN_ITIME;
@@ -1155,12 +1101,12 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
struct tsl2x7x_parse_result result;
int y, z, filter_delay;
+ int ret;
- result.integer = 0;
- result.fract = 0;
- tsl2x7x_parse_buffer(buf, &result);
+ ret = iio_str_to_fixpoint(buf, 100, &result.integer, &result.fract);
+ if (ret)
+ return ret;
- result.fract /= 1000;
y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1;
z = y * TSL2X7X_MIN_ITIME;
diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig
index d290d27..e53274b 100644
--- a/drivers/staging/iio/meter/Kconfig
+++ b/drivers/staging/iio/meter/Kconfig
@@ -21,7 +21,7 @@ config ADE7758
tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver"
depends on SPI
select IIO_TRIGGER if IIO_BUFFER
- select IIO_SW_RING if IIO_BUFFER
+ select IIO_KFIFO_BUF if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADE7758 Polyphase
Multifunction Energy Metering IC with Per Phase Information Driver.
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 51c3bde..e5943e2 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -103,7 +103,6 @@ static int ade7753_spi_read_reg_24(struct device *dev,
u8 reg_address,
u32 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
int ret;
@@ -122,10 +121,7 @@ static int ade7753_spi_read_reg_24(struct device *dev,
mutex_lock(&st->buf_lock);
st->tx[0] = ADE7753_READ_REG(reg_address);
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
reg_address);
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index b50c89e..7b6503b 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -103,7 +103,6 @@ static int ade7754_spi_read_reg_24(struct device *dev,
u8 reg_address,
u32 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
int ret;
@@ -122,9 +121,7 @@ static int ade7754_spi_read_reg_24(struct device *dev,
st->tx[2] = 0;
st->tx[3] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(xfers, &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
reg_address);
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 3454e51..53c68dc 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -47,7 +47,6 @@ static int ade7758_spi_write_reg_16(struct device *dev,
u16 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
struct spi_transfer xfers[] = {
@@ -63,9 +62,7 @@ static int ade7758_spi_write_reg_16(struct device *dev,
st->tx[1] = (value >> 8) & 0xFF;
st->tx[2] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(xfers, &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
mutex_unlock(&st->buf_lock);
return ret;
@@ -76,7 +73,6 @@ static int ade7758_spi_write_reg_24(struct device *dev,
u32 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
struct spi_transfer xfers[] = {
@@ -93,9 +89,7 @@ static int ade7758_spi_write_reg_24(struct device *dev,
st->tx[2] = (value >> 8) & 0xFF;
st->tx[3] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(xfers, &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
mutex_unlock(&st->buf_lock);
return ret;
@@ -105,7 +99,6 @@ int ade7758_spi_read_reg_8(struct device *dev,
u8 reg_address,
u8 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
int ret;
@@ -128,10 +121,7 @@ int ade7758_spi_read_reg_8(struct device *dev,
st->tx[0] = ADE7758_READ_REG(reg_address);
st->tx[1] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
reg_address);
@@ -148,7 +138,6 @@ static int ade7758_spi_read_reg_16(struct device *dev,
u8 reg_address,
u16 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
int ret;
@@ -173,10 +162,7 @@ static int ade7758_spi_read_reg_16(struct device *dev,
st->tx[1] = 0;
st->tx[2] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -194,7 +180,6 @@ static int ade7758_spi_read_reg_24(struct device *dev,
u8 reg_address,
u32 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
int ret;
@@ -219,10 +204,7 @@ static int ade7758_spi_read_reg_24(struct device *dev,
st->tx[2] = 0;
st->tx[3] = 0;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
reg_address);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 4552a4c..b29e2d5 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -13,7 +13,7 @@
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
-#include "../ring_sw.h"
+#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger_consumer.h>
#include "ade7758.h"
@@ -119,7 +119,7 @@ static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
{
iio_dealloc_pollfunc(indio_dev->pollfunc);
- iio_sw_rb_free(indio_dev->buffer);
+ iio_kfifo_free(indio_dev->buffer);
}
int ade7758_configure_ring(struct iio_dev *indio_dev)
@@ -127,7 +127,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
struct ade7758_state *st = iio_priv(indio_dev);
int ret = 0;
- indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
+ indio_dev->buffer = iio_kfifo_allocate(indio_dev);
if (!indio_dev->buffer) {
ret = -ENOMEM;
return ret;
@@ -143,7 +143,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
- goto error_iio_sw_rb_free;
+ goto error_iio_kfifo_free;
}
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
@@ -183,8 +183,8 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
return 0;
-error_iio_sw_rb_free:
- iio_sw_rb_free(indio_dev->buffer);
+error_iio_kfifo_free:
+ iio_kfifo_free(indio_dev->buffer);
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 10b911b..17dc373 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -103,7 +103,6 @@ static int ade7759_spi_read_reg_40(struct device *dev,
u8 reg_address,
u64 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7759_state *st = iio_priv(indio_dev);
int ret;
@@ -120,9 +119,7 @@ static int ade7759_spi_read_reg_40(struct device *dev,
st->tx[0] = ADE7759_READ_REG(reg_address);
memset(&st->tx[1], 0 , 5);
- spi_message_init(&msg);
- spi_message_add_tail(xfers, &msg);
- ret = spi_sync(st->us, &msg);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 40 bit register 0x%02X",
reg_address);
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index f0984fa..a802cf2 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -20,7 +20,6 @@ static int ade7854_spi_write_reg_8(struct device *dev,
u8 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
struct spi_transfer xfer = {
@@ -35,9 +34,7 @@ static int ade7854_spi_write_reg_8(struct device *dev,
st->tx[2] = reg_address & 0xFF;
st->tx[3] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock);
return ret;
@@ -48,7 +45,6 @@ static int ade7854_spi_write_reg_16(struct device *dev,
u16 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
struct spi_transfer xfer = {
@@ -64,9 +60,7 @@ static int ade7854_spi_write_reg_16(struct device *dev,
st->tx[3] = (value >> 8) & 0xFF;
st->tx[4] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock);
return ret;
@@ -77,7 +71,6 @@ static int ade7854_spi_write_reg_24(struct device *dev,
u32 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
struct spi_transfer xfer = {
@@ -94,9 +87,7 @@ static int ade7854_spi_write_reg_24(struct device *dev,
st->tx[4] = (value >> 8) & 0xFF;
st->tx[5] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock);
return ret;
@@ -107,7 +98,6 @@ static int ade7854_spi_write_reg_32(struct device *dev,
u32 value)
{
int ret;
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
struct spi_transfer xfer = {
@@ -125,9 +115,7 @@ static int ade7854_spi_write_reg_32(struct device *dev,
st->tx[5] = (value >> 8) & 0xFF;
st->tx[6] = value & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock);
return ret;
@@ -137,7 +125,6 @@ static int ade7854_spi_read_reg_8(struct device *dev,
u16 reg_address,
u8 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
@@ -159,10 +146,7 @@ static int ade7854_spi_read_reg_8(struct device *dev,
st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X",
reg_address);
@@ -179,7 +163,6 @@ static int ade7854_spi_read_reg_16(struct device *dev,
u16 reg_address,
u16 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
@@ -200,10 +183,7 @@ static int ade7854_spi_read_reg_16(struct device *dev,
st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -220,7 +200,6 @@ static int ade7854_spi_read_reg_24(struct device *dev,
u16 reg_address,
u32 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
@@ -242,10 +221,7 @@ static int ade7854_spi_read_reg_24(struct device *dev,
st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X",
reg_address);
@@ -262,7 +238,6 @@ static int ade7854_spi_read_reg_32(struct device *dev,
u16 reg_address,
u32 *val)
{
- struct spi_message msg;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
@@ -284,10 +259,7 @@ static int ade7854_spi_read_reg_32(struct device *dev,
st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->spi, &msg);
+ ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X",
reg_address);
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index ed07a34..53110b6 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -130,15 +130,12 @@ static int ad2s1210_config_read(struct ad2s1210_state *st,
.rx_buf = st->rx,
.tx_buf = st->tx,
};
- struct spi_message msg;
int ret = 0;
ad2s1210_set_mode(MOD_CONFIG, st);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
st->tx[0] = address | AD2S1210_MSB_IS_HIGH;
st->tx[1] = AD2S1210_REG_FAULT;
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret < 0)
return ret;
st->old_data = true;
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
deleted file mode 100644
index 3a45f9a..0000000
--- a/drivers/staging/iio/ring_sw.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* The industrial I/O simple minimally locked ring buffer.
- *
- * Copyright (c) 2008 Jonathan Cameron
- *
- * 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 published by
- * the Free Software Foundation.
- */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/poll.h>
-#include "ring_sw.h"
-#include <linux/iio/trigger.h>
-
-/**
- * struct iio_sw_ring_buffer - software ring buffer
- * @buf: generic ring buffer elements
- * @data: the ring buffer memory
- * @read_p: read pointer (oldest available)
- * @write_p: write pointer
- * @half_p: half buffer length behind write_p (event generation)
- * @update_needed: flag to indicate change in size requested
- *
- * Note that the first element of all ring buffers must be a
- * struct iio_buffer.
-**/
-struct iio_sw_ring_buffer {
- struct iio_buffer buf;
- unsigned char *data;
- unsigned char *read_p;
- unsigned char *write_p;
- /* used to act as a point at which to signal an event */
- unsigned char *half_p;
- int update_needed;
-};
-
-#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
-
-static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
- int bytes_per_datum, int length)
-{
- if ((length == 0) || (bytes_per_datum == 0))
- return -EINVAL;
- __iio_update_buffer(&ring->buf, bytes_per_datum, length);
- ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC);
- ring->read_p = NULL;
- ring->write_p = NULL;
- ring->half_p = NULL;
- return ring->data ? 0 : -ENOMEM;
-}
-
-static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
-{
- kfree(ring->data);
-}
-
-/* Ring buffer related functionality */
-/* Store to ring is typically called in the bh of a data ready interrupt handler
- * in the device driver */
-/* 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)
-{
- int ret = 0;
- unsigned char *temp_ptr, *change_test_ptr;
-
- /* initial store */
- if (unlikely(ring->write_p == NULL)) {
- ring->write_p = ring->data;
- /* Doesn't actually matter if this is out of the set
- * as long as the read pointer is valid before this
- * passes it - guaranteed as set later in this function.
- */
- ring->half_p = ring->data - ring->buf.length*ring->buf.bytes_per_datum/2;
- }
- /* Copy data to where ever the current write pointer says */
- memcpy(ring->write_p, data, ring->buf.bytes_per_datum);
- barrier();
- /* Update the pointer used to get most recent value.
- * Always valid as either points to latest or second latest value.
- * Before this runs it is null and read attempts fail with -EAGAIN.
- */
- barrier();
- /* temp_ptr used to ensure we never have an invalid pointer
- * it may be slightly lagging, but never invalid
- */
- temp_ptr = ring->write_p + ring->buf.bytes_per_datum;
- /* End of ring, back to the beginning */
- if (temp_ptr == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
- temp_ptr = ring->data;
- /* Update the write pointer
- * always valid as long as this is the only function able to write.
- * Care needed with smp systems to ensure more than one ring fill
- * is never scheduled.
- */
- ring->write_p = temp_ptr;
-
- if (ring->read_p == NULL)
- ring->read_p = ring->data;
- /* Buffer full - move the read pointer and create / escalate
- * ring event */
- /* Tricky case - if the read pointer moves before we adjust it.
- * Handle by not pushing if it has moved - may result in occasional
- * unnecessary buffer full events when it wasn't quite true.
- */
- else if (ring->write_p == ring->read_p) {
- change_test_ptr = ring->read_p;
- temp_ptr = change_test_ptr + ring->buf.bytes_per_datum;
- if (temp_ptr
- == ring->data + ring->buf.length*ring->buf.bytes_per_datum) {
- temp_ptr = ring->data;
- }
- /* We are moving pointer on one because the ring is full. Any
- * change to the read pointer will be this or greater.
- */
- if (change_test_ptr == ring->read_p)
- ring->read_p = temp_ptr;
- }
- /* investigate if our event barrier has been passed */
- /* There are definite 'issues' with this and chances of
- * simultaneous read */
- /* Also need to use loop count to ensure this only happens once */
- ring->half_p += ring->buf.bytes_per_datum;
- if (ring->half_p == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
- ring->half_p = ring->data;
- if (ring->half_p == ring->read_p) {
- ring->buf.stufftoread = true;
- wake_up_interruptible(&ring->buf.pollq);
- }
- return ret;
-}
-
-static int iio_read_first_n_sw_rb(struct iio_buffer *r,
- size_t n, char __user *buf)
-{
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-
- u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
- u8 *data;
- int ret, max_copied, bytes_to_rip, dead_offset;
- size_t data_available, buffer_size;
-
- /* A userspace program has probably made an error if it tries to
- * read something that is not a whole number of bpds.
- * Return an error.
- */
- if (n % ring->buf.bytes_per_datum) {
- ret = -EINVAL;
- printk(KERN_INFO "Ring buffer read request not whole number of"
- "samples: Request bytes %zd, Current bytes per datum %d\n",
- n, ring->buf.bytes_per_datum);
- goto error_ret;
- }
-
- buffer_size = ring->buf.bytes_per_datum*ring->buf.length;
-
- /* Limit size to whole of ring buffer */
- bytes_to_rip = min_t(size_t, buffer_size, n);
-
- data = kmalloc(bytes_to_rip, GFP_KERNEL);
- if (data == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
-
- /* build local copy */
- initial_read_p = ring->read_p;
- if (unlikely(initial_read_p == NULL)) { /* No data here as yet */
- ret = 0;
- goto error_free_data_cpy;
- }
-
- initial_write_p = ring->write_p;
-
- /* Need a consistent pair */
- while ((initial_read_p != ring->read_p)
- || (initial_write_p != ring->write_p)) {
- initial_read_p = ring->read_p;
- initial_write_p = ring->write_p;
- }
- if (initial_write_p == initial_read_p) {
- /* No new data available.*/
- ret = 0;
- goto error_free_data_cpy;
- }
-
- if (initial_write_p >= initial_read_p)
- data_available = initial_write_p - initial_read_p;
- else
- data_available = buffer_size - (initial_read_p - initial_write_p);
-
- if (data_available < bytes_to_rip)
- bytes_to_rip = data_available;
-
- if (initial_read_p + bytes_to_rip >= ring->data + buffer_size) {
- max_copied = ring->data + buffer_size - initial_read_p;
- memcpy(data, initial_read_p, max_copied);
- memcpy(data + max_copied, ring->data, bytes_to_rip - max_copied);
- end_read_p = ring->data + bytes_to_rip - max_copied;
- } else {
- memcpy(data, initial_read_p, bytes_to_rip);
- end_read_p = initial_read_p + bytes_to_rip;
- }
-
- /* Now to verify which section was cleanly copied - i.e. how far
- * read pointer has been pushed */
- current_read_p = ring->read_p;
-
- if (initial_read_p <= current_read_p)
- dead_offset = current_read_p - initial_read_p;
- else
- dead_offset = buffer_size - (initial_read_p - current_read_p);
-
- /* possible issue if the initial write has been lapped or indeed
- * the point we were reading to has been passed */
- /* No valid data read.
- * In this case the read pointer is already correct having been
- * pushed further than we would look. */
- if (bytes_to_rip - dead_offset < 0) {
- ret = 0;
- goto error_free_data_cpy;
- }
-
- /* setup the next read position */
- /* Beware, this may fail due to concurrency fun and games.
- * Possible that sufficient fill commands have run to push the read
- * pointer past where we would be after the rip. If this occurs, leave
- * it be.
- */
- /* Tricky - deal with loops */
-
- while (ring->read_p != end_read_p)
- ring->read_p = end_read_p;
-
- ret = bytes_to_rip - dead_offset;
-
- if (copy_to_user(buf, data + dead_offset, ret)) {
- ret = -EFAULT;
- goto error_free_data_cpy;
- }
-
- if (bytes_to_rip >= ring->buf.length*ring->buf.bytes_per_datum/2)
- ring->buf.stufftoread = 0;
-
-error_free_data_cpy:
- kfree(data);
-error_ret:
-
- return ret;
-}
-
-static int iio_store_to_sw_rb(struct iio_buffer *r,
- u8 *data)
-{
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
- return iio_store_to_sw_ring(ring, data);
-}
-
-static int iio_request_update_sw_rb(struct iio_buffer *r)
-{
- int ret = 0;
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-
- r->stufftoread = false;
- if (!ring->update_needed)
- goto error_ret;
- __iio_free_sw_ring_buffer(ring);
- ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bytes_per_datum,
- ring->buf.length);
-error_ret:
- return ret;
-}
-
-static int iio_get_bytes_per_datum_sw_rb(struct iio_buffer *r)
-{
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
- return ring->buf.bytes_per_datum;
-}
-
-static int iio_mark_update_needed_sw_rb(struct iio_buffer *r)
-{
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
- ring->update_needed = true;
- return 0;
-}
-
-static int iio_set_bytes_per_datum_sw_rb(struct iio_buffer *r, size_t bpd)
-{
- if (r->bytes_per_datum != bpd) {
- r->bytes_per_datum = bpd;
- iio_mark_update_needed_sw_rb(r);
- }
- return 0;
-}
-
-static int iio_get_length_sw_rb(struct iio_buffer *r)
-{
- return r->length;
-}
-
-static int iio_set_length_sw_rb(struct iio_buffer *r, int length)
-{
- if (r->length != length) {
- r->length = length;
- iio_mark_update_needed_sw_rb(r);
- }
- return 0;
-}
-
-static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_LENGTH_ATTR;
-
-/* Standard set of ring buffer attributes */
-static struct attribute *iio_ring_attributes[] = {
- &dev_attr_length.attr,
- &dev_attr_enable.attr,
- NULL,
-};
-
-static struct attribute_group iio_ring_attribute_group = {
- .attrs = iio_ring_attributes,
- .name = "buffer",
-};
-
-static const struct iio_buffer_access_funcs ring_sw_access_funcs = {
- .store_to = &iio_store_to_sw_rb,
- .read_first_n = &iio_read_first_n_sw_rb,
- .request_update = &iio_request_update_sw_rb,
- .get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
- .set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
- .get_length = &iio_get_length_sw_rb,
- .set_length = &iio_set_length_sw_rb,
-};
-
-struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
-{
- struct iio_buffer *buf;
- struct iio_sw_ring_buffer *ring;
-
- ring = kzalloc(sizeof *ring, GFP_KERNEL);
- if (!ring)
- return NULL;
- ring->update_needed = true;
- buf = &ring->buf;
- iio_buffer_init(buf);
- buf->attrs = &iio_ring_attribute_group;
- buf->access = &ring_sw_access_funcs;
-
- return buf;
-}
-EXPORT_SYMBOL(iio_sw_rb_allocate);
-
-void iio_sw_rb_free(struct iio_buffer *r)
-{
- kfree(iio_to_sw_ring(r));
-}
-EXPORT_SYMBOL(iio_sw_rb_free);
-
-MODULE_DESCRIPTION("Industrial I/O software ring buffer");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
deleted file mode 100644
index a5857aa..0000000
--- a/drivers/staging/iio/ring_sw.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* The industrial I/O simple minimally locked ring buffer.
- *
- * Copyright (c) 2008 Jonathan Cameron
- *
- * 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 published by
- * the Free Software Foundation.
- *
- * This code is deliberately kept separate from the main industrialio I/O core
- * as it is intended that in the future a number of different software ring
- * buffer implementations will exist with different characteristics to suit
- * different applications.
- *
- * This particular one was designed for a data capture application where it was
- * particularly important that no userspace reads would interrupt the capture
- * process. To this end the ring is not locked during a read.
- *
- * Comments on this buffer design welcomed. It's far from efficient and some of
- * my understanding of the effects of scheduling on this are somewhat limited.
- * Frankly, to my mind, this is the current weak point in the industrial I/O
- * patch set.
- */
-
-#ifndef _IIO_RING_SW_H_
-#define _IIO_RING_SW_H_
-#include <linux/iio/buffer.h>
-
-struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
-void iio_sw_rb_free(struct iio_buffer *ring);
-#endif /* _IIO_RING_SW_H_ */