diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 10:50:03 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 10:50:03 -0700 |
commit | ef994fda44d6b55ffef7bfdf06f645ff2ab1ab1a (patch) | |
tree | 564a62822ebb1f6f7e1f86b0eefc34bc769dff7d /drivers/iio | |
parent | 25eeb667599b192ea850a062d69383ee864c06ab (diff) | |
parent | 51b53dc991ae7eebc5d45b06d576da6486fbf823 (diff) | |
download | linux-stable-ef994fda44d6b55ffef7bfdf06f645ff2ab1ab1a.tar.gz linux-stable-ef994fda44d6b55ffef7bfdf06f645ff2ab1ab1a.tar.bz2 linux-stable-ef994fda44d6b55ffef7bfdf06f645ff2ab1ab1a.zip |
Merge tag 'iio-for-3.10a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
First set of IIO new drivers and cleanup for the 3.10 cycle.
New stuff
1) Add OF support for specifying mappings between iio devices and their
in kernel consumers.
2) Driver for AD7923 (extra functionality and support for ad7904, ad7914 and
ad7924 added later in series)
3) Driver for Exynos adc (dt suppor for phy added later in series).
4) Make iio_push_event save IRQ context - necessary if it is to be used
within an interrupt handler. Users of this functionality to follow.
5) For iio use the device tree node name to provide the hwmon name attribute
if available.
Removal and moves out of staging
1) Drop the adt7410 driver from IIO now that there is a hmwon driver with
equivalent support. This device is very much targeted at hardware
monitoring so hwmon is a more appropriate host for the driver.
2) Move iio_hwmon driver to drivers/hwmon.
Cleanups
1) Minor cleanup in ST common library.
2) Large set of patches to break the info_mask element which previously used
odd and even bits to specify if a channel attribute was either shared across
similar channels or specific to only one. Now we have two bitmaps, one for
those parameters that are specific to this channel and one for those shared
by all channels with the same type as this one. This has no effect on the
userspace abi. It simplifies the core code and provides more space for new
channel parameters. It has been on the todo list for a long time!
Conflicts:
drivers/iio/dac/ad5064.c
Diffstat (limited to 'drivers/iio')
52 files changed, 1292 insertions, 253 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/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/at91_adc.c b/drivers/iio/adc/at91_adc.c index 83c836ba600f..92eb6a5b9e72 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -140,8 +140,8 @@ static int at91_adc_channel_init(struct iio_dev *idev) chan->scan_type.sign = 'u'; chan->scan_type.realbits = 10; 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; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c new file mode 100644 index 000000000000..4a8a9a34228f --- /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 = of_match_ptr(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/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/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_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/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/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, ×tamp, 1); - spin_unlock(&st->time_stamp_lock); + kfifo_in_spinlocked(&st->timestamps, ×tamp, 1, + &st->time_stamp_lock); return IRQ_WAKE_THREAD; } 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/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, } }; |