[PATCH 3.14 19/44] iio: adis16400: Compute the scan mask from channel indices

Greg Kroah-Hartman
2015-06-19T21:05:02Z

From: Paul Cercueil <paul.cercueil@analog.com>

commit c2a8b623a089d52c199e305e7905829907db8ec8 upstream.

We unfortunately can't use ~0UL for the scan mask to indicate that the
only valid scan mask is all channels selected. The IIO core needs the exact
mask to work correctly and not a super-set of it. So calculate the masked
based on the channels that are available for a particular device.

Signed-off-by: Paul Cercueil <paul.cercueil@analog.com>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Fixes: 5eda3550a3cc ("staging:iio:adis16400: Preallocate transfer message")
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
drivers/iio/imu/adis16400.h | 1 +
drivers/iio/imu/adis16400_core.c | 25 ++++++++++++++++++-------
2 files changed, 19 insertions(+), 7 deletions(-)

--- a/drivers/iio/imu/adis16400.h
+++ b/drivers/iio/imu/adis16400.h
@@ -165,6 +165,7 @@ struct adis16400_state {
int filt_int;

struct adis adis;
+ unsigned long avail_scan_mask[2];
};

/* At the moment triggers are only used for ring buffer
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -824,11 +824,6 @@ static const struct iio_info adis16400_i
.debugfs_reg_access = adis_debugfs_reg_access,
};

-static const unsigned long adis16400_burst_scan_mask[] = {
- ~0UL,
- 0,
-};
-
static const char * const adis16400_status_error_msgs[] = {
[ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
[ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
@@ -876,6 +871,20 @@ static const struct adis_data adis16400_
BIT(ADIS16400_DIAG_STAT_POWER_LOW),
};

+static void adis16400_setup_chan_mask(struct adis16400_state *st)
+{
+ const struct adis16400_chip_info *chip_info = st->variant;
+ unsigned i;
+
+ for (i = 0; i < chip_info->num_channels; i++) {
+ const struct iio_chan_spec *ch = &chip_info->channels[i];
+
+ if (ch->scan_index >= 0 &&
+ ch->scan_index != ADIS16400_SCAN_TIMESTAMP)
+ st->avail_scan_mask[0] |= BIT(ch->scan_index);
+ }
+}
+
static int adis16400_probe(struct spi_device *spi)
{
struct adis16400_state *st;
@@ -899,8 +908,10 @@ static int adis16400_probe(struct spi_de
indio_dev->info = &adis16400_info;
indio_dev->modes = INDIO_DIRECT_MODE;

- if (!(st->variant->flags & ADIS16400_NO_BURST))
- indio_dev->available_scan_masks = adis16400_burst_scan_mask;
+ if (!(st->variant->flags & ADIS16400_NO_BURST)) {
+ adis16400_setup_chan_mask(st);
+ indio_dev->available_scan_masks = st->avail_scan_mask;
+ }

ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
if (ret)