]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
staging:iio: Switch the channel masks to bitmaps so as to allow for more channels.
authorJonathan Cameron <jic23@cam.ac.uk>
Fri, 2 Sep 2011 16:14:38 +0000 (17:14 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 6 Sep 2011 23:01:59 +0000 (16:01 -0700)
This is as light as possible on changes to current drivers.
Some drivers make assumptions that their masks fit in a single
long.  Given they were previously working this is clearly valid if
not tidy.

The max1363 is an example where there should be no such assumptions.

V2: Add the new ad5933

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Acked-by: Michael Hennerich <Michael.Hennerich@analog.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20 files changed:
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/adc/ad7298_ring.c
drivers/staging/iio/adc/ad7793.c
drivers/staging/iio/adc/ad7887.h
drivers/staging/iio/adc/ad7887_ring.c
drivers/staging/iio/adc/ad799x.h
drivers/staging/iio/adc/ad799x_core.c
drivers/staging/iio/adc/ad799x_ring.c
drivers/staging/iio/adc/max1363.h
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/adc/max1363_ring.c
drivers/staging/iio/iio.h
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/iio/imu/adis16400_ring.c
drivers/staging/iio/industrialio-ring.c
drivers/staging/iio/meter/ade7758.h
drivers/staging/iio/meter/ade7758_core.c
drivers/staging/iio/meter/ade7758_ring.c
drivers/staging/iio/ring_generic.h

index d67d78394cb9a621e1239b9c0d17ee7b34d9d5ec..c8169338b2761e59ca49e47467ed84dd185480f0 100644 (file)
@@ -61,8 +61,9 @@ ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
        ret = ring->access->read_last(ring, (u8 *)data);
        if (ret)
                goto error_free_data;
-       *val = data[bitmap_weight(&ring->scan_mask, index)];
+       *val = data[bitmap_weight(ring->scan_mask, index)];
 error_free_data:
+
        kfree(data);
 
        return ret;
@@ -99,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
        mutex_lock(&st->buf_lock);
 
        for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
-               if (ring->scan_mask & (1 << i)) {
+               if (test_bit(i, ring->scan_mask)) {
                        /* lower byte */
                        xfers[j].tx_buf = st->tx + 2*j;
                        st->tx[2*j] = read_all_tx_array[i*4];
index 80b067c5b21251f6fcd9182451e5dd276ee797e0..c67da6aac9999e0f45de044f9fa1413a161ff4cc 100644 (file)
@@ -146,7 +146,7 @@ struct ad7192_state {
        u32                             mode;
        u32                             conf;
        u32                             scale_avail[8][2];
-       u32                             available_scan_masks[9];
+       long                            available_scan_masks[9];
        u8                              gpocon;
        u8                              devid;
        /*
@@ -460,7 +460,7 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
        s64 dat64[2];
        u32 *dat32 = (u32 *)dat64;
 
-       if (!(ring->scan_mask & (1 << ch)))
+       if (!(test_bit(ch, ring->scan_mask)))
                return  -EBUSY;
 
        ret = ring->access->read_last(ring, (u8 *) &dat64);
@@ -482,7 +482,7 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev)
        if (!ring->scan_count)
                return -EINVAL;
 
-       channel = __ffs(ring->scan_mask);
+       channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
 
        d_size = ring->scan_count *
                 indio_dev->channels[0].scan_type.storagebits / 8;
index 741818c0b8290b2426fdf111e92e827779b4b628..246b2e724d385b41357d0f376efd83f7f3d80555 100644 (file)
@@ -24,7 +24,7 @@ int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch)
        int ret;
        u16 *ring_data;
 
-       if (!(ring->scan_mask & (1 << ch))) {
+       if (!(test_bit(ch, ring->scan_mask))) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -79,7 +79,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
        command = AD7298_WRITE | st->ext_ref;
 
        for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
-               if (ring->scan_mask & (1 << i))
+               if (test_bit(i, ring->scan_mask))
                        command |= m;
 
        st->tx_buf[0] = cpu_to_be16(command);
index 38095eba0994da4da8c5ccdd1f00d220089ace75..b42a7ace426de681c2edffa34e1f1c9dfcd2ef1a 100644 (file)
@@ -51,7 +51,8 @@ struct ad7793_state {
        u16                             mode;
        u16                             conf;
        u32                             scale_avail[8][2];
-       u32                             available_scan_masks[7];
+       /* Note this uses fact that 8 the mask always fits in a long */
+       unsigned long                   available_scan_masks[7];
        /*
         * DMA (thus cache coherency maintenance) requires the
         * transfer buffers to live in their own cache lines.
@@ -321,7 +322,7 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
        s64 dat64[2];
        u32 *dat32 = (u32 *)dat64;
 
-       if (!(ring->scan_mask & (1 << ch)))
+       if (!(test_bit(ch, ring->scan_mask)))
                return  -EBUSY;
 
        ret = ring->access->read_last(ring, (u8 *) &dat64);
@@ -343,7 +344,8 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev)
        if (!ring->scan_count)
                return -EINVAL;
 
-       channel = __ffs(ring->scan_mask);
+       channel = find_first_bit(ring->scan_mask,
+                                indio_dev->masklength);
 
        d_size = ring->scan_count *
                 indio_dev->channels[0].scan_type.storagebits / 8;
@@ -875,10 +877,12 @@ static int __devinit ad7793_probe(struct spi_device *spi)
        indio_dev->num_channels = 7;
        indio_dev->info = &ad7793_info;
 
-       for (i = 0; i < indio_dev->num_channels; i++)
-               st->available_scan_masks[i] = (1 << i) | (1 <<
-                       indio_dev->channels[indio_dev->num_channels - 1].
-                       scan_index);
+       for (i = 0; i < indio_dev->num_channels; i++) {
+               set_bit(i, &st->available_scan_masks[i]);
+               set_bit(indio_dev->
+                       channels[indio_dev->num_channels - 1].scan_index,
+                       &st->available_scan_masks[i]);
+       }
 
        init_waitqueue_head(&st->wq_data_avail);
 
index 837046c7b894f54db1e11c963db45dd487af2c73..1b7a772934cc1b2b57761bb525d62d84f30ad897 100644 (file)
@@ -83,11 +83,11 @@ enum ad7887_supported_device_ids {
 };
 
 #ifdef CONFIG_IIO_RING_BUFFER
-int ad7887_scan_from_ring(struct ad7887_state *st, long mask);
+int ad7887_scan_from_ring(struct ad7887_state *st, int channum);
 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7887_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_RING_BUFFER */
-static inline int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
+static inline int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
 {
        return 0;
 }
index 6b3daf41e0c69828d5c2495fc34dce9aec1aeea2..36e118cf32e2b95728fe3a0773f6272a92418a4a 100644 (file)
 
 #include "ad7887.h"
 
-int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
+int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
 {
        struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
        int count = 0, ret;
        u16 *ring_data;
 
-       if (!(ring->scan_mask & mask)) {
+       if (!(test_bit(channum, ring->scan_mask))) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -41,7 +41,8 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
                goto error_free_ring_data;
 
        /* for single channel scan the result is stored with zero offset */
-       if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1)))
+       if ((test_bit(1, ring->scan_mask) || test_bit(0, ring->scan_mask)) &&
+           (channum == 1))
                count = 1;
 
        ret = be16_to_cpu(ring_data[count]);
@@ -78,7 +79,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
                indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
                                                            st->d_size);
 
-       switch (ring->scan_mask) {
+       /* We know this is a single long so can 'cheat' */
+       switch (*ring->scan_mask) {
        case (1 << 0):
                st->ring_msg = &st->msg[AD7887_CH0];
                break;
index 0dc9b4c73a33af36ac2ede6e19f7ded3d71111ab..98f06f682b8e4418793b7c8f35a351769d7db0e8 100644 (file)
@@ -124,11 +124,11 @@ struct ad799x_platform_data {
 int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask);
 
 #ifdef CONFIG_AD799X_RING_BUFFER
-int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask);
+int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum);
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad799x_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_AD799X_RING_BUFFER */
-int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
+int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum)
 {
        return -EINVAL;
 }
index 299183c05d434835ee96e62335f0955e6f861d21..cfe4b2caea8c672a5ef6ab978a57ad82be373ad5 100644 (file)
@@ -151,7 +151,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info,
                mutex_lock(&dev_info->mlock);
                if (iio_ring_enabled(dev_info))
                        ret = ad799x_single_channel_from_ring(st,
-                               1 << chan->address);
+                                                             chan->address);
                else
                        ret = ad799x_scan_direct(st, chan->address);
                mutex_unlock(&dev_info->mlock);
