summaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 22:34:17 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 22:34:17 +0400
commitfdc719b63ae35d6a2d8a2a2c76eed813294664bf (patch)
treef02336d93870e77f8bba4db49f7fc58078465fca /drivers/iio
parent2794b5d408c625e104de813d3de7ac0ec34d46d9 (diff)
parenta0eeed40100b2eca57afdf99d76c57dedd218a8a (diff)
downloadlinux-fdc719b63ae35d6a2d8a2a2c76eed813294664bf.tar.xz
Merge tag 'staging-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver tree update from Greg Kroah-Hartman: "Here's the big staging driver tree update for 3.10-rc1 This update contains loads of comedi driver cleanups and fixes in here, iio updates, android driver changes, and other various staging driver cleanups. Thanks to some drivers being removed, and the comedi driver cleanups, we have removed more code than we added: 627 files changed, 65145 insertions(+), 76321 deletions(-) which is always nice to see. All of these have been in linux-next for a while." * tag 'staging-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (940 commits) staging: comedi: ni_labpc: fix legacy driver build staging: comedi: das800: cleanup the cio-das802/16 fifo comments staging: comedi: das800: rename CamelCase vars in das800_ai_do_cmd() staging: comedi: das800: tidy up the private data staging: comedi: das800: tidy up das800_interrupt() staging: comedi: das800: tidy up das800_ai_insn_read() staging: comedi: das800: tidy up das800_di_insn_bits() staging: comedi: das800: tidy up das800_do_insn_bits() staging: comedi: das800: remove extra divisor calculation call staging: comedi: das800: rename {enable,disable}_das800 staging: comedi: das800: tidy up subdevice init staging: comedi: das800: allow attaching without interrupt support staging: comedi: das800: interrupts are required for async command support staging: comedi: das800: tidy up das800_ai_do_cmdtest() staging: comedi: das800: remove 'volatile' on private data variables staging: comedi: das800: cleanup the boardinfo staging: comedi: das800: cleanup range table declarations staging: comedi: das800: introduce das800_ind_{write, read}() staging: comedi: das800: remove forward declarations staging: comedi: das800: move das800_set_frequency() ...
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 dd8ea4284934..bbcbd7101f33 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 c2229a521ab9..7229645bf1d7 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 6bd82c7f769c..d9b350756f90 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 e372257a8494..ab0767e6727e 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 2d5f10080d8d..0a825bed43f6 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 bbad9b94cd75..c2744a75c3b0 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 b34d754994d5..03b77189dbfe 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 1491fa6debb2..2e98bef4af67 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 a33d5cd1a536..dd15a5b0f701 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 000000000000..97fa0d3dc4aa
--- /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;
+}
+
+static int ad7923_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct ad7923_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ regulator_disable(st->reg);
+ regulator_put(st->reg);
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static const struct spi_device_id ad7923_id[] = {
+ {"ad7904", AD7904},
+ {"ad7914", AD7914},
+ {"ad7923", AD7924},
+ {"ad7924", AD7924},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, ad7923_id);
+
+static struct spi_driver ad7923_driver = {
+ .driver = {
+ .name = "ad7923",
+ .owner = THIS_MODULE,
+ },
+ .probe = ad7923_probe,
+ .remove = ad7923_remove,
+ .id_table = ad7923_id,
+};
+module_spi_driver(ad7923_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Patrick Vasseur <patrick.vasseur@c-s.fr>");
+MODULE_DESCRIPTION("Analog Devices AD7904/AD7914/AD7923/AD7924 ADC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index afe6d78c8ff0..f0d6335ae087 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -470,7 +470,7 @@ static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
disable_irq_nosync(sigma_delta->spi->irq);
}
sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
- sigma_delta->trig->private_data = sigma_delta;
+ iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta);
ret = iio_trigger_register(sigma_delta->trig);
if (ret)
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 83c836ba600f..e5b88d5d3b59 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -52,11 +52,15 @@ struct at91_adc_state {
void __iomem *reg_base;
struct at91_adc_reg_desc *registers;
u8 startup_time;
+ u8 sample_hold_time;
+ bool sleep_mode;
struct iio_trigger **trig;
struct at91_adc_trigger *trigger_list;
u32 trigger_number;
bool use_external;
u32 vref_mv;
+ u32 res; /* resolution used for convertions */
+ bool low_res; /* the resolution corresponds to the lowest one */
wait_queue_head_t wq_data_avail;
};
@@ -138,10 +142,10 @@ static int at91_adc_channel_init(struct iio_dev *idev)
chan->channel = bit;
chan->scan_index = idx;
chan->scan_type.sign = 'u';
- chan->scan_type.realbits = 10;
+ chan->scan_type.realbits = st->res;
chan->scan_type.storagebits = 16;
- chan->info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_RAW_SEPARATE_BIT;
+ chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
+ chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
idx++;
}
timestamp = chan_array + idx;
@@ -188,7 +192,7 @@ static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
{
- struct iio_dev *idev = trig->private_data;
+ struct iio_dev *idev = iio_trigger_get_drvdata(trig);
struct at91_adc_state *st = iio_priv(idev);
struct iio_buffer *buffer = idev->buffer;
struct at91_adc_reg_desc *reg = st->registers;
@@ -254,7 +258,7 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev,
return NULL;
trig->dev.parent = idev->dev.parent;
- trig->private_data = idev;
+ iio_trigger_set_drvdata(trig, idev);
trig->ops = &at91_adc_trigger_ops;
ret = iio_trigger_register(trig);
@@ -372,6 +376,59 @@ static int at91_adc_read_raw(struct iio_dev *idev,
return -EINVAL;
}
+static int at91_adc_of_get_resolution(struct at91_adc_state *st,
+ struct platform_device *pdev)
+{
+ struct iio_dev *idev = iio_priv_to_dev(st);
+ struct device_node *np = pdev->dev.of_node;
+ int count, i, ret = 0;
+ char *res_name, *s;
+ u32 *resolutions;
+
+ count = of_property_count_strings(np, "atmel,adc-res-names");
+ if (count < 2) {
+ dev_err(&idev->dev, "You must specified at least two resolution names for "
+ "adc-res-names property in the DT\n");
+ return count;
+ }
+
+ resolutions = kmalloc(count * sizeof(*resolutions), GFP_KERNEL);
+ if (!resolutions)
+ return -ENOMEM;
+
+ if (of_property_read_u32_array(np, "atmel,adc-res", resolutions, count)) {
+ dev_err(&idev->dev, "Missing adc-res property in the DT.\n");
+ ret = -ENODEV;
+ goto ret;
+ }
+
+ if (of_property_read_string(np, "atmel,adc-use-res", (const char **)&res_name))
+ res_name = "highres";
+
+ for (i = 0; i < count; i++) {
+ if (of_property_read_string_index(np, "atmel,adc-res-names", i, (const char **)&s))
+ continue;
+
+ if (strcmp(res_name, s))
+ continue;
+
+ st->res = resolutions[i];
+ if (!strcmp(res_name, "lowres"))
+ st->low_res = true;
+ else
+ st->low_res = false;
+
+ dev_info(&idev->dev, "Resolution used: %u bits\n", st->res);
+ goto ret;
+ }
+
+ dev_err(&idev->dev, "There is no resolution for %s\n", res_name);
+
+ret:
+ kfree(resolutions);
+ return ret;
+}
+
static int at91_adc_probe_dt(struct at91_adc_state *st,
struct platform_device *pdev)
{
@@ -400,6 +457,8 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
}
st->num_channels = prop;
+ st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");
+
if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n");
ret = -EINVAL;
@@ -407,6 +466,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
}
st->startup_time = prop;
+ prop = 0;
+ of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop);
+ st->sample_hold_time = prop;
if (of_property_read_u32(node, "atmel,adc-vref", &prop)) {
dev_err(&idev->dev, "Missing adc-vref property in the DT.\n");
@@ -415,6 +477,10 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
}
st->vref_mv = prop;
+ ret = at91_adc_of_get_resolution(st, pdev);
+ if (ret)
+ goto error_ret;
+
st->registers = devm_kzalloc(&idev->dev,
sizeof(struct at91_adc_reg_desc),
GFP_KERNEL);
@@ -516,11 +582,12 @@ static const struct iio_info at91_adc_info = {
static int at91_adc_probe(struct platform_device *pdev)
{
- unsigned int prsc, mstrclk, ticks, adc_clk;
+ unsigned int prsc, mstrclk, ticks, adc_clk, shtim;
int ret;
struct iio_dev *idev;
struct at91_adc_state *st;
struct resource *res;
+ u32 reg;
idev = iio_device_alloc(sizeof(struct at91_adc_state));
if (idev == NULL) {
@@ -628,9 +695,22 @@ static int at91_adc_probe(struct platform_device *pdev)
*/
ticks = round_up((st->startup_time * adc_clk /
1000000) - 1, 8) / 8;
- at91_adc_writel(st, AT91_ADC_MR,
- (AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL) |
- (AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP));
+ /*
+ * a minimal Sample and Hold Time is necessary for the ADC to guarantee
+ * the best converted final value between two channels selection
+ * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock
+ */
+ shtim = round_up((st->sample_hold_time * adc_clk /
+ 1000000) - 1, 1);
+
+ reg = AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL;
+ reg |= AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP;
+ if (st->low_res)
+ reg |= AT91_ADC_LOWRES;
+ if (st->sleep_mode)
+ reg |= AT91_ADC_SLEEP;
+ reg |= AT91_ADC_SHTIM_(shtim) & AT91_ADC_SHTIM;
+ at91_adc_writel(st, AT91_ADC_MR, reg);
/* Setup the ADC channels available on the board */
ret = at91_adc_channel_init(idev);
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
new file mode 100644
index 000000000000..9f3a8ef1fb3e
--- /dev/null
+++ b/drivers/iio/adc/exynos_adc.c
@@ -0,0 +1,452 @@
+/*
+ * exynos_adc.c - Support for ADC in EXYNOS SoCs
+ *
+ * 8 ~ 10 channel, 10/12-bit ADC
+ *
+ * Copyright (C) 2013 Naveen Krishna Chatradhi <ch.naveen@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_platform.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/machine.h>
+#include <linux/iio/driver.h>
+
+enum adc_version {
+ ADC_V1,
+ ADC_V2
+};
+
+/* EXYNOS4412/5250 ADC_V1 registers definitions */
+#define ADC_V1_CON(x) ((x) + 0x00)
+#define ADC_V1_DLY(x) ((x) + 0x08)
+#define ADC_V1_DATX(x) ((x) + 0x0C)
+#define ADC_V1_INTCLR(x) ((x) + 0x18)
+#define ADC_V1_MUX(x) ((x) + 0x1c)
+
+/* Future ADC_V2 registers definitions */
+#define ADC_V2_CON1(x) ((x) + 0x00)
+#define ADC_V2_CON2(x) ((x) + 0x04)
+#define ADC_V2_STAT(x) ((x) + 0x08)
+#define ADC_V2_INT_EN(x) ((x) + 0x10)
+#define ADC_V2_INT_ST(x) ((x) + 0x14)
+#define ADC_V2_VER(x) ((x) + 0x20)
+
+/* Bit definitions for ADC_V1 */
+#define ADC_V1_CON_RES (1u << 16)
+#define ADC_V1_CON_PRSCEN (1u << 14)
+#define ADC_V1_CON_PRSCLV(x) (((x) & 0xFF) << 6)
+#define ADC_V1_CON_STANDBY (1u << 2)
+
+/* Bit definitions for ADC_V2 */
+#define ADC_V2_CON1_SOFT_RESET (1u << 2)
+
+#define ADC_V2_CON2_OSEL (1u << 10)
+#define ADC_V2_CON2_ESEL (1u << 9)
+#define ADC_V2_CON2_HIGHF (1u << 8)
+#define ADC_V2_CON2_C_TIME(x) (((x) & 7) << 4)
+#define ADC_V2_CON2_ACH_SEL(x) (((x) & 0xF) << 0)
+#define ADC_V2_CON2_ACH_MASK 0xF
+
+#define MAX_ADC_V2_CHANNELS 10
+#define MAX_ADC_V1_CHANNELS 8
+
+/* Bit definitions common for ADC_V1 and ADC_V2 */
+#define ADC_CON_EN_START (1u << 0)
+#define ADC_DATX_MASK 0xFFF
+
+#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(1000))
+
+struct exynos_adc {
+ void __iomem *regs;
+ void __iomem *enable_reg;
+ struct clk *clk;
+ unsigned int irq;
+ struct regulator *vdd;
+
+ struct completion completion;
+
+ u32 value;
+ unsigned int version;
+};
+
+static const struct of_device_id exynos_adc_match[] = {
+ { .compatible = "samsung,exynos-adc-v1", .data = (void *)ADC_V1 },
+ { .compatible = "samsung,exynos-adc-v2", .data = (void *)ADC_V2 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_adc_match);
+
+static inline unsigned int exynos_adc_get_version(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+
+ match = of_match_node(exynos_adc_match, pdev->dev.of_node);
+ return (unsigned int)match->data;
+}
+
+static int exynos_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+ struct exynos_adc *info = iio_priv(indio_dev);
+ unsigned long timeout;
+ u32 con1, con2;
+
+ if (mask != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+
+ /* Select the channel to be used and Trigger conversion */
+ if (info->version == ADC_V2) {
+ con2 = readl(ADC_V2_CON2(info->regs));
+ con2 &= ~ADC_V2_CON2_ACH_MASK;
+ con2 |= ADC_V2_CON2_ACH_SEL(chan->address);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ con1 = readl(ADC_V2_CON1(info->regs));
+ writel(con1 | ADC_CON_EN_START,
+ ADC_V2_CON1(info->regs));
+ } else {
+ writel(chan->address, ADC_V1_MUX(info->regs));
+
+ con1 = readl(ADC_V1_CON(info->regs));
+ writel(con1 | ADC_CON_EN_START,
+ ADC_V1_CON(info->regs));
+ }
+
+ timeout = wait_for_completion_interruptible_timeout
+ (&info->completion, EXYNOS_ADC_TIMEOUT);
+ *val = info->value;
+
+ mutex_unlock(&indio_dev->mlock);
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ return IIO_VAL_INT;
+}
+
+static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
+{
+ struct exynos_adc *info = (struct exynos_adc *)dev_id;
+
+ /* Read value */
+ info->value = readl(ADC_V1_DATX(info->regs)) &
+ ADC_DATX_MASK;
+ /* clear irq */
+ if (info->version == ADC_V2)
+ writel(1, ADC_V2_INT_ST(info->regs));
+ else
+ writel(1, ADC_V1_INTCLR(info->regs));
+
+ complete(&info->completion);
+
+ return IRQ_HANDLED;
+}
+
+static int exynos_adc_reg_access(struct iio_dev *indio_dev,
+ unsigned reg, unsigned writeval,
+ unsigned *readval)
+{
+ struct exynos_adc *info = iio_priv(indio_dev);
+
+ if (readval == NULL)
+ return -EINVAL;
+
+ *readval = readl(info->regs + reg);
+
+ return 0;
+}
+
+static const struct iio_info exynos_adc_iio_info = {
+ .read_raw = &exynos_read_raw,
+ .debugfs_reg_access = &exynos_adc_reg_access,
+ .driver_module = THIS_MODULE,
+};
+
+#define ADC_CHANNEL(_index, _id) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = _index, \
+ .address = _index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .datasheet_name = _id, \
+}
+
+static const struct iio_chan_spec exynos_adc_iio_channels[] = {
+ ADC_CHANNEL(0, "adc0"),
+ ADC_CHANNEL(1, "adc1"),
+ ADC_CHANNEL(2, "adc2"),
+ ADC_CHANNEL(3, "adc3"),
+ ADC_CHANNEL(4, "adc4"),
+ ADC_CHANNEL(5, "adc5"),
+ ADC_CHANNEL(6, "adc6"),
+ ADC_CHANNEL(7, "adc7"),
+ ADC_CHANNEL(8, "adc8"),
+ ADC_CHANNEL(9, "adc9"),
+};
+
+static int exynos_adc_remove_devices(struct device *dev, void *c)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ platform_device_unregister(pdev);
+
+ return 0;
+}
+
+static void exynos_adc_hw_init(struct exynos_adc *info)
+{
+ u32 con1, con2;
+
+ if (info->version == ADC_V2) {
+ con1 = ADC_V2_CON1_SOFT_RESET;
+ writel(con1, ADC_V2_CON1(info->regs));
+
+ con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
+ ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ /* Enable interrupts */
+ writel(1, ADC_V2_INT_EN(info->regs));
+ } else {
+ /* set default prescaler values and Enable prescaler */
+ con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+
+ /* Enable 12-bit ADC resolution */
+ con1 |= ADC_V1_CON_RES;
+ writel(con1, ADC_V1_CON(info->regs));
+ }
+}
+
+static int exynos_adc_probe(struct platform_device *pdev)
+{
+ struct exynos_adc *info = NULL;
+ struct device_node *np = pdev->dev.of_node;
+ struct iio_dev *indio_dev = NULL;
+ struct resource *mem;
+ int ret = -ENODEV;
+ int irq;
+
+ if (!np)
+ return ret;
+
+ indio_dev = iio_device_alloc(sizeof(struct exynos_adc));
+ if (!indio_dev) {
+ dev_err(&pdev->dev, "failed allocating iio device\n");
+ return -ENOMEM;
+ }
+
+ info = iio_priv(indio_dev);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ info->regs = devm_request_and_ioremap(&pdev->dev, mem);
+ if (!info->regs) {
+ ret = -ENOMEM;
+ goto err_iio;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ info->enable_reg = devm_request_and_ioremap(&pdev->dev, mem);
+ if (!info->enable_reg) {
+ ret = -ENOMEM;
+ goto err_iio;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq resource?\n");
+ ret = irq;
+ goto err_iio;
+ }
+
+ info->irq = irq;
+
+ init_completion(&info->completion);
+
+ ret = request_irq(info->irq, exynos_adc_isr,
+ 0, dev_name(&pdev->dev), info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
+ info->irq);
+ goto err_iio;
+ }
+
+ writel(1, info->enable_reg);
+
+ info->clk = devm_clk_get(&pdev->dev, "adc");
+ if (IS_ERR(info->clk)) {
+ dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
+ PTR_ERR(info->clk));
+ ret = PTR_ERR(info->clk);
+ goto err_irq;
+ }
+
+ info->vdd = devm_regulator_get(&pdev->dev, "vdd");
+ if (IS_ERR(info->vdd)) {
+ dev_err(&pdev->dev, "failed getting regulator, err = %ld\n",
+ PTR_ERR(info->vdd));
+ ret = PTR_ERR(info->vdd);
+ goto err_irq;
+ }
+
+ info->version = exynos_adc_get_version(pdev);
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ indio_dev->name = dev_name(&pdev->dev);
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->dev.of_node = pdev->dev.of_node;
+ indio_dev->info = &exynos_adc_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = exynos_adc_iio_channels;
+
+ if (info->version == ADC_V1)
+ indio_dev->num_channels = MAX_ADC_V1_CHANNELS;
+ else
+ indio_dev->num_channels = MAX_ADC_V2_CHANNELS;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_irq;
+
+ ret = regulator_enable(info->vdd);
+ if (ret)
+ goto err_iio_dev;
+
+ clk_prepare_enable(info->clk);
+
+ exynos_adc_hw_init(info);
+
+ ret = of_platform_populate(np, exynos_adc_match, NULL, &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed adding child nodes\n");
+ goto err_of_populate;
+ }
+
+ return 0;
+
+err_of_populate:
+ device_for_each_child(&pdev->dev, NULL,
+ exynos_adc_remove_devices);
+ regulator_disable(info->vdd);
+ clk_disable_unprepare(info->clk);
+err_iio_dev:
+ iio_device_unregister(indio_dev);
+err_irq:
+ free_irq(info->irq, info);
+err_iio:
+ iio_device_free(indio_dev);
+ return ret;
+}
+
+static int exynos_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct exynos_adc *info = iio_priv(indio_dev);
+
+ device_for_each_child(&pdev->dev, NULL,
+ exynos_adc_remove_devices);
+ regulator_disable(info->vdd);
+ clk_disable_unprepare(info->clk);
+ writel(0, info->enable_reg);
+ iio_device_unregister(indio_dev);
+ free_irq(info->irq, info);
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_adc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct exynos_adc *info = platform_get_drvdata(pdev);
+ u32 con;
+
+ if (info->version == ADC_V2) {
+ con = readl(ADC_V2_CON1(info->regs));
+ con &= ~ADC_CON_EN_START;
+ writel(con, ADC_V2_CON1(info->regs));
+ } else {
+ con = readl(ADC_V1_CON(info->regs));
+ con |= ADC_V1_CON_STANDBY;
+ writel(con, ADC_V1_CON(info->regs));
+ }
+
+ clk_disable_unprepare(info->clk);
+ writel(0, info->enable_reg);
+ regulator_disable(info->vdd);
+
+ return 0;
+}
+
+static int exynos_adc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct exynos_adc *info = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = regulator_enable(info->vdd);
+ if (ret)
+ return ret;
+
+ writel(1, info->enable_reg);
+ clk_prepare_enable(info->clk);
+
+ exynos_adc_hw_init(info);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(exynos_adc_pm_ops,
+ exynos_adc_suspend,
+ exynos_adc_resume);
+
+static struct platform_driver exynos_adc_driver = {
+ .probe = exynos_adc_probe,
+ .remove = exynos_adc_remove,
+ .driver = {
+ .name = "exynos-adc",
+ .owner = THIS_MODULE,
+ .of_match_table = exynos_adc_match,
+ .pm = &exynos_adc_pm_ops,
+ },
+};
+
+module_platform_driver(exynos_adc_driver);
+
+MODULE_AUTHOR("Naveen Krishna Chatradhi <ch.naveen@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS5 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
index 763f57565ee4..62bc39e9c94f 100644
--- a/drivers/iio/adc/lp8788_adc.c
+++ b/drivers/iio/adc/lp8788_adc.c
@@ -132,8 +132,8 @@ static const struct iio_info lp8788_adc_info = {
.type = _type, \
.indexed = 1, \
.channel = LPADC_##_id, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = #_id, \
}
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 6c1cfb74bdfc..9e6da72ad823 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -427,15 +427,15 @@ static const enum max1363_modes max1363_mode_list[] = {
#define MAX1363_EV_M \
(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \
| IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
-#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT)
+
#define MAX1363_CHAN_U(num, addr, si, bits, evmask) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = num, \
.address = addr, \
- .info_mask = MAX1363_INFO_MASK, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = "AIN"#num, \
.scan_type = { \
.sign = 'u', \
@@ -456,7 +456,8 @@ static const enum max1363_modes max1363_mode_list[] = {
.channel = num, \
.channel2 = num2, \
.address = addr, \
- .info_mask = MAX1363_INFO_MASK, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = "AIN"#num"-AIN"#num2, \
.scan_type = { \
.sign = 's', \
diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c
index f4a46dd8f43b..2826faae706c 100644
--- a/drivers/iio/adc/ti-adc081c.c
+++ b/drivers/iio/adc/ti-adc081c.c
@@ -55,8 +55,8 @@ static int adc081c_read_raw(struct iio_dev *iio,
static const struct iio_chan_spec adc081c_channel = {
.type = IIO_VOLTAGE,
- .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_RAW_SEPARATE_BIT,
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
};
static const struct iio_info adc081c_info = {
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index cd030e100c39..5f9a7e7d3135 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -89,7 +89,7 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
chan->type = IIO_VOLTAGE;
chan->indexed = 1;
chan->channel = i;
- chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
+ chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
}
indio_dev->channels = chan_array;
diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c
index ad0261533dee..56ac481c73c0 100644
--- a/drivers/iio/adc/viperboard_adc.c
+++ b/drivers/iio/adc/viperboard_adc.c
@@ -41,7 +41,7 @@ struct vprbrd_adc {
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = _index, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.scan_index = _index, \
.scan_type = { \
.sign = 'u', \
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
index d6c0af23a2a7..d354554b51b3 100644
--- a/drivers/iio/amplifiers/ad8366.c
+++ b/drivers/iio/amplifiers/ad8366.c
@@ -125,7 +125,7 @@ static const struct iio_info ad8366_info = {
.output = 1, \
.indexed = 1, \
.channel = _channel, \
- .info_mask = IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT,\
+ .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN),\
}
static const struct iio_chan_spec ad8366_channels[] = {
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 7a525a91105d..87419c41b991 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -31,7 +31,7 @@
static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
- struct hid_sensor_common *st = trig->private_data;
+ struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
int state_val;
state_val = state ? 1 : 0;
@@ -76,7 +76,7 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
}
trig->dev.parent = indio_dev->dev.parent;
- trig->private_data = attrb;
+ iio_trigger_set_drvdata(trig, attrb);
trig->ops = &hid_sensor_trigger_ops;
ret = iio_trigger_register(trig);
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
index f0aa2f105222..251baf6abc25 100644
--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -29,7 +29,6 @@ static unsigned int st_sensors_spi_get_irq(struct iio_dev *indio_dev)
static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
struct device *dev, u8 reg_addr, int len, u8 *data, bool multiread_bit)
{
- struct spi_message msg;
int err;
struct spi_transfer xfers[] = {
@@ -51,10 +50,7 @@ static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
else
tb->tx_buf[0] = reg_addr | ST_SENSORS_SPI_READ;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- err = spi_sync(to_spi_device(dev), &msg);
+ err = spi_sync_transfer(to_spi_device(dev), xfers, ARRAY_SIZE(xfers));
if (err)
goto acc_spi_read_error;
@@ -83,7 +79,6 @@ static int st_sensors_spi_read_multiple_byte(
static int st_sensors_spi_write_byte(struct st_sensor_transfer_buffer *tb,
struct device *dev, u8 reg_addr, u8 data)
{
- struct spi_message msg;
int err;
struct spi_transfer xfers = {
@@ -96,9 +91,7 @@ static int st_sensors_spi_write_byte(struct st_sensor_transfer_buffer *tb,
tb->tx_buf[0] = reg_addr;
tb->tx_buf[1] = data;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers, &msg);
- err = spi_sync(to_spi_device(dev), &msg);
+ err = spi_sync_transfer(to_spi_device(dev), &xfers, 1);
mutex_unlock(&tb->buf_lock);
return err;
diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c
index 139ed030abb0..8fc3a97eb266 100644
--- a/drivers/iio/common/st_sensors/st_sensors_trigger.c
+++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c
@@ -40,7 +40,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
if (err)
goto request_irq_error;
- sdata->trig->private_data = indio_dev;
+ iio_trigger_set_drvdata(sdata->trig, indio_dev);
sdata->trig->ops = trigger_ops;
sdata->trig->dev.parent = sdata->dev;
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index 74f2d52795f6..aa26d50ab638 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -296,8 +296,8 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
.indexed = 1, \
.output = 1, \
.channel = (chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.address = addr, \
.scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \
.ext_info = ad5064_ext_info, \
diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c
index 92771217f665..80923af424f2 100644
--- a/drivers/iio/dac/ad5360.c
+++ b/drivers/iio/dac/ad5360.c
@@ -102,11 +102,11 @@ enum ad5360_type {
.type = IIO_VOLTAGE, \
.indexed = 1, \
.output = 1, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
.scan_type = IIO_ST('u', (bits), 16, 16 - (bits)) \
}
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c
index 483fc379a2da..bf2db02215c2 100644
--- a/drivers/iio/dac/ad5380.c
+++ b/drivers/iio/dac/ad5380.c
@@ -257,10 +257,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
.type = IIO_VOLTAGE, \
.indexed = 1, \
.output = 1, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)), \
.ext_info = ad5380_ext_info, \
}
diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c
index 6b86a638dad0..98f24407c3ce 100644
--- a/drivers/iio/dac/ad5421.c
+++ b/drivers/iio/dac/ad5421.c
@@ -86,11 +86,11 @@ static const struct iio_chan_spec ad5421_channels[] = {
.indexed = 1,
.output = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SHARED_BIT |
- IIO_CHAN_INFO_OFFSET_SHARED_BIT |
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_CALIBSCALE) |
+ BIT(IIO_CHAN_INFO_CALIBBIAS),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
.scan_type = IIO_ST('u', 16, 16, 0),
.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c
index f5583aedfb59..cae8f6056ac3 100644
--- a/drivers/iio/dac/ad5446.c
+++ b/drivers/iio/dac/ad5446.c
@@ -143,8 +143,8 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
.indexed = 1, \
.output = 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), \
.scan_type = IIO_ST('u', (bits), (storage), (shift)), \
.ext_info = (ext), \
}
diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c
index c4731b7b577b..ba1c914b0399 100644
--- a/drivers/iio/dac/ad5449.c
+++ b/drivers/iio/dac/ad5449.c
@@ -206,8 +206,8 @@ static const struct iio_info ad5449_info = {
.indexed = 1, \
.output = 1, \
.channel = (chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.address = (chan), \
.scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \
}
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
index e5e59749f109..139206e84cb7 100644
--- a/drivers/iio/dac/ad5504.c
+++ b/drivers/iio/dac/ad5504.c
@@ -259,8 +259,8 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
.indexed = 1, \
.output = 1, \
.channel = (_chan), \
- .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 = AD5504_ADDR_DAC(_chan), \
.scan_type = IIO_ST('u', 12, 16, 0), \
.ext_info = ad5504_ext_info, \
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c
index f6e116627b71..bb298aaff321 100644
--- a/drivers/iio/dac/ad5624r_spi.c
+++ b/drivers/iio/dac/ad5624r_spi.c
@@ -174,8 +174,8 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
.indexed = 1, \
.output = 1, \
.channel = (_chan), \
- .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 = (_chan), \
.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
.ext_info = ad5624r_ext_info, \
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 5e554af21703..06439b1af9b6 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -276,9 +276,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
.indexed = 1, \
.output = 1, \
.channel = chan, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT, \
- .address = AD5686_ADDR_DAC(chan), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
+ .address = AD5686_ADDR_DAC(chan), \
.scan_type = IIO_ST('u', bits, 16, shift), \
.ext_info = ad5686_ext_info, \
}
diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c
index 71faabc6b14e..12bb315e55f8 100644
--- a/drivers/iio/dac/ad5755.c
+++ b/drivers/iio/dac/ad5755.c
@@ -393,11 +393,11 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
#define AD5755_CHANNEL(_bits) { \
.indexed = 1, \
.output = 1, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
.ext_info = ad5755_ext_info, \
}
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c
index 5b7acd3a2c77..7a53f7d70dac 100644
--- a/drivers/iio/dac/ad5764.c
+++ b/drivers/iio/dac/ad5764.c
@@ -78,11 +78,11 @@ enum ad5764_type {
.output = 1, \
.channel = (_chan), \
.address = (_chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_OFFSET_SHARED_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET), \
.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)) \
}
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
index 8dfd3da8a07b..97c1e5d780df 100644
--- a/drivers/iio/dac/ad5791.c
+++ b/drivers/iio/dac/ad5791.c
@@ -302,9 +302,9 @@ static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
.indexed = 1, \
.address = AD5791_ADDR_DAC0, \
.channel = 0, \
- .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_type = IIO_ST('u', bits, 24, shift), \
.ext_info = ad5791_ext_info, \
}
diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c
index 352abe2004a4..ebfaa4156246 100644
--- a/drivers/iio/dac/max517.c
+++ b/drivers/iio/dac/max517.c
@@ -146,8 +146,8 @@ static const struct iio_info max517_info = {
.indexed = 1, \
.output = 1, \
.channel = (chan), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.scan_type = IIO_ST('u', 8, 8, 0), \
}
diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c
index 8f88cc4059a2..a612ec766d96 100644
--- a/drivers/iio/dac/mcp4725.c
+++ b/drivers/iio/dac/mcp4725.c
@@ -69,8 +69,8 @@ static const struct iio_chan_spec mcp4725_channel = {
.indexed = 1,
.output = 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),
.scan_type = IIO_ST('u', 12, 16, 0),
};
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 1ea132e239ea..92276deeb026 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -920,10 +920,10 @@ static int ad9523_setup(struct iio_dev *indio_dev)
st->ad9523_channels[i].channel = chan->channel_num;
st->ad9523_channels[i].extend_name =
chan->extended_name;
- st->ad9523_channels[i].info_mask =
- IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_PHASE_SEPARATE_BIT |
- IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT;
+ st->ad9523_channels[i].info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_PHASE) |
+ BIT(IIO_CHAN_INFO_FREQUENCY);
}
}
diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c
index 1861287911f1..e1bb5f994a54 100644
--- a/drivers/iio/gyro/adis16080.c
+++ b/drivers/iio/gyro/adis16080.c
@@ -136,32 +136,32 @@ 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 |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
.address = ADIS16080_DIN_GYRO,
}, {
.type = IIO_VOLTAGE,
.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 = ADIS16080_DIN_AIN1,
}, {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
- .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 = ADIS16080_DIN_AIN2,
}, {
.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 = ADIS16080_DIN_TEMP,
}
};
diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c
index 8cb0bcbfd609..058e6d5c955f 100644
--- a/drivers/iio/gyro/adis16136.c
+++ b/drivers/iio/gyro/adis16136.c
@@ -357,10 +357,11 @@ static const struct iio_chan_spec adis16136_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_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_CALIBBIAS) |
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+
.address = ADIS16136_REG_GYRO_OUT2,
.scan_index = ADIS16136_SCAN_GYRO,
.scan_type = {
@@ -373,8 +374,8 @@ static const struct iio_chan_spec adis16136_channels[] = {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
.address = ADIS16136_REG_TEMP_OUT,
.scan_index = ADIS16136_SCAN_TEMP,
.scan_type = {
diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c
index 5b79953f7011..8bd72b490b7f 100644
--- a/drivers/iio/gyro/adxrs450.c
+++ b/drivers/iio/gyro/adxrs450.c
@@ -383,16 +383,16 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = {
.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,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_CALIBBIAS) |
+ BIT(IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
}, {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
}
},
[ID_ADXRS453] = {
@@ -400,15 +400,15 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = {
.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,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW),
}, {
.type = IIO_TEMP,
.indexed = 1,
.channel = 0,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
}
},
};
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index fcfc83a9f861..bc943dd47da5 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -60,28 +60,28 @@ static const struct iio_chan_spec gyro_3d_channels[] = {
.type = IIO_ANGL_VEL,
.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_ANGL_VEL,
.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_ANGL_VEL,
.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/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c
index f667d2c8c00f..6c43af9bb0a4 100644
--- a/drivers/iio/gyro/itg3200_buffer.c
+++ b/drivers/iio/gyro/itg3200_buffer.c
@@ -81,7 +81,7 @@ void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
static int itg3200_data_rdy_trigger_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);
int ret;
u8 msc;
@@ -129,7 +129,7 @@ int itg3200_probe_trigger(struct iio_dev *indio_dev)
st->trig->dev.parent = &st->i2c->dev;
st->trig->ops = &itg3200_trigger_ops;
- st->trig->private_data = indio_dev;
+ iio_trigger_set_drvdata(st->trig, indio_dev);
ret = iio_trigger_register(st->trig);
if (ret)
goto error_free_irq;
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
index df2e6aa5d73b..d66605d2629d 100644
--- a/drivers/iio/gyro/itg3200_core.c
+++ b/drivers/iio/gyro/itg3200_core.c
@@ -248,12 +248,6 @@ err_ret:
return ret;
}
-#define ITG3200_TEMP_INFO_MASK (IIO_CHAN_INFO_OFFSET_SHARED_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_RAW_SEPARATE_BIT)
-#define ITG3200_GYRO_INFO_MASK (IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_RAW_SEPARATE_BIT)
-
#define ITG3200_ST \
{ .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE }
@@ -261,7 +255,8 @@ err_ret:
.type = IIO_ANGL_VEL, \
.modified = 1, \
.channel2 = IIO_MOD_ ## _mod, \
- .info_mask = ITG3200_GYRO_INFO_MASK, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \
.scan_index = ITG3200_SCAN_GYRO_ ## _mod, \
.scan_type = ITG3200_ST, \
@@ -271,7 +266,9 @@ static const struct iio_chan_spec itg3200_channels[] = {
{
.type = IIO_TEMP,
.channel2 = IIO_NO_MOD,
- .info_mask = ITG3200_TEMP_INFO_MASK,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
.address = ITG3200_REG_TEMP_OUT_H,
.scan_index = ITG3200_SCAN_TEMP,
.scan_type = ITG3200_ST,
diff --git a/drivers/iio/gyro/st_gyro_buffer.c b/drivers/iio/gyro/st_gyro_buffer.c
index da4d122ec7dc..69017c7ec302 100644
--- a/drivers/iio/gyro/st_gyro_buffer.c
+++ b/drivers/iio/gyro/st_gyro_buffer.c
@@ -25,7 +25,7 @@
int st_gyro_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/iio_core.h b/drivers/iio/iio_core.h
index f652e6ae5a35..05c1b74502a3 100644
--- a/drivers/iio/iio_core.h
+++ b/drivers/iio/iio_core.h
@@ -18,6 +18,7 @@
struct iio_chan_spec;
struct iio_dev;
+extern struct device_type iio_device_type;
int __iio_add_chan_devattr(const char *postfix,
struct iio_chan_spec const *chan,
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index b7f215eab5de..f60591f0b925 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -484,8 +484,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.indexed = 1, \
.channel = 0, \
.extend_name = name, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.address = (addr), \
.scan_index = (si), \
.scan_type = { \
@@ -507,10 +507,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.type = IIO_ANGL_VEL, \
.modified = 1, \
.channel2 = IIO_MOD_ ## mod, \
- .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, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
.address = addr, \
.scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
.scan_type = { \
@@ -526,10 +526,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.type = IIO_ACCEL, \
.modified = 1, \
.channel2 = IIO_MOD_ ## mod, \
- .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, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
.address = (addr), \
.scan_index = ADIS16400_SCAN_ACC_ ## mod, \
.scan_type = { \
@@ -545,9 +545,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_ ## mod, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
.address = (addr), \
.scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
.scan_type = { \
@@ -568,10 +568,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.indexed = 1, \
.channel = 0, \
.extend_name = ADIS16400_MOD_TEMP_NAME_ ## mod, \
- .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, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_type = \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
.address = (addr), \
.scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
.scan_type = { \
@@ -587,9 +588,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.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, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.address = (addr), \
.scan_index = ADIS16350_SCAN_TEMP_X, \
.scan_type = { \
@@ -605,8 +606,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.type = IIO_INCLI, \
.modified = 1, \
.channel2 = IIO_MOD_ ## mod, \
- .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 = (addr), \
.scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
.scan_type = { \
@@ -646,8 +647,8 @@ static const struct iio_chan_spec adis16448_channels[] = {
ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 16),
{
.type = IIO_PRESSURE,
- .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 = ADIS16448_BARO_OUT,
.scan_index = ADIS16400_SCAN_BARO,
.scan_type = IIO_ST('s', 16, 16, 0),
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
index 8c26a5f7cd5d..b7db38376295 100644
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -591,15 +591,15 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
}
}
-#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info, _bits) \
+#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info_sep, _bits) \
{ \
.type = (_type), \
.modified = 1, \
.channel2 = (_mod), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SHARED_BIT | \
- _info, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | \
+ _info_sep, \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.address = (_address), \
.scan_index = (_si), \
.scan_type = { \
@@ -613,21 +613,21 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
#define ADIS16480_GYRO_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE), \
32)
#define ADIS16480_ACCEL_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
+ BIT(IIO_CHAN_INFO_CALIBSCALE), \
32)
#define ADIS16480_MAGN_CHANNEL(_mod) \
ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \
ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \
- IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
16)
#define ADIS16480_PRESSURE_CHANNEL() \
@@ -635,9 +635,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
.type = IIO_PRESSURE, \
.indexed = 1, \
.channel = 0, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.address = ADIS16480_REG_BAROM_OUT, \
.scan_index = ADIS16480_SCAN_BARO, \
.scan_type = { \
@@ -652,9 +652,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
.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 = ADIS16480_REG_TEMP_OUT, \
.scan_index = ADIS16480_SCAN_TEMP, \
.scan_type = { \
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
index 5a24c9cac343..e0017c22bb9c 100644
--- a/drivers/iio/imu/adis_trigger.c
+++ b/drivers/iio/imu/adis_trigger.c
@@ -19,7 +19,7 @@
static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
- struct adis *adis = trig->private_data;
+ struct adis *adis = iio_trigger_get_drvdata(trig);
return adis_enable_irq(adis, state);
}
@@ -57,7 +57,7 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
adis->trig->dev.parent = &adis->spi->dev;
adis->trig->ops = &adis_trigger_ops;
- adis->trig->private_data = adis;
+ iio_trigger_set_drvdata(adis->trig, adis);
ret = iio_trigger_register(adis->trig);
indio_dev->trig = adis->trig;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 37ca05b47e4b..fe4c61e219f3 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -544,8 +544,8 @@ static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev,
.type = _type, \
.modified = 1, \
.channel2 = _channel2, \
- .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT \
- | IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.scan_index = _index, \
.scan_type = { \
.sign = 's', \
@@ -564,9 +564,9 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
*/
{
.type = IIO_TEMP,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT
- | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT
- | IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
+ | BIT(IIO_CHAN_INFO_OFFSET)
+ | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = -1,
},
INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index 331781ffbb15..7da0832f187b 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -105,9 +105,8 @@ irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
s64 timestamp;
timestamp = iio_get_time_ns();
- spin_lock(&st->time_stamp_lock);
- kfifo_in(&st->timestamps, &timestamp, 1);
- spin_unlock(&st->time_stamp_lock);
+ kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
+ &st->time_stamp_lock);
return IRQ_WAKE_THREAD;
}
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index e1d0869e0ad1..03b9372c1212 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -103,7 +103,7 @@ static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
- return inv_mpu6050_set_enable(trig->private_data, state);
+ return inv_mpu6050_set_enable(iio_trigger_get_drvdata(trig), state);
}
static const struct iio_trigger_ops inv_mpu_trigger_ops = {
@@ -130,8 +130,8 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
if (ret)
goto error_free_trig;
st->trig->dev.parent = &st->client->dev;
- st->trig->private_data = indio_dev;
st->trig->ops = &inv_mpu_trigger_ops;
+ iio_trigger_set_drvdata(st->trig, indio_dev);
ret = iio_trigger_register(st->trig);
if (ret)
goto error_free_irq;
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 8848f16c547b..e145931ef1b8 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -691,21 +691,34 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
if (chan->channel < 0)
return 0;
- for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
- ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
+ for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
+ ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
chan,
&iio_read_channel_info,
&iio_write_channel_info,
- i/2,
- !(i%2),
+ i,
+ 0,
&indio_dev->dev,
&indio_dev->channel_attr_list);
- if (ret == -EBUSY && (i%2 == 0)) {
+ if (ret < 0)
+ goto error_ret;
+ attrcount++;
+ }
+ for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
+ ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
+ chan,
+ &iio_read_channel_info,
+ &iio_write_channel_info,
+ i,
+ 1,
+ &indio_dev->dev,
+ &indio_dev->channel_attr_list);
+ if (ret == -EBUSY) {
ret = 0;
continue;
- }
- if (ret < 0)
+ } else if (ret < 0) {
goto error_ret;
+ }
attrcount++;
}
@@ -847,7 +860,7 @@ static void iio_dev_release(struct device *device)
kfree(indio_dev);
}
-static struct device_type iio_dev_type = {
+struct device_type iio_device_type = {
.name = "iio_device",
.release = iio_dev_release,
};
@@ -869,7 +882,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
if (dev) {
dev->dev.groups = dev->groups;
- dev->dev.type = &iio_dev_type;
+ dev->dev.type = &iio_device_type;
dev->dev.bus = &iio_bus_type;
device_initialize(&dev->dev);
dev_set_drvdata(&dev->dev, (void *)dev);
@@ -960,6 +973,10 @@ int iio_device_register(struct iio_dev *indio_dev)
{
int ret;
+ /* If the calling driver did not initialize of_node, do it here */
+ if (!indio_dev->dev.of_node && indio_dev->dev.parent)
+ indio_dev->dev.of_node = indio_dev->dev.parent->of_node;
+
/* configure elements for the chrdev */
indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 261cae00557e..10aa9ef86cec 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -46,10 +46,11 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
{
struct iio_event_interface *ev_int = indio_dev->event_interface;
struct iio_event_data ev;
+ unsigned long flags;
int copied;
/* Does anyone care? */
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irqsave(&ev_int->wait.lock, flags);
if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
ev.id = ev_code;
@@ -59,7 +60,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
if (copied != 0)
wake_up_locked_poll(&ev_int->wait, POLLIN);
}
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irqrestore(&ev_int->wait.lock, flags);
return 0;
}
@@ -76,10 +77,10 @@ static unsigned int iio_event_poll(struct file *filep,
poll_wait(filep, &ev_int->wait, wait);
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irq(&ev_int->wait.lock);
if (!kfifo_is_empty(&ev_int->det_events))
events = POLLIN | POLLRDNORM;
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
return events;
}
@@ -96,14 +97,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
if (count < sizeof(struct iio_event_data))
return -EINVAL;
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irq(&ev_int->wait.lock);
if (kfifo_is_empty(&ev_int->det_events)) {
if (filep->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
goto error_unlock;
}
/* Blocking on device; waiting for something to be there */
- ret = wait_event_interruptible_locked(ev_int->wait,
+ ret = wait_event_interruptible_locked_irq(ev_int->wait,
!kfifo_is_empty(&ev_int->det_events));
if (ret)
goto error_unlock;
@@ -113,7 +114,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);
error_unlock:
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
return ret ? ret : copied;
}
@@ -122,7 +123,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
{
struct iio_event_interface *ev_int = filep->private_data;
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
/*
* In order to maintain a clean state for reopening,
@@ -130,7 +131,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
* any new __iio_push_event calls running.
*/
kfifo_reset_out(&ev_int->det_events);
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
return 0;
}
@@ -151,18 +152,18 @@ int iio_event_getfd(struct iio_dev *indio_dev)
if (ev_int == NULL)
return -ENODEV;
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irq(&ev_int->wait.lock);
if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
return -EBUSY;
}
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
fd = anon_inode_getfd("iio:event",
&iio_event_chrdev_fileops, ev_int, O_RDONLY);
if (fd < 0) {
- spin_lock(&ev_int->wait.lock);
+ spin_lock_irq(&ev_int->wait.lock);
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
- spin_unlock(&ev_int->wait.lock);
+ spin_unlock_irq(&ev_int->wait.lock);
}
return fd;
}
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index b289915b8469..795d100b4c36 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -10,6 +10,7 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/iio/iio.h>
#include "iio_core.h"
@@ -92,6 +93,164 @@ static const struct iio_chan_spec
return chan;
}
+#ifdef CONFIG_OF
+
+static int iio_dev_node_match(struct device *dev, void *data)
+{
+ return dev->of_node == data && dev->type == &iio_device_type;
+}
+
+static int __of_iio_channel_get(struct iio_channel *channel,
+ struct device_node *np, int index)
+{
+ struct device *idev;
+ struct iio_dev *indio_dev;
+ int err;
+ struct of_phandle_args iiospec;
+
+ err = of_parse_phandle_with_args(np, "io-channels",
+ "#io-channel-cells",
+ index, &iiospec);
+ if (err)
+ return err;
+
+ idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
+ iio_dev_node_match);
+ of_node_put(iiospec.np);
+ if (idev == NULL)
+ return -EPROBE_DEFER;
+
+ indio_dev = dev_to_iio_dev(idev);
+ channel->indio_dev = indio_dev;
+ index = iiospec.args_count ? iiospec.args[0] : 0;
+ if (index >= indio_dev->num_channels) {
+ return -EINVAL;
+ goto err_put;
+ }
+ channel->channel = &indio_dev->channels[index];
+
+ return 0;
+
+err_put:
+ iio_device_put(indio_dev);
+ return err;
+}
+
+static struct iio_channel *of_iio_channel_get(struct device_node *np, int index)
+{
+ struct iio_channel *channel;
+ int err;
+
+ if (index < 0)
+ return ERR_PTR(-EINVAL);
+
+ channel = kzalloc(sizeof(*channel), GFP_KERNEL);
+ if (channel == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ err = __of_iio_channel_get(channel, np, index);
+ if (err)
+ goto err_free_channel;
+
+ return channel;
+
+err_free_channel:
+ kfree(channel);
+ return ERR_PTR(err);
+}
+
+static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np,
+ const char *name)
+{
+ struct iio_channel *chan = NULL;
+
+ /* Walk up the tree of devices looking for a matching iio channel */
+ while (np) {
+ int index = 0;
+
+ /*
+ * For named iio channels, first look up the name in the
+ * "io-channel-names" property. If it cannot be found, the
+ * index will be an error code, and of_iio_channel_get()
+ * will fail.
+ */
+ if (name)
+ index = of_property_match_string(np, "io-channel-names",
+ name);
+ chan = of_iio_channel_get(np, index);
+ if (!IS_ERR(chan))
+ break;
+ else if (name && index >= 0) {
+ pr_err("ERROR: could not get IIO channel %s:%s(%i)\n",
+ np->full_name, name ? name : "", index);
+ return chan;
+ }
+
+ /*
+ * No matching IIO channel found on this node.
+ * If the parent node has a "io-channel-ranges" property,
+ * then we can try one of its channels.
+ */
+ np = np->parent;
+ if (np && !of_get_property(np, "io-channel-ranges", NULL))
+ break;
+ }
+ return chan;
+}
+
+static struct iio_channel *of_iio_channel_get_all(struct device *dev)
+{
+ struct iio_channel *chans;
+ int i, mapind, nummaps = 0;
+ int ret;
+
+ do {
+ ret = of_parse_phandle_with_args(dev->of_node,
+ "io-channels",
+ "#io-channel-cells",
+ nummaps, NULL);
+ if (ret < 0)
+ break;
+ } while (++nummaps);
+
+ if (nummaps == 0) /* no error, return NULL to search map table */
+ return NULL;
+
+ /* NULL terminated array to save passing size */
+ chans = kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL);
+ if (chans == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Search for OF matches */
+ for (mapind = 0; mapind < nummaps; mapind++) {
+ ret = __of_iio_channel_get(&chans[mapind], dev->of_node,
+ mapind);
+ if (ret)
+ goto error_free_chans;
+ }
+ return chans;
+
+error_free_chans:
+ for (i = 0; i < mapind; i++)
+ iio_device_put(chans[i].indio_dev);
+ kfree(chans);
+ return ERR_PTR(ret);
+}
+
+#else /* CONFIG_OF */
+
+static inline struct iio_channel *
+of_iio_channel_get_by_name(struct device_node *np, const char *name)
+{
+ return NULL;
+}
+
+static inline struct iio_channel *of_iio_channel_get_all(struct device *dev)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_OF */
static struct iio_channel *iio_channel_get_sys(const char *name,
const char *channel_name)
@@ -150,7 +309,14 @@ struct iio_channel *iio_channel_get(struct device *dev,
const char *channel_name)
{
const char *name = dev ? dev_name(dev) : NULL;
+ struct iio_channel *channel;
+ if (dev) {
+ channel = of_iio_channel_get_by_name(dev->of_node,
+ channel_name);
+ if (channel != NULL)
+ return channel;
+ }
return iio_channel_get_sys(name, channel_name);
}
EXPORT_SYMBOL_GPL(iio_channel_get);
@@ -173,6 +339,11 @@ struct iio_channel *iio_channel_get_all(struct device *dev)
if (dev == NULL)
return ERR_PTR(-EINVAL);
+
+ chans = of_iio_channel_get_all(dev);
+ if (chans)
+ return chans;
+
name = dev_name(dev);
mutex_lock(&iio_map_list_lock);
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c
index d5b9d39d95b2..5f4749e60b04 100644
--- a/drivers/iio/light/adjd_s311.c
+++ b/drivers/iio/light/adjd_s311.c
@@ -207,8 +207,8 @@ static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = {
.type = IIO_INTENSITY, \
.modified = 1, \
.address = (IDX_##_color), \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
- IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
.channel2 = (IIO_MOD_LIGHT_##_color), \
.scan_index = (_scan_idx), \
.scan_type = IIO_ST('u', 10, 16, 0), \
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 3d7e8c9b4beb..80d68ff02d29 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -49,10 +49,10 @@ static const struct iio_chan_spec als_channels[] = {
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_BOTH,
- .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_ILLUM,
}
};
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index 7503012ce933..5fa31a4ef82a 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -231,7 +231,7 @@ static int lm3533_als_read_raw(struct iio_dev *indio_dev,
.channel = _channel, \
.indexed = true, \
.output = true, \
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
}
static const struct iio_chan_spec lm3533_als_channels[] = {
@@ -239,8 +239,8 @@ static const struct iio_chan_spec lm3533_als_channels[] = {
.type = IIO_LIGHT,
.channel = 0,
.indexed = true,
- .info_mask = (IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_RAW_SEPARATE_BIT),
+ .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
+ BIT(IIO_CHAN_INFO_RAW),
},
CHANNEL_CURRENT(0),
CHANNEL_CURRENT(1),
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
index fd8be69b7d05..1f529f36f138 100644
--- a/drivers/iio/light/tsl2563.c
+++ b/drivers/iio/light/tsl2563.c
@@ -530,14 +530,14 @@ static const struct iio_chan_spec tsl2563_channels[] = {
{
.type = IIO_LIGHT,
.indexed = 1,
- .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
.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,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_CALIBSCALE),
.event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
IIO_EV_DIR_RISING) |
IIO_EV_BIT(IIO_EV_TYPE_THRESH,
@@ -546,8 +546,8 @@ static const struct iio_chan_spec tsl2563_channels[] = {
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_IR,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_CALIBSCALE),
}
};
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 2aa748fbdc0e..1014943d949a 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -93,11 +93,11 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
static const struct iio_chan_spec vcnl4000_channels[] = {
{
.type = IIO_LIGHT,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
- IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
}, {
.type = IIO_PROXIMITY,
- .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
}
};
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index cd29be54f643..bd1cfb666695 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -3,6 +3,17 @@
#
menu "Magnetometer sensors"
+config AK8975
+ tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
+ depends on I2C
+ depends on GPIOLIB
+ help
+ Say yes here to build support for Asahi Kasei AK8975 3-Axis
+ Magnetometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ak8975.
+
config HID_SENSOR_MAGNETOMETER_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index e78672876dc2..7f328e37fbab 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -2,6 +2,7 @@
# Makefile for industrial I/O Magnetometer sensor drivers
#
+obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
new file mode 100644
index 000000000000..af6c320a534e
--- /dev/null
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -0,0 +1,485 @@
+/*
+ * A sensor driver for the magnetometer AK8975.
+ *
+ * Magnetic compass sensor driver for monitoring magnetic flux information.
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include <linux/gpio.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+/*
+ * Register definitions, as well as various shifts and masks to get at the
+ * individual fields of the registers.
+ */
+#define AK8975_REG_WIA 0x00
+#define AK8975_DEVICE_ID 0x48
+
+#define AK8975_REG_INFO 0x01
+
+#define AK8975_REG_ST1 0x02
+#define AK8975_REG_ST1_DRDY_SHIFT 0
+#define AK8975_REG_ST1_DRDY_MASK (1 << AK8975_REG_ST1_DRDY_SHIFT)
+
+#define AK8975_REG_HXL 0x03
+#define AK8975_REG_HXH 0x04
+#define AK8975_REG_HYL 0x05
+#define AK8975_REG_HYH 0x06
+#define AK8975_REG_HZL 0x07
+#define AK8975_REG_HZH 0x08
+#define AK8975_REG_ST2 0x09
+#define AK8975_REG_ST2_DERR_SHIFT 2
+#define AK8975_REG_ST2_DERR_MASK (1 << AK8975_REG_ST2_DERR_SHIFT)
+
+#define AK8975_REG_ST2_HOFL_SHIFT 3
+#define AK8975_REG_ST2_HOFL_MASK (1 << AK8975_REG_ST2_HOFL_SHIFT)
+
+#define AK8975_REG_CNTL 0x0A
+#define AK8975_REG_CNTL_MODE_SHIFT 0
+#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT)
+#define AK8975_REG_CNTL_MODE_POWER_DOWN 0
+#define AK8975_REG_CNTL_MODE_ONCE 1
+#define AK8975_REG_CNTL_MODE_SELF_TEST 8
+#define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF
+
+#define AK8975_REG_RSVC 0x0B
+#define AK8975_REG_ASTC 0x0C
+#define AK8975_REG_TS1 0x0D
+#define AK8975_REG_TS2 0x0E
+#define AK8975_REG_I2CDIS 0x0F
+#define AK8975_REG_ASAX 0x10
+#define AK8975_REG_ASAY 0x11
+#define AK8975_REG_ASAZ 0x12
+
+#define AK8975_MAX_REGS AK8975_REG_ASAZ
+
+/*
+ * Miscellaneous values.
+ */
+#define AK8975_MAX_CONVERSION_TIMEOUT 500
+#define AK8975_CONVERSION_DONE_POLL_TIME 10
+
+/*
+ * Per-instance context data for the device.
+ */
+struct ak8975_data {
+ struct i2c_client *client;
+ struct attribute_group attrs;
+ struct mutex lock;
+ u8 asa[3];
+ long raw_to_gauss[3];
+ u8 reg_cache[AK8975_MAX_REGS];
+ int eoc_gpio;
+};
+
+static const int ak8975_index_to_reg[] = {
+ AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL,
+};
+
+/*
+ * Helper function to write to the I2C device's registers.
+ */
+static int ak8975_write_data(struct i2c_client *client,
+ u8 reg, u8 val, u8 mask, u8 shift)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
+ u8 regval;
+ int ret;
+
+ regval = (data->reg_cache[reg] & ~mask) | (val << shift);
+ ret = i2c_smbus_write_byte_data(client, reg, regval);
+ if (ret < 0) {
+ dev_err(&client->dev, "Write to device fails status %x\n", ret);
+ return ret;
+ }
+ data->reg_cache[reg] = regval;
+
+ return 0;
+}
+
+/*
+ * Perform some start-of-day setup, including reading the asa calibration
+ * values and caching them.
+ */
+static int ak8975_setup(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
+ u8 device_id;
+ int ret;
+
+ /* Confirm that the device we're talking to is really an AK8975. */
+ ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading WIA\n");
+ return ret;
+ }
+ device_id = ret;
+ if (device_id != AK8975_DEVICE_ID) {
+ dev_err(&client->dev, "Device ak8975 not found\n");
+ return -ENODEV;
+ }
+
+ /* Write the fused rom access mode. */
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ AK8975_REG_CNTL_MODE_FUSE_ROM,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting fuse access mode\n");
+ return ret;
+ }
+
+ /* Get asa data and store in the device data. */
+ ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
+ 3, data->asa);
+ if (ret < 0) {
+ dev_err(&client->dev, "Not able to read asa data\n");
+ return ret;
+ }
+
+ /* After reading fuse ROM data set power-down mode */
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ AK8975_REG_CNTL_MODE_POWER_DOWN,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting power-down mode\n");
+ return ret;
+ }
+
+/*
+ * Precalculate scale factor (in Gauss units) for each axis and
+ * store in the device data.
+ *
+ * This scale factor is axis-dependent, and is derived from 3 calibration
+ * factors ASA(x), ASA(y), and ASA(z).
+ *
+ * These ASA values are read from the sensor device at start of day, and
+ * cached in the device context struct.
+ *
+ * Adjusting the flux value with the sensitivity adjustment value should be
+ * done via the following formula:
+ *
+ * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
+ *
+ * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
+ * is the resultant adjusted value.
+ *
+ * We reduce the formula to:
+ *
+ * Hadj = H * (ASA + 128) / 256
+ *
+ * H is in the range of -4096 to 4095. The magnetometer has a range of
+ * +-1229uT. To go from the raw value to uT is:
+ *
+ * HuT = H * 1229/4096, or roughly, 3/10.
+ *
+ * Since 1uT = 100 gauss, our final scale factor becomes:
+ *
+ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
+ * Hadj = H * ((ASA + 128) * 30 / 256
+ *
+ * Since ASA doesn't change, we cache the resultant scale factor into the
+ * device context in ak8975_setup().
+ */
+ data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
+ data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
+ data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
+
+ return 0;
+}
+
+static int wait_conversion_complete_gpio(struct ak8975_data *data)
+{
+ struct i2c_client *client = data->client;
+ u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
+ int ret;
+
+ /* Wait for the conversion to complete. */
+ while (timeout_ms) {
+ msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+ if (gpio_get_value(data->eoc_gpio))
+ break;
+ timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
+ }
+ if (!timeout_ms) {
+ dev_err(&client->dev, "Conversion timeout happened\n");
+ return -EINVAL;
+ }
+
+ ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+ if (ret < 0)
+ dev_err(&client->dev, "Error in reading ST1\n");
+
+ return ret;
+}
+
+static int wait_conversion_complete_polled(struct ak8975_data *data)
+{
+ struct i2c_client *client = data->client;
+ u8 read_status;
+ u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
+ int ret;
+
+ /* Wait for the conversion to complete. */
+ while (timeout_ms) {
+ msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+ ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in reading ST1\n");
+ return ret;
+ }
+ read_status = ret;
+ if (read_status)
+ break;
+ timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
+ }
+ if (!timeout_ms) {
+ dev_err(&client->dev, "Conversion timeout happened\n");
+ return -EINVAL;
+ }
+ return read_status;
+}
+
+/*
+ * Emits the raw flux value for the x, y, or z axis.
+ */
+static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
+{
+ struct ak8975_data *data = iio_priv(indio_dev);
+ struct i2c_client *client = data->client;
+ u16 meas_reg;
+ s16 raw;
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ /* Set up the device for taking a sample. */
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ AK8975_REG_CNTL_MODE_ONCE,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting operating mode\n");
+ goto exit;
+ }
+
+ /* Wait for the conversion to complete. */
+ if (gpio_is_valid(data->eoc_gpio))
+ ret = wait_conversion_complete_gpio(data);
+ else
+ ret = wait_conversion_complete_polled(data);
+ if (ret < 0)
+ goto exit;
+
+ if (ret & AK8975_REG_ST1_DRDY_MASK) {
+ ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in reading ST2\n");
+ goto exit;
+ }
+ if (ret & (AK8975_REG_ST2_DERR_MASK |
+ AK8975_REG_ST2_HOFL_MASK)) {
+ dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
+ ret = -EINVAL;
+ goto exit;
+ }
+ }
+
+ /* Read the flux value from the appropriate register
+ (the register is specified in the iio device attributes). */
+ ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
+ if (ret < 0) {
+ dev_err(&client->dev, "Read axis data fails\n");
+ goto exit;
+ }
+ meas_reg = ret;
+
+ mutex_unlock(&data->lock);
+
+ /* Endian conversion of the measured values. */
+ raw = (s16) (le16_to_cpu(meas_reg));
+
+ /* Clamp to valid range. */
+ raw = clamp_t(s16, raw, -4096, 4095);
+ *val = raw;
+ return IIO_VAL_INT;
+
+exit:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int ak8975_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2,
+ long mask)
+{
+ struct ak8975_data *data = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ return ak8975_read_axis(indio_dev, chan->address, val);
+ case IIO_CHAN_INFO_SCALE:
+ *val = data->raw_to_gauss[chan->address];
+ return IIO_VAL_INT;
+ }
+ return -EINVAL;
+}
+
+#define AK8975_CHANNEL(axis, index) \
+ { \
+ .type = IIO_MAGN, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ }
+
+static const struct iio_chan_spec ak8975_channels[] = {
+ AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2),
+};
+
+static const struct iio_info ak8975_info = {
+ .read_raw = &ak8975_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int ak8975_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ak8975_data *data;
+ struct iio_dev *indio_dev;
+ int eoc_gpio;
+ int err;
+
+ /* Grab and set up the supplied GPIO. */
+ if (client->dev.platform_data == NULL)
+ eoc_gpio = -1;
+ else
+ eoc_gpio = *(int *)(client->dev.platform_data);
+
+ /* We may not have a GPIO based IRQ to scan, that is fine, we will
+ poll if so */
+ if (gpio_is_valid(eoc_gpio)) {
+ err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975");
+ if (err < 0) {
+ dev_err(&client->dev,
+ "failed to request GPIO %d, error %d\n",
+ eoc_gpio, err);
+ goto exit;
+ }
+ }
+
+ /* Register with IIO */
+ indio_dev = iio_device_alloc(sizeof(*data));
+ if (indio_dev == NULL) {
+ err = -ENOMEM;
+ goto exit_gpio;
+ }
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ /* Perform some basic start-of-day setup of the device. */
+ err = ak8975_setup(client);
+ if (err < 0) {
+ dev_err(&client->dev, "AK8975 initialization fails\n");
+ goto exit_free_iio;
+ }
+
+ data->client = client;
+ mutex_init(&data->lock);
+ data->eoc_gpio = eoc_gpio;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = ak8975_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
+ indio_dev->info = &ak8975_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ err = iio_device_register(indio_dev);
+ if (err < 0)
+ goto exit_free_iio;
+
+ return 0;
+
+exit_free_iio:
+ iio_device_free(indio_dev);
+exit_gpio:
+ if (gpio_is_valid(eoc_gpio))
+ gpio_free(eoc_gpio);
+exit:
+ return err;
+}
+
+static int ak8975_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ if (gpio_is_valid(data->eoc_gpio))
+ gpio_free(data->eoc_gpio);
+
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id ak8975_id[] = {
+ {"ak8975", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ak8975_id);
+
+static const struct of_device_id ak8975_of_match[] = {
+ { .compatible = "asahi-kasei,ak8975", },
+ { .compatible = "ak8975", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ak8975_of_match);
+
+static struct i2c_driver ak8975_driver = {
+ .driver = {
+ .name = "ak8975",
+ .of_match_table = ak8975_of_match,
+ },
+ .probe = ak8975_probe,
+ .remove = ak8975_remove,
+ .id_table = ak8975_id,
+};
+module_i2c_driver(ak8975_driver);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("AK8975 magnetometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index d8d01265220b..99f4e494513b 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -60,28 +60,28 @@ static const struct iio_chan_spec magn_3d_channels[] = {
.type = IIO_MAGN,
.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_MAGN,
.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_MAGN,
.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,
}
};