aboutsummaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c24
-rw-r--r--drivers/iio/accel/kxsd9.c6
-rw-r--r--drivers/iio/accel/st_accel_buffer.c2
-rw-r--r--drivers/iio/adc/Kconfig20
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/ad7266.c12
-rw-r--r--drivers/iio/adc/ad7298.c10
-rw-r--r--drivers/iio/adc/ad7476.c10
-rw-r--r--drivers/iio/adc/ad7887.c8
-rw-r--r--drivers/iio/adc/ad7923.c383
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c2
-rw-r--r--drivers/iio/adc/at91_adc.c98
-rw-r--r--drivers/iio/adc/exynos_adc.c452
-rw-r--r--drivers/iio/adc/lp8788_adc.c4
-rw-r--r--drivers/iio/adc/max1363.c9
-rw-r--r--drivers/iio/adc/ti-adc081c.c4
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c2
-rw-r--r--drivers/iio/adc/viperboard_adc.c2
-rw-r--r--drivers/iio/amplifiers/ad8366.c2
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c4
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_spi.c11
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_trigger.c2
-rw-r--r--drivers/iio/dac/ad5064.c4
-rw-r--r--drivers/iio/dac/ad5360.c10
-rw-r--r--drivers/iio/dac/ad5380.c8
-rw-r--r--drivers/iio/dac/ad5421.c10
-rw-r--r--drivers/iio/dac/ad5446.c4
-rw-r--r--drivers/iio/dac/ad5449.c4
-rw-r--r--drivers/iio/dac/ad5504.c4
-rw-r--r--drivers/iio/dac/ad5624r_spi.c4
-rw-r--r--drivers/iio/dac/ad5686.c6
-rw-r--r--drivers/iio/dac/ad5755.c10
-rw-r--r--drivers/iio/dac/ad5764.c10
-rw-r--r--drivers/iio/dac/ad5791.c6
-rw-r--r--drivers/iio/dac/max517.c4
-rw-r--r--drivers/iio/dac/mcp4725.c4
-rw-r--r--drivers/iio/frequency/ad9523.c8
-rw-r--r--drivers/iio/gyro/adis16080.c22
-rw-r--r--drivers/iio/gyro/adis16136.c13
-rw-r--r--drivers/iio/gyro/adxrs450.c22
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c24
-rw-r--r--drivers/iio/gyro/itg3200_buffer.c4
-rw-r--r--drivers/iio/gyro/itg3200_core.c13
-rw-r--r--drivers/iio/gyro/st_gyro_buffer.c2
-rw-r--r--drivers/iio/iio_core.h1
-rw-r--r--drivers/iio/imu/adis16400_core.c49
-rw-r--r--drivers/iio/imu/adis16480.c32
-rw-r--r--drivers/iio/imu/adis_trigger.c4
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_core.c10
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c5
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c4
-rw-r--r--drivers/iio/industrialio-core.c35
-rw-r--r--drivers/iio/industrialio-event.c29
-rw-r--r--drivers/iio/inkern.c171
-rw-r--r--drivers/iio/light/adjd_s311.c4
-rw-r--r--drivers/iio/light/hid-sensor-als.c8
-rw-r--r--drivers/iio/light/lm3533-als.c6
-rw-r--r--drivers/iio/light/tsl2563.c10
-rw-r--r--drivers/iio/light/vcnl4000.c6
-rw-r--r--drivers/iio/magnetometer/Kconfig11
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak8975.c485
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c24
63 files changed, 1888 insertions, 272 deletions
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index dd8ea428493..bbcbd7101f3 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -60,28 +60,28 @@ static const struct iio_chan_spec accel_3d_channels[] = {
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_X,
- .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
- IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_Y,
- .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
- IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_Z,
- .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT |
- IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT,
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_Z,
}
};
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index c2229a521ab..7229645bf1d 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -177,8 +177,8 @@ error_ret:
.type = IIO_ACCEL, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.address = KXSD9_REG_##axis, \
}
@@ -186,7 +186,7 @@ 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,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.indexed = 1,
.address = KXSD9_REG_AUX,
}
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c
index 6bd82c7f769..d9b350756f9 100644
--- a/drivers/iio/accel/st_accel_buffer.c
+++ b/drivers/iio/accel/st_accel_buffer.c
@@ -25,7 +25,7 @@
int st_accel_trig_set_state(struct iio_trigger *trig, bool state)
{
- struct iio_dev *indio_dev = trig->private_data;
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
return st_sensors_set_dataready_irq(indio_dev, state);
}
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index e372257a849..ab0767e6727 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -30,6 +30,18 @@ config AD7298
To compile this driver as a module, choose M here: the
module will be called ad7298.
+config AD7923
+ tristate "Analog Devices AD7923 and similar ADCs driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Analog Devices
+ AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7923.
+
config AD7791
tristate "Analog Devices AD7791 ADC driver"
depends on SPI
@@ -91,6 +103,14 @@ config AT91_ADC
help
Say yes here to build support for Atmel AT91 ADC.
+config EXYNOS_ADC
+ bool "Exynos ADC driver support"
+ depends on OF
+ help
+ Core support for the ADC block found in the Samsung EXYNOS series
+ of SoCs for drivers such as the touchscreen and hwmon to use to share
+ this resource.
+
config LP8788_ADC
bool "LP8788 ADC driver"
depends on MFD_LP8788
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 2d5f10080d8..0a825bed43f 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -5,11 +5,13 @@
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7298) += ad7298.o
+obj-$(CONFIG_AD7923) += ad7923.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AD7793) += ad7793.o
obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
+obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index bbad9b94cd7..c2744a75c3b 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -201,9 +201,9 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
.indexed = 1, \
.channel = (_chan), \
.address = (_chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \
- | IIO_CHAN_INFO_SCALE_SHARED_BIT \
- | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+ | BIT(IIO_CHAN_INFO_OFFSET), \
.scan_index = (_chan), \
.scan_type = { \
.sign = (_sign), \
@@ -249,9 +249,9 @@ static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(s, 's');
.channel = (_chan) * 2, \
.channel2 = (_chan) * 2 + 1, \
.address = (_chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \
- | IIO_CHAN_INFO_SCALE_SHARED_BIT \
- | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+ | BIT(IIO_CHAN_INFO_OFFSET), \
.scan_index = (_chan), \
.scan_type = { \
.sign = _sign, \
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
index b34d754994d..03b77189dbf 100644
--- a/drivers/iio/adc/ad7298.c
+++ b/drivers/iio/adc/ad7298.c
@@ -63,8 +63,8 @@ struct ad7298_state {
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = index, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.address = index, \
.scan_index = index, \
.scan_type = { \
@@ -80,9 +80,9 @@ static const struct iio_chan_spec ad7298_channels[] = {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
.address = AD7298_CH_TEMP,
.scan_index = -1,
.scan_type = {
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index 1491fa6debb..2e98bef4af6 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -140,12 +140,12 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-#define _AD7476_CHAN(bits, _shift, _info_mask) \
+#define _AD7476_CHAN(bits, _shift, _info_mask_sep) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
- .info_mask = _info_mask | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+ .info_mask_separate = _info_mask_sep, \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.scan_type = { \
.sign = 'u', \
.realbits = (bits), \
@@ -156,9 +156,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
}
#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \
- IIO_CHAN_INFO_RAW_SEPARATE_BIT)
+ BIT(IIO_CHAN_INFO_RAW))
#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
- IIO_CHAN_INFO_RAW_SEPARATE_BIT)
+ BIT(IIO_CHAN_INFO_RAW))
#define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index a33d5cd1a53..dd15a5b0f70 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -207,8 +207,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.address = 1,
.scan_index = 1,
.scan_type = IIO_ST('u', 12, 16, 0),
@@ -217,8 +217,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.address = 0,
.scan_index = 0,
.scan_type = IIO_ST('u', 12, 16, 0),
diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
new file mode 100644
index 00000000000..97fa0d3dc4a
--- /dev/null
+++ b/drivers/iio/adc/ad7923.c
@@ -0,0 +1,383 @@
+/*
+ * AD7904/AD7914/AD7923/AD7924 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define AD7923_WRITE_CR (1 << 11) /* write control register */
+#define AD7923_RANGE (1 << 1) /* range to REFin */
+#define AD7923_CODING (1 << 0) /* coding is straight binary */
+#define AD7923_PM_MODE_AS (1) /* auto shutdown */
+#define AD7923_PM_MODE_FS (2) /* full shutdown */
+#define AD7923_PM_MODE_OPS (3) /* normal operation */
+#define AD7923_CHANNEL_0 (0) /* analog input 0 */
+#define AD7923_CHANNEL_1 (1) /* analog input 1 */
+#define AD7923_CHANNEL_2 (2) /* analog input 2 */
+#define AD7923_CHANNEL_3 (3) /* analog input 3 */
+#define AD7923_SEQUENCE_OFF (0) /* no sequence fonction */
+#define AD7923_SEQUENCE_PROTECT (2) /* no interrupt write cycle */
+#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
+
+#define AD7923_MAX_CHAN 4
+
+#define AD7923_PM_MODE_WRITE(mode) (mode << 4) /* write mode */
+#define AD7923_CHANNEL_WRITE(channel) (channel << 6) /* write channel */
+#define AD7923_SEQUENCE_WRITE(sequence) (((sequence & 1) << 3) \
+ + ((sequence & 2) << 9))
+ /* write sequence fonction */
+/* left shift for CR : bit 11 transmit in first */
+#define AD7923_SHIFT_REGISTER 4
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define EXTRACT(val, dec, bits) ((val >> dec) & ((1 << bits) - 1))
+
+struct ad7923_state {
+ struct spi_device *spi;
+ struct spi_transfer ring_xfer[5];
+ struct spi_transfer scan_single_xfer[2];
+ struct spi_message ring_msg;
+ struct spi_message scan_single_msg;
+
+ struct regulator *reg;
+
+ unsigned int settings;
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 rx_buf[4] ____cacheline_aligned;
+ __be16 tx_buf[4];
+};
+
+struct ad7923_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+};
+
+enum ad7923_id {
+ AD7904,
+ AD7914,
+ AD7924,
+};
+
+#define AD7923_V_CHAN(index, bits) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define DECLARE_AD7923_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ AD7923_V_CHAN(0, bits), \
+ AD7923_V_CHAN(1, bits), \
+ AD7923_V_CHAN(2, bits), \
+ AD7923_V_CHAN(3, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(4), \
+}
+
+static DECLARE_AD7923_CHANNELS(ad7904, 8);
+static DECLARE_AD7923_CHANNELS(ad7914, 10);
+static DECLARE_AD7923_CHANNELS(ad7924, 12);
+
+static const struct ad7923_chip_info ad7923_chip_info[] = {
+ [AD7904] = {
+ .channels = ad7904_channels,
+ .num_channels = ARRAY_SIZE(ad7904_channels),
+ },
+ [AD7914] = {
+ .channels = ad7914_channels,
+ .num_channels = ARRAY_SIZE(ad7914_channels),
+ },
+ [AD7924] = {
+ .channels = ad7924_channels,
+ .num_channels = ARRAY_SIZE(ad7924_channels),
+ },
+};
+
+/**
+ * ad7923_update_scan_mode() setup the spi transfer buffer for the new scan mask
+ **/
+static int ad7923_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *active_scan_mask)
+{
+ struct ad7923_state *st = iio_priv(indio_dev);
+ int i, cmd, len;
+
+ len = 0;
+ for_each_set_bit(i, active_scan_mask, AD7923_MAX_CHAN) {
+ cmd = AD7923_WRITE_CR | AD7923_CHANNEL_WRITE(i) |
+ AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) |
+ st->settings;
+ cmd <<= AD7923_SHIFT_REGISTER;
+ st->tx_buf[len++] = cpu_to_be16(cmd);
+ }
+ /* build spi ring message */
+ st->ring_xfer[0].tx_buf = &st->tx_buf[0];
+ st->ring_xfer[0].len = len;
+ st->ring_xfer[0].cs_change = 1;
+
+ spi_message_init(&st->ring_msg);
+ spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
+
+ for (i = 0; i < len; i++) {
+ st->ring_xfer[i + 1].rx_buf = &st->rx_buf[i];
+ st->ring_xfer[i + 1].len = 2;
+ st->ring_xfer[i + 1].cs_change = 1;
+ spi_message_add_tail(&st->ring_xfer[i + 1], &st->ring_msg);
+ }
+ /* make sure last transfer cs_change is not set */
+ st->ring_xfer[i + 1].cs_change = 0;
+
+ return 0;
+}
+
+/**
+ * ad7923_trigger_handler() bh of trigger launched polling to ring buffer
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ **/
+static irqreturn_t ad7923_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ad7923_state *st = iio_priv(indio_dev);
+ s64 time_ns = 0;
+ int b_sent;
+
+ b_sent = spi_sync(st->spi, &st->ring_msg);
+ if (b_sent)
+ goto done;
+
+ if (indio_dev->scan_timestamp) {
+ time_ns = iio_get_time_ns();
+ memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
+ &time_ns, sizeof(time_ns));
+ }
+
+ iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch)
+{
+ int ret, cmd;
+
+ cmd = AD7923_WRITE_CR | AD7923_CHANNEL_WRITE(ch) |
+ AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) |
+ st->settings;
+ cmd <<= AD7923_SHIFT_REGISTER;
+ st->tx_buf[0] = cpu_to_be16(cmd);
+
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ if (ret)
+ return ret;
+
+ return be16_to_cpu(st->rx_buf[0]);
+}
+
+static int ad7923_get_range(struct ad7923_state *st)
+{
+ int vref;
+
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
+
+ vref /= 1000;
+
+ if (!(st->settings & AD7923_RANGE))
+ vref *= 2;
+
+ return vref;
+}
+
+static int ad7923_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
+{
+ int ret;
+ struct ad7923_state *st = iio_priv(indio_dev);
+
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&indio_dev->mlock);
+ if (iio_buffer_enabled(indio_dev))
+ ret = -EBUSY;
+ else
+ ret = ad7923_scan_direct(st, chan->address);
+ mutex_unlock(&indio_dev->mlock);
+
+ if (ret < 0)
+ return ret;
+
+ if (chan->address == EXTRACT(ret, 12, 4))
+ *val = EXTRACT(ret, 0, 12);
+ else
+ return -EIO;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = ad7923_get_range(st);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
+ return -EINVAL;
+}
+
+static const struct iio_info ad7923_info = {
+ .read_raw = &ad7923_read_raw,
+ .update_scan_mode = ad7923_update_scan_mode,
+ .driver_module = THIS_MODULE,
+};
+
+static int ad7923_probe(struct spi_device *spi)
+{
+ struct ad7923_state *st;
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ const struct ad7923_chip_info *info;
+ int ret;
+
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st->spi = spi;
+ st->settings = AD7923_CODING | AD7923_RANGE |
+ AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS);
+
+ info = &ad7923_chip_info[spi_get_device_id(spi)->driver_data];
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = info->channels;
+ indio_dev->num_channels = info->num_channels;
+ indio_dev->info = &ad7923_info;
+
+ /* Setup default message */
+
+ st->scan_single_xfer[0].tx_buf = &st->tx_buf[0];
+ st->scan_single_xfer[0].len = 2;
+ st->scan_single_xfer[0].cs_change = 1;
+ st->scan_single_xfer[1].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[1].len = 2;
+
+ spi_message_init(&st->scan_single_msg);
+ spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
+ spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
+
+ st->reg = regulator_get(&spi->dev, "refin");
+ if (IS_ERR(st->reg)) {
+ ret = PTR_ERR(st->reg);
+ goto error_free;
+ }
+ ret = regulator_enable(st->reg);
+ if (ret)
+ goto error_put_reg;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &ad7923_trigger_handler, NULL);
+ if (ret)
+ goto error_disable_reg;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_cleanup_ring;
+
+ return 0;
+
+error_cleanup_ring:
+ iio_triggered_buffer_cleanup(indio_dev);
+error_disable_reg:
+ regulator_disable(st->reg);
+error_put_reg:
+ regulator_put(st->reg);
+error_free:
+ iio_device_free(indio_dev);
+
+ return ret;