index 8f1fc52560f1473caa25a584f04c29074c1d1d88..438e81d190c68ea06ff1d4bea8dee12a931e08a2 100644 (file)
 
 #include "ad799x.h"
 
-int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
+int ad799x_single_channel_from_ring(struct ad799x_state *st, int channum)
 {
        struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
        int count = 0, ret;
        u16 *ring_data;
 
-       if (!(ring->scan_mask & mask)) {
+       if (!(test_bit(channum, ring->scan_mask))) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -44,13 +44,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
        if (ret)
                goto error_free_ring_data;
        /* Need a count of channels prior to this one */
-       mask >>= 1;
-       while (mask) {
-               if (mask & ring->scan_mask)
-                       count++;
-               mask >>= 1;
-       }
-
+       count = bitmap_weight(ring->scan_mask, channum);
        ret = be16_to_cpu(ring_data[count]);
 
 error_free_ring_data:
@@ -77,7 +71,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
         */
 
        if (st->id == ad7997 || st->id == ad7998)
-               ad7997_8_set_scan_mode(st, ring->scan_mask);
+               ad7997_8_set_scan_mode(st, *ring->scan_mask);
 
        st->d_size = ring->scan_count * 2;
 
@@ -121,12 +115,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
        case ad7991:
        case ad7995:
        case ad7999:
-               cmd = st->config | (ring->scan_mask << AD799X_CHANNEL_SHIFT);
+               cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT);
                break;
        case ad7992:
        case ad7993:
        case ad7994:
-               cmd = (ring->scan_mask << AD799X_CHANNEL_SHIFT) |
+               cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) |
                        AD7998_CONV_RES_REG;
                break;
        case ad7997:
index 360bfc5398fc7d7c6d6d3192bf9621769af34f66..cbcb08a2cb50de65774c9f8304c6bb010919c672 100644 (file)
@@ -57,6 +57,7 @@
 #define MAX1363_SCAN_MASK                      0x60
 #define MAX1363_SE_DE_MASK                     0x01
 
+#define MAX1363_MAX_CHANNELS 25
 /**
  * struct max1363_mode - scan mode information
  * @conf:      The corresponding value of the configuration register
@@ -64,7 +65,7 @@
  */
 struct max1363_mode {
        int8_t          conf;
-       long            modemask;
+       DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
 };
 
 /* This must be maintained along side the max1363_mode_table in max1363_core */
@@ -145,13 +146,14 @@ struct max1363_state {
 };
 
 const struct max1363_mode
-*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci);
+*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci);
 
 int max1363_set_scan_mode(struct max1363_state *st);
 
 #ifdef CONFIG_MAX1363_RING_BUFFER
 
-int max1363_single_channel_from_ring(long mask, struct max1363_state *st);
+int max1363_single_channel_from_ring(const long *mask,
+                                    struct max1363_state *st);
 int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void max1363_ring_cleanup(struct iio_dev *indio_dev);
 
index e921efa7196f59f353eacc47f63f703ca5473740..49b2ce22e6edb6b27f57cf080b19646260bd9969 100644 (file)
                .conf = MAX1363_CHANNEL_SEL(_num)                       \
                        | MAX1363_CONFIG_SCAN_SINGLE_1                  \
                        | MAX1363_CONFIG_SE,                            \
-                       .modemask = _mask,                              \
+                       .modemask[0] = _mask,                           \
                        }
 
 #define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {                    \
                .conf = MAX1363_CHANNEL_SEL(_num)                       \
                        | MAX1363_CONFIG_SCAN_TO_CS                     \
                        | MAX1363_CONFIG_SE,                            \
-                       .modemask = _mask,                              \
+                       .modemask[0] = _mask,                           \
                        }
 
 /* note not available for max1363 hence naming */
                .conf = MAX1363_CHANNEL_SEL(_num)                       \
                        | MAX1236_SCAN_MID_TO_CHANNEL                   \
                        | MAX1363_CONFIG_SE,                            \
-                       .modemask = _mask                               \
+                       .modemask[0] = _mask                            \
 }
 
 #define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {                        \
                .conf = MAX1363_CHANNEL_SEL(_nump)                      \
                        | MAX1363_CONFIG_SCAN_SINGLE_1                  \
                        | MAX1363_CONFIG_DE,                            \
-                       .modemask = _mask                               \
+                       .modemask[0] = _mask                            \
                        }
 
 /* Can't think how to automate naming so specify for now */
@@ -72,7 +72,7 @@
                .conf = MAX1363_CHANNEL_SEL(_num)                       \
                        | MAX1363_CONFIG_SCAN_TO_CS                     \
                        | MAX1363_CONFIG_DE,                            \
-                       .modemask = _mask                               \
+                       .modemask[0] = _mask                            \
                        }
 
 /* note only available for max1363 hence naming */
@@ -80,7 +80,7 @@
                .conf = MAX1363_CHANNEL_SEL(_num)                       \
                        | MAX1236_SCAN_MID_TO_CHANNEL                   \
                        | MAX1363_CONFIG_SE,                            \
-                       .modemask = _mask                               \
+                       .modemask[0] = _mask                            \
 }
 
 static const struct max1363_mode max1363_mode_table[] = {
@@ -147,13 +147,15 @@ static const struct max1363_mode max1363_mode_table[] = {
 };
 
 const struct max1363_mode
-*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci)
+*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci)
 {
        int i;
        if (mask)
                for (i = 0; i < ci->num_modes; i++)
-                       if (!((~max1363_mode_table[ci->mode_list[i]].modemask) &
-                             mask))
+                       if (bitmap_subset(mask,
+                                         max1363_mode_table[ci->mode_list[i]].
+                                         modemask,
+                                         MAX1363_MAX_CHANNELS))
                                return &max1363_mode_table[ci->mode_list[i]];
        return NULL;
 }
@@ -187,7 +189,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
        int ret = 0;
        s32 data;
        char rxbuf[2];
-       long mask;
+       const unsigned long *mask;
        struct max1363_state *st = iio_priv(indio_dev);
        struct i2c_client *client = st->client;
 
@@ -644,7 +646,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
        int ret, i = 3, j;
        unsigned long numelements;
        int len;
-       long modemask;
+       const long *modemask;
 
        if (!enabled) {
                /* transition to ring capture is not currently supported */
@@ -672,7 +674,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
                st->configbyte |= max1363_mode_table[d1m0to3m2].conf;
                modemask = max1363_mode_table[d1m0to3m2].modemask;
        }
-       numelements = hweight_long(modemask);
+       numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS);
        len = 3 * numelements + 3;
        tx_buf = kmalloc(len, GFP_KERNEL);
        if (!tx_buf) {
@@ -688,7 +690,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
         * setup to match what we need.
         */
        for (j = 0; j < 8; j++)
-               if (modemask & (1 << j)) {
+               if (test_bit(j, modemask)) {
                        /* Establish the mode is in the scan */
                        if (st->mask_low & (1 << j)) {
                                tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF;
@@ -1281,7 +1283,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
        st->client = client;
 
        indio_dev->available_scan_masks
-               = kzalloc(sizeof(*indio_dev->available_scan_masks)*
+               = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*
                          (st->chip_info->num_modes + 1), GFP_KERNEL);
        if (!indio_dev->available_scan_masks) {
                ret = -ENOMEM;
@@ -1289,9 +1291,10 @@ static int __devinit max1363_probe(struct i2c_client *client,
        }
 
        for (i = 0; i < st->chip_info->num_modes; i++)
-               indio_dev->available_scan_masks[i] =
-                       max1363_mode_table[st->chip_info->mode_list[i]]
-                       .modemask;
+               bitmap_copy(indio_dev->available_scan_masks +
+                           BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i,
+                           max1363_mode_table[st->chip_info->mode_list[i]]
+                           .modemask, MAX1363_MAX_CHANNELS);
        /* Estabilish that the iio_dev is a child of the i2c device */
        indio_dev->dev.parent = &client->dev;
        indio_dev->name = id->name;
index be601e07639db4983129c8523364676c1a9354a0..abe9e03f36e33ca9c4193c77d3c32d0840f054a6 100644 (file)
 
 #include "max1363.h"
 
-int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
+int max1363_single_channel_from_ring(const long *mask, struct max1363_state *st)
 {
        struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
-       int count = 0, ret;
+       int count = 0, ret, index;
        u8 *ring_data;
-       if (!(st->current_mode->modemask & mask)) {
+       index = find_first_bit(mask, MAX1363_MAX_CHANNELS);
+
+       if (!(test_bit(index, st->current_mode->modemask))) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -41,12 +43,8 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
        if (ret)
                goto error_free_ring_data;
        /* Need a count of channels prior to this one */
-       mask >>= 1;
-       while (mask) {
-               if (mask & st->current_mode->modemask)
-                       count++;
-               mask >>= 1;
-       }
+
+       count = bitmap_weight(mask, index - 1);
        if (st->chip_info->bits != 8)
                ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8)
                        + (int)(ring_data[count*2 + 1]);
@@ -85,7 +83,8 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
 
        max1363_set_scan_mode(st);
 
-       numvals = hweight_long(st->current_mode->modemask);
+       numvals = bitmap_weight(st->current_mode->modemask,
+                               indio_dev->masklength);
        if (ring->access->set_bytes_per_datum) {
                if (ring->scan_timestamp)
                        d_size += sizeof(s64);
@@ -110,7 +109,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
        __u8 *rxbuf;
        int b_sent;
        size_t d_size;
-       unsigned long numvals = hweight_long(st->current_mode->modemask);
+       unsigned long numvals = bitmap_weight(st->current_mode->modemask,
+                                             MAX1363_MAX_CHANNELS);
 
        /* Ensure the timestamp is 8 byte aligned */
        if (st->chip_info->bits != 8)
index daaea94a5e6d26ec5e93425f7991794b593a4fe3..635fa73e4623f5edff9640dfd1837e2941caa315 100644 (file)
@@ -272,6 +272,8 @@ struct iio_info {
  * @mlock:             [INTERN] lock used to prevent simultaneous device state
  *                     changes
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
+ * @masklength:                [INTERN] the length of the mask established from
+ *                     channels
  * @trig:              [INTERN] current device trigger (ring buffer modes)
  * @pollfunc:          [DRIVER] function run on trigger being received
  * @channels:          [DRIVER] channel specification structure table
@@ -294,7 +296,8 @@ struct iio_dev {
        struct iio_ring_buffer          *ring;
        struct mutex                    mlock;
 
-       u32                             *available_scan_masks;
+       unsigned long                   *available_scan_masks;
+       unsigned                        masklength;
        struct iio_trigger              *trig;
        struct iio_poll_func            *pollfunc;
 
index 1c1cd8eac9de4aa5bcc8b5f8fab70b8a4ad9c4d1..e199bbed75e953bdc20da925715b0d8d5c8137c9 100644 (file)
@@ -640,7 +640,7 @@ static void ad5933_work(struct work_struct *work)
 
        if (status & AD5933_STAT_DATA_VALID) {
                ad5933_i2c_read(st->client,
-                               (ring->scan_mask & (1 << 0)) ?
+                               test_bit(1, ring->scan_mask) ?
                                AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
                                ring->scan_count * 2, (u8 *)buf);
 
index d2506b1b2db0e8352eddd3276b2102acd19208b9..af25697dab987073062d2b0748b6d66e55ee8c4e 100644 (file)
@@ -85,7 +85,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx)
                return -ENOMEM;
 
        for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
-               if (indio_dev->ring->scan_mask & (1 << i)) {
+               if (test_bit(i, indio_dev->ring->scan_mask)) {
                        xfers[j].tx_buf = &read_all_tx_array[i];
                        xfers[j].bits_per_word = 16;
                        xfers[j].len = 2;
@@ -117,7 +117,8 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
        int i = 0, j, ret = 0;
        s16 *data;
        size_t datasize = ring->access->get_bytes_per_datum(ring);
-       unsigned long mask = ring->scan_mask;
+       /* Asumption that long is enough for maximum channels */
+       unsigned long mask = *ring->scan_mask;
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
index 23967d491925123c59ae4d6bc176ebeeb0ddd6cf..6f14c0d848677ce21edb3ba67a6200df9ac3652d 100644 (file)
@@ -132,9 +132,7 @@ static ssize_t iio_scan_el_show(struct device *dev,
 
 static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
 {
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-       ring->scan_mask &= ~(1 << bit);
+       clear_bit(bit, ring->scan_mask);
        ring->scan_count--;
        return 0;
 }
@@ -323,11 +321,27 @@ int iio_ring_buffer_register(struct iio_dev *indio_dev,
        if (channels) {
                /* new magic */
                for (i = 0; i < num_channels; i++) {
+                       /* Establish necessary mask length */
+                       if (channels[i].scan_index >
+                           (int)indio_dev->masklength - 1)
+                               indio_dev->masklength
+                                       = indio_dev->channels[i].scan_index + 1;
+
                        ret = iio_ring_add_channel_sysfs(indio_dev,
                                                         &channels[i]);
                        if (ret < 0)
                                goto error_cleanup_group;
                }
+               if (indio_dev->masklength && ring->scan_mask == NULL) {
+                       ring->scan_mask
+                               = kzalloc(sizeof(*ring->scan_mask)*
+                                         BITS_TO_LONGS(indio_dev->masklength),
+                                         GFP_KERNEL);
+                       if (ring->scan_mask == NULL) {
+                               ret = -ENOMEM;
+                               goto error_cleanup_group;
+                       }
+               }
        }
 
        return 0;
@@ -343,6 +357,7 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
 
 void iio_ring_buffer_unregister(struct iio_dev *indio_dev)
 {
+       kfree(indio_dev->ring->scan_mask);
        if (indio_dev->ring->attrs)
                sysfs_remove_group(&indio_dev->dev.kobj,
                                   indio_dev->ring->attrs);
@@ -539,3 +554,85 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev)
        return 0;
 }
 EXPORT_SYMBOL(iio_sw_ring_preenable);
+
+
+/* note NULL used as error indicator as it doesn't make sense. */
+static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
+                                         unsigned int masklength,
+                                         unsigned long *mask)
+{
+       if (bitmap_empty(mask, masklength))
+               return NULL;
+       while (*av_masks) {
+               if (bitmap_subset(mask, av_masks, masklength))
+                       return av_masks;
+               av_masks += BITS_TO_LONGS(masklength);
+       }
+       return NULL;
+}
+
+/**
+ * iio_scan_mask_set() - set particular bit in the scan mask
+ * @ring: the ring buffer whose scan mask we are interested in
+ * @bit: the bit to be set.
+ **/
+int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
+{
+       struct iio_dev *dev_info = ring->indio_dev;
+       unsigned long *mask;
+       unsigned long *trialmask;
+
+       trialmask = kmalloc(sizeof(*trialmask)*
+                           BITS_TO_LONGS(dev_info->masklength),
+                           GFP_KERNEL);
+
+       if (trialmask == NULL)
+               return -ENOMEM;
+       if (!dev_info->masklength) {
+               WARN_ON("trying to set scan mask prior to registering ring\n");
+               kfree(trialmask);
+               return -EINVAL;
+       }
+       bitmap_copy(trialmask, ring->scan_mask, dev_info->masklength);
+       set_bit(bit, trialmask);
+
+       if (dev_info->available_scan_masks) {
+               mask = iio_scan_mask_match(dev_info->available_scan_masks,
+                                          dev_info->masklength,
+                                          trialmask);
+               if (!mask) {
+                       kfree(trialmask);
+                       return -EINVAL;
+               }
+       }
+       bitmap_copy(ring->scan_mask, trialmask, dev_info->masklength);
+       ring->scan_count++;
+
+       kfree(trialmask);
+
+       return 0;
+};
+EXPORT_SYMBOL_GPL(iio_scan_mask_set);
+
+int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
+{
+       struct iio_dev *dev_info = ring->indio_dev;
+       long *mask;
+
+       if (bit > dev_info->masklength)
+               return -EINVAL;
+
+       if (!ring->scan_mask)
+               return 0;
+       if (dev_info->available_scan_masks)
+               mask = iio_scan_mask_match(dev_info->available_scan_masks,
+                                          dev_info->masklength,
+                                          ring->scan_mask);
+       else
+               mask = ring->scan_mask;
+       if (!mask)
+               return 0;
+
+       return test_bit(bit, mask);
+};
+EXPORT_SYMBOL_GPL(iio_scan_mask_query);
index 4d73e1a38815bd375c3f3a231f1ce5eb98bcc70d..20a2bcace7f41c673eb4b3220f7e53c3aa6fa7f8 100644 (file)
@@ -122,7 +122,7 @@ struct ade7758_state {
        u8                      *tx;
        u8                      *rx;
        struct mutex            buf_lock;
-       u32                     available_scan_masks[AD7758_NUM_WAVESRC];
+       unsigned long           available_scan_masks[AD7758_NUM_WAVESRC];
        struct iio_chan_spec    *ade7758_ring_channels;
        struct spi_transfer     ring_xfer[4];
        struct spi_message      ring_msg;
index 77bd2761f272f5ba1325b8e3351cee503ecdd1e5..ce513bda0216134df9704ed6fd3480cca84bccf8 100644 (file)
@@ -767,7 +767,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
        indio_dev->modes = INDIO_DIRECT_MODE;
 
        for (i = 0; i < AD7758_NUM_WAVESRC; i++)
-               st->available_scan_masks[i] = 1 << i;
+               set_bit(i, &st->available_scan_masks[i]);
 
        indio_dev->available_scan_masks = st->available_scan_masks;
 
index 5e740e386162cb9ab75dd3931a67338dbc8b7297..9934f508ded27d46ef48aab7cf275c782e59a964 100644 (file)
@@ -98,7 +98,7 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
        if (!ring->scan_count)
                return -EINVAL;
 
-       channel = __ffs(ring->scan_mask);
+       channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
 
        d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
 
index 25aacf3b89331f67f42bee8e324dcc7aa3e81432..7a47f62755692c18d8639508ba4c898509c6789a 100644 (file)
@@ -104,7 +104,7 @@ struct iio_ring_buffer {
        int                                     bpe;
        struct attribute_group                  *scan_el_attrs;
        int                                     scan_count;
-       unsigned long                           scan_mask;
+       long                                    *scan_mask;
        bool                                    scan_timestamp;
        const struct iio_ring_access_funcs      *access;
        const struct iio_ring_setup_ops         *setup_ops;
@@ -124,6 +124,8 @@ struct iio_ring_buffer {
 void iio_ring_buffer_init(struct iio_ring_buffer *ring,
                          struct iio_dev *dev_info);
 
+void iio_ring_buffer_deinit(struct iio_ring_buffer *ring);
+
 /**
  * __iio_update_ring_buffer() - update common elements of ring buffers
  * @ring:              ring buffer that is the event source
@@ -137,70 +139,14 @@ static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
        ring->length = length;
 }
 
-/*
- * These are mainly provided to allow for a change of implementation if a device
- * has a large number of scan elements
- */
-#define IIO_MAX_SCAN_LENGTH 31
-
-/* note 0 used as error indicator as it doesn't make sense. */
-static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
-{
-       while (*av_masks) {
-               if (!(~*av_masks & mask))
-                       return *av_masks;
-               av_masks++;
-       }
-       return 0;
-}
-
-static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
-{
-       struct iio_dev *dev_info = ring->indio_dev;
-       u32 mask;
-
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-
-       if (!ring->scan_mask)
-               return 0;
-
-       if (dev_info->available_scan_masks)
-               mask = iio_scan_mask_match(dev_info->available_scan_masks,
-                                       ring->scan_mask);
-       else
-               mask = ring->scan_mask;
-
-       if (!mask)
-               return -EINVAL;
-
-       return !!(mask & (1 << bit));
-};
+int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit);
 
 /**
  * iio_scan_mask_set() - set particular bit in the scan mask
  * @ring: the ring buffer whose scan mask we are interested in
  * @bit: the bit to be set.
  **/
-static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
-{
-       struct iio_dev *dev_info = ring->indio_dev;
-       u32 mask;
-       u32 trialmask = ring->scan_mask | (1 << bit);
-
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-       if (dev_info->available_scan_masks) {
-               mask = iio_scan_mask_match(dev_info->available_scan_masks,
-                                       trialmask);
-               if (!mask)
-                       return -EINVAL;
-       }
-       ring->scan_mask = trialmask;
-       ring->scan_count++;
-
-       return 0;
-};
+int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit);
 
 #define to_iio_ring_buffer(d)                          \
        container_of(d, struct iio_ring_buffer, dev)