staging: iio move scan_elements into ring buffer
authorManuel Stahl <manuel.stahl@iis.fraunhofer.de>
Tue, 31 Aug 2010 09:32:52 +0000 (11:32 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 31 Aug 2010 18:42:02 +0000 (11:42 -0700)
tested with sca3000, adis16400

Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
15 files changed:
drivers/staging/iio/accel/adis16209_ring.c
drivers/staging/iio/accel/adis16240_ring.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/adc/max1363_ring.c
drivers/staging/iio/gyro/adis16260_ring.c
drivers/staging/iio/iio.h
drivers/staging/iio/imu/adis16300_ring.c
drivers/staging/iio/imu/adis16350_ring.c
drivers/staging/iio/imu/adis16400_ring.c
drivers/staging/iio/industrialio-core.c
drivers/staging/iio/industrialio-ring.c
drivers/staging/iio/ring_generic.h
drivers/staging/iio/ring_sw.c

index d40b95f..120bf91 100644 (file)
@@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16209_state *st
                = container_of(work_s, struct adis16209_state,
                               work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                           (u8 *)data,
-                                           st->last_timestamp);
+       ring->access.store_to(ring,
+                             (u8 *)data,
+                             st->last_timestamp);
 
        iio_trigger_notify_done(st->indio_dev->trig);
        kfree(data);
@@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
        struct adis16209_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16209_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -182,11 +169,23 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16209_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_rot.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp.number);
+       iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
+       iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index 462d452..581d0e5 100644 (file)
@@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16240_state *st
                = container_of(work_s, struct adis16240_state,
                                work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+       ring->access.store_to(ring,
                        (u8 *)data,
                        st->last_timestamp);
 
@@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
        struct adis16240_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16240_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -172,11 +161,21 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16240_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp.number);
+       iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index 9ad04f0..a68a381 100644 (file)
@@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
        int ret, len = 0, i = 0;
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        struct iio_dev *dev_info = dev_get_drvdata(dev);
+       struct iio_ring_buffer *ring = dev_info->ring;
+       struct attribute_group *scan_el_attrs = ring->scan_el_attrs;
        s16 *data;
 
-       while (dev_info->scan_el_attrs->attrs[i]) {
+       while (scan_el_attrs->attrs[i]) {
                el = to_iio_scan_el((struct device_attribute *)
-                                   (dev_info->scan_el_attrs->attrs[i]));
+                                   (scan_el_attrs->attrs[i]));
                /* label is in fact the address */
                if (el->label == this_attr->address)
                        break;
                i++;
        }
-       if (!dev_info->scan_el_attrs->attrs[i]) {
+       if (!scan_el_attrs->attrs[i]) {
                ret = -EINVAL;
                goto error_ret;
        }
        /* If this element is in the scan mask */
-       ret = iio_scan_mask_query(dev_info, el->number);
+       ret = iio_scan_mask_query(ring, el->number);
        if (ret < 0)
                goto error_ret;
        if (ret) {
-               data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
+               data = kmalloc(ring->access.get_bytes_per_datum(ring),
                               GFP_KERNEL);
                if (data == NULL)
                        return -ENOMEM;
-               ret = dev_info->ring->access.read_last(dev_info->ring,
-                                                     (u8 *)data);
+               ret = ring->access.read_last(ring,
+                                       (u8 *)data);
                if (ret)
                        goto error_free_data;
        } else {
                ret = -EINVAL;
                goto error_ret;
        }
-       len = iio_scan_mask_count_to_right(dev_info, el->number);
+       len = iio_scan_mask_count_to_right(ring, el->number);
        if (len < 0) {
                ret = len;
                goto error_free_data;
@@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
  **/
 static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
 {
+       struct iio_ring_buffer *ring = st->help.indio_dev->ring;
        struct spi_transfer *xfers;
        struct spi_message msg;
        int ret, i, j = 0;
 
-       xfers = kzalloc((st->help.indio_dev->scan_count) * 2
+       xfers = kzalloc((ring->scan_count) * 2
                        * sizeof(*xfers), GFP_KERNEL);
        if (!xfers)
                return -ENOMEM;
@@ -223,7 +226,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
        mutex_lock(&st->buf_lock);
 
        for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
-               if (st->help.indio_dev->scan_mask & (1 << i)) {
+               if (ring->scan_mask & (1 << i)) {
                        /* lower byte */
                        xfers[j].tx_buf = st->tx + 2*j;
                        st->tx[2*j] = read_all_tx_array[i*4];
@@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
         * values in alternate bytes
         */
        spi_message_init(&msg);
-       for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
+       for (j = 0; j < ring->scan_count * 2; j++)
                spi_message_add_tail(&xfers[j], &msg);
 
        ret = spi_sync(st->us, &msg);
@@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
        u8 *rx_array ;
        s16 *data = (s16 *)buf;
 
-       rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
+       rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
        if (rx_array == NULL)
                return -ENOMEM;
        ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
        if (ret < 0)
                return ret;
-       for (i = 0; i < h->indio_dev->scan_count; i++)
+       for (i = 0; i < h->indio_dev->ring->scan_count; i++)
                data[i] = combine_8_to_16(rx_array[i*4+1],
                                        rx_array[i*4+3]);
        kfree(rx_array);
@@ -481,14 +484,7 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
        struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
        struct iio_ring_buffer *ring;
        INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
-       /* Set default scan mode */
        h->get_ring_element = &lis3l02dq_get_ring_element;
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring)
@@ -498,11 +494,18 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &lis3l02dq_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;;
index eff5b9a..6d19d15 100644 (file)
@@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
 
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
-       indio_dev->scan_el_attrs = &sca3000_scan_el_group;
        indio_dev->ring = sca3000_rb_allocate(indio_dev);
        if (indio_dev->ring == NULL)
                return -ENOMEM;
        indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
 
+       indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
        indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
        indio_dev->ring->access.get_length = &sca3000_ring_get_length;
        indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
index 6435e50..1dc428f 100644 (file)
@@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
        st->indio_dev->attrs = st->chip_info->dev_attrs;
 
        /* Todo: this shouldn't be here. */
-       st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
        st->indio_dev->dev_data = (void *)(st);
        st->indio_dev->driver_module = THIS_MODULE;
        st->indio_dev->modes = INDIO_DIRECT_MODE;
index edac0ba..1d6ce54 100644 (file)
@@ -30,6 +30,7 @@
 /* Todo: test this */
 int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 {
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
        unsigned long numvals;
        int count = 0, ret;
        u8 *ring_data;
@@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
                ret = -ENOMEM;
                goto error_ret;
        }
-       ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
-                                               ring_data);
+       ret = ring->access.read_last(ring, ring_data);
        if (ret)
                goto error_free_ring_data;
        /* Need a count of channels prior to this one */
@@ -77,6 +77,7 @@ error_ret:
 static int max1363_ring_preenable(struct iio_dev *indio_dev)
 {
        struct max1363_state *st = indio_dev->dev_data;
+       struct iio_ring_buffer *ring = indio_dev->ring;
        size_t d_size;
        unsigned long numvals;
 
@@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
         * Need to figure out the current mode based upon the requested
         * scan mask in iio_dev
         */
-       st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
+       st->current_mode = max1363_match_mode(ring->scan_mask,
                                        st->chip_info);
        if (!st->current_mode)
                return -EINVAL;
@@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
        max1363_set_scan_mode(st);
 
        numvals = hweight_long(st->current_mode->modemask);
-       if (indio_dev->ring->access.set_bytes_per_datum) {
+       if (ring->access.set_bytes_per_datum) {
                if (st->chip_info->bits != 8)
                        d_size = numvals*2 + sizeof(s64);
                else
                        d_size = numvals + sizeof(s64);
                if (d_size % 8)
                        d_size += 8 - (d_size % 8);
-               indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
+               ring->access.set_bytes_per_datum(ring, d_size);
        }
 
        return 0;
@@ -135,7 +136,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
        struct max1363_state *st = container_of(work_s, struct max1363_state,
                                                  poll_work);
        struct iio_dev *indio_dev = st->indio_dev;
-       struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
+       struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
        s64 time_ns;
        __u8 *rxbuf;
        int b_sent;
@@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
 
        memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
 
-       indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
+       indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
 done:
        kfree(rxbuf);
        atomic_dec(&st->protect_ring);
@@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
                goto error_ret;
        }
        /* Effectively select the ring buffer implementation */
-       iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
+       iio_ring_sw_register_funcs(&indio_dev->ring->access);
        ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
        if (ret)
                goto error_deallocate_sw_rb;
 
        /* Ring buffer functions - here trigger setup related */
+       indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
        indio_dev->ring->postenable = &iio_triggered_ring_postenable;
        indio_dev->ring->preenable = &max1363_ring_preenable;
        indio_dev->ring->predisable = &iio_triggered_ring_predisable;
index 055d5e8..0334860 100644 (file)
@@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16260_state *st
                = container_of(work_s, struct adis16260_state,
                                work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+       ring->access.store_to(ring,
                        (u8 *)data,
                        st->last_timestamp);
 
@@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
        struct adis16260_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16260_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -174,11 +164,20 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16260_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro.number);
+       iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp.number);
+       iio_scan_mask_set(ring, iio_scan_el_angl.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index 9d0ca12..3072c45 100644 (file)
@@ -90,12 +90,7 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
  * @ring:              [DRIVER] any ring buffer present
  * @mlock:             [INTERN] lock used to prevent simultaneous device state
  *                     changes
- * @scan_el_attrs:     [DRIVER] control of scan elements if that scan mode
- *                     control method is used
- * @scan_count:        [INTERN] the number of elements in the current scan mode
- * @scan_mask:         [INTERN] bitmask used in masking scan mode elements
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
- * @scan_timestamp:    [INTERN] does the scan mode include a timestamp
  * @trig:              [INTERN] current device trigger (ring buffer modes)
  * @pollfunc:          [DRIVER] function run on trigger being recieved
  **/
@@ -118,104 +113,11 @@ struct iio_dev {
        struct iio_ring_buffer          *ring;
        struct mutex                    mlock;
 
-       struct attribute_group          *scan_el_attrs;
-       int                             scan_count;
-
-       u32                             scan_mask;
        u32                             *available_scan_masks;
-       bool                            scan_timestamp;
        struct iio_trigger              *trig;
        struct iio_poll_func            *pollfunc;
 };
 
-/*
- * 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_dev *dev_info, int bit)
-{
-       u32 mask;
-
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-
-       if (!dev_info->scan_mask)
-               return 0;
-
-       if (dev_info->available_scan_masks)
-               mask = iio_scan_mask_match(dev_info->available_scan_masks,
-                                       dev_info->scan_mask);
-       else
-               mask = dev_info->scan_mask;
-
-       if (!mask)
-               return -EINVAL;
-
-       return !!(mask & (1 << bit));
-};
-
-static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
-{
-       u32 mask;
-       u32 trialmask = dev_info->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;
-       }
-       dev_info->scan_mask = trialmask;
-       dev_info->scan_count++;
-
-       return 0;
-};
-
-static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
-{
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-       dev_info->scan_mask &= ~(1 << bit);
-       dev_info->scan_count--;
-       return 0;
-};
-
-/**
- * iio_scan_mask_count_to_right() - how many scan elements occur before here
- * @dev_info: the iio_device whose scan mode we are querying
- * @bit: which number scan element is this
- **/
-static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
-                                               int bit)
-{
-       int count = 0;
-       int mask = (1 << bit);
-       if (bit > IIO_MAX_SCAN_LENGTH)
-               return -EINVAL;
-       while (mask) {
-               mask >>= 1;
-               if (mask & dev_info->scan_mask)
-                       count++;
-       }
-
-       return count;
-}
-
 /**
  * iio_device_register() - register a device with the IIO subsystem
  * @dev_info:          Device structure filled by the device driver
index 854183c..742cad6 100644 (file)
@@ -134,11 +134,11 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16300_state *st
                = container_of(work_s, struct adis16300_state,
                               work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                           (u8 *)data,
-                                           st->last_timestamp);
+       ring->access.store_to(ring,
+                       (u8 *)data,
+                       st->last_timestamp);
 
        iio_trigger_notify_done(st->indio_dev->trig);
        kfree(data);
@@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
        struct adis16300_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16300_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -202,11 +188,24 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16300_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp.number);
+       iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
+       iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index 9620cbe..a0b80e4 100644 (file)
@@ -134,11 +134,11 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16350_state *st
                = container_of(work_s, struct adis16350_state,
                               work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                           (u8 *)data,
-                                           st->last_timestamp);
+       ring->access.store_to(ring,
+                       (u8 *)data,
+                       st->last_timestamp);
 
        iio_trigger_notify_done(st->indio_dev->trig);
        kfree(data);
@@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
        struct adis16350_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16350_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -204,11 +188,26 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16350_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index c8e2316..667f77b 100644 (file)
@@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
        struct adis16400_state *st
                = container_of(work_s, struct adis16400_state,
                               work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
 
        int i = 0;
        s16 *data;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
 
        data = kmalloc(datasize , GFP_KERNEL);
        if (data == NULL) {
@@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-                       for (; i < st->indio_dev->scan_count; i++)
+                       for (; i < ring->scan_count; i++)
                                data[i] = be16_to_cpup(
                                        (__be16 *)&(st->rx[i*2]));
 
        /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
 
-       st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                           (u8 *)data,
-                                           st->last_timestamp);
+       ring->access.store_to(ring,
+                       (u8 *) data,
+                       st->last_timestamp);
 
        iio_trigger_notify_done(st->indio_dev->trig);
        kfree(data);
@@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
        struct adis16400_state *st = indio_dev->dev_data;
        struct iio_ring_buffer *ring;
        INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
-       /* Set default scan mode */
-
-       iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
-       iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
-       indio_dev->scan_timestamp = true;
-
-       indio_dev->scan_el_attrs = &adis16400_scan_el_group;
 
        ring = iio_sw_rb_allocate(indio_dev);
        if (!ring) {
@@ -214,11 +197,27 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&ring->access);
        ring->bpe = 2;
+       ring->scan_el_attrs = &adis16400_scan_el_group;
+       ring->scan_timestamp = true;
        ring->preenable = &iio_sw_ring_preenable;
        ring->postenable = &iio_triggered_ring_postenable;
        ring->predisable = &iio_triggered_ring_predisable;
        ring->owner = THIS_MODULE;
 
+       /* Set default scan mode */
+       iio_scan_mask_set(ring, iio_scan_el_supply.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_magn_x.number);
+       iio_scan_mask_set(ring, iio_scan_el_magn_y.number);
+       iio_scan_mask_set(ring, iio_scan_el_magn_z.number);
+       iio_scan_mask_set(ring, iio_scan_el_temp.number);
+       iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
+
        ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
        if (ret)
                goto error_iio_sw_rb_free;
index dd4d87a..5c0e56a 100644 (file)
@@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
                goto error_ret;
        }
 
-       if (dev_info->scan_el_attrs) {
-               ret = sysfs_create_group(&dev_info->dev.kobj,
-                                        dev_info->scan_el_attrs);
-               if (ret)
-                       dev_err(&dev_info->dev,
-                               "Failed to add sysfs scan els\n");
-       }
-
 error_ret:
        return ret;
 }
 
 static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
-       if (dev_info->scan_el_attrs)
-               sysfs_remove_group(&dev_info->dev.kobj,
-                                  dev_info->scan_el_attrs);
-
        sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
index 610c2b6..f3c87ed 100644 (file)
@@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
        if (ret)
                goto error_free_ring_buffer_event_chrdev;
 
+       if (ring->scan_el_attrs) {
+               ret = sysfs_create_group(&ring->dev.kobj,
+                                        ring->scan_el_attrs);
+               if (ret) {
+                       dev_err(&ring->dev,
+                               "Failed to add sysfs scan elements\n");
+                       goto error_free_ring_buffer_event_chrdev;
+               }
+       }
+
        return ret;
 error_free_ring_buffer_event_chrdev:
        __iio_free_ring_buffer_event_chrdev(ring);
@@ -291,6 +301,10 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
 
 void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
+       if (ring->scan_el_attrs)
+               sysfs_remove_group(&ring->dev.kobj,
+                                  ring->scan_el_attrs);
+
        __iio_free_ring_buffer_access_chrdev(ring);
        __iio_free_ring_buffer_event_chrdev(ring);
        device_del(&ring->dev);
@@ -465,10 +479,10 @@ ssize_t iio_scan_el_show(struct device *dev,
                         char *buf)
 {
        int ret;
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct iio_ring_buffer *ring = dev_get_drvdata(dev);
        struct iio_scan_el *this_el = to_iio_scan_el(attr);
 
-       ret = iio_scan_mask_query(indio_dev, this_el->number);
+       ret = iio_scan_mask_query(ring, this_el->number);
        if (ret < 0)
                return ret;
        return sprintf(buf, "%d\n", ret);
@@ -482,7 +496,8 @@ ssize_t iio_scan_el_store(struct device *dev,
 {
        int ret = 0;
        bool state;
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+       struct iio_dev *indio_dev = ring->indio_dev;
        struct iio_scan_el *this_el = to_iio_scan_el(attr);
 
        state = !(buf[0] == '0');
@@ -491,19 +506,17 @@ ssize_t iio_scan_el_store(struct device *dev,
                ret = -EBUSY;
                goto error_ret;
        }
-       ret = iio_scan_mask_query(indio_dev, this_el->number);
+       ret = iio_scan_mask_query(ring, this_el->number);
        if (ret < 0)
                goto error_ret;
        if (!state && ret) {
-               ret = iio_scan_mask_clear(indio_dev, this_el->number);
+               ret = iio_scan_mask_clear(ring, this_el->number);
                if (ret)
                        goto error_ret;
-               indio_dev->scan_count--;
        } else if (state && !ret) {
-               ret = iio_scan_mask_set(indio_dev, this_el->number);
+               ret = iio_scan_mask_set(ring, this_el->number);
                if (ret)
                        goto error_ret;
-               indio_dev->scan_count++;
        }
        if (this_el->set_state)
                ret = this_el->set_state(this_el, indio_dev, state);
@@ -519,8 +532,8 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
                            struct device_attribute *attr,
                            char *buf)
 {
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
+       struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n", ring->scan_timestamp);
 }
 EXPORT_SYMBOL(iio_scan_el_ts_show);
 
@@ -530,7 +543,8 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
                             size_t len)
 {
        int ret = 0;
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+       struct iio_dev *indio_dev = ring->indio_dev;
        bool state;
        state = !(buf[0] == '0');
        mutex_lock(&indio_dev->mlock);
@@ -538,7 +552,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
                ret = -EBUSY;
                goto error_ret;
        }
-       indio_dev->scan_timestamp = state;
+       ring->scan_timestamp = state;
 error_ret:
        mutex_unlock(&indio_dev->mlock);
 
index ac017b1..6124353 100644 (file)
@@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
  * @bytes_per_datum    [DEVICE] size of individual datum including timestamp
  * @bpe:               [DEVICE] size of individual channel value
  * @loopcount:         [INTERN] number of times the ring has looped
+ * @scan_el_attrs:     [DRIVER] control of scan elements if that scan mode
+ *                     control method is used
+ * @scan_count:        [INTERN] the number of elements in the current scan mode
+ * @scan_mask:         [INTERN] bitmask used in masking scan mode elements
+ * @scan_timestamp:    [INTERN] does the scan mode include a timestamp
  * @access_handler:    [INTERN] chrdev access handling
  * @ev_int:            [INTERN] chrdev interface for the event chrdev
  * @shared_ev_pointer: [INTERN] the shared event pointer to allow escalation of
@@ -124,6 +129,10 @@ struct iio_ring_buffer {
        int                             bytes_per_datum;
        int                             bpe;
        int                             loopcount;
+       struct attribute_group          *scan_el_attrs;
+       int                             scan_count;
+       u32                             scan_mask;
+       bool                            scan_timestamp;
        struct iio_handler              access_handler;
        struct iio_event_interface      ev_int;
        struct iio_shared_ev_pointer    shared_ev_pointer;
@@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
                                   iio_scan_el_ts_store),       \
        }
 
+/*
+ * 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));
+};
+
+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;
+};
+
+static inline 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);
+       ring->scan_count--;
+       return 0;
+};
+
+/**
+ * iio_scan_mask_count_to_right() - how many scan elements occur before here
+ * @dev_info: the iio_device whose scan mode we are querying
+ * @bit: which number scan element is this
+ **/
+static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
+                                               int bit)
+{
+       int count = 0;
+       int mask = (1 << bit);
+       if (bit > IIO_MAX_SCAN_LENGTH)
+               return -EINVAL;
+       while (mask) {
+               mask >>= 1;
+               if (mask & ring->scan_mask)
+                       count++;
+       }
+
+       return count;
+}
+
+
 static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
 {
        put_device(&ring->dev);
index 99efb6b..52624ac 100644 (file)
@@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
 
 int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 {
+       struct iio_ring_buffer *ring = indio_dev->ring;
        size_t size;
        dev_dbg(&indio_dev->dev, "%s\n", __func__);
        /* Check if there are any scan elements enabled, if not fail*/
-       if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
+       if (!(ring->scan_count || ring->scan_timestamp))
                return -EINVAL;
-       if (indio_dev->scan_timestamp)
-               if (indio_dev->scan_count)
+       if (ring->scan_timestamp)
+               if (ring->scan_count)
                        /* Timestamp (aligned to s64) and data */
-                       size = (((indio_dev->scan_count * indio_dev->ring->bpe)
+                       size = (((ring->scan_count * ring->bpe)
                                        + sizeof(s64) - 1)
                                & ~(sizeof(s64) - 1))
                                + sizeof(s64);
                else /* Timestamp only  */
                        size = sizeof(s64);
        else /* Data only */
-               size = indio_dev->scan_count * indio_dev->ring->bpe;
-       indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
+               size = ring->scan_count * ring->bpe;
+       ring->access.set_bytes_per_datum(ring, size);
 
        return 0;
 }
@@ -462,9 +463,9 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
        struct iio_sw_ring_helper_state *st
                = container_of(work_s, struct iio_sw_ring_helper_state,
                        work_trigger_to_ring);
+       struct iio_ring_buffer *ring = st->indio_dev->ring;
        int len = 0;
-       size_t datasize = st->indio_dev
-               ->ring->access.get_bytes_per_datum(st->indio_dev->ring);
+       size_t datasize = ring->access.get_bytes_per_datum(ring);
        char *data = kmalloc(datasize, GFP_KERNEL);
 
        if (data == NULL) {
@@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
                return;
        }
 
-       if (st->indio_dev->scan_count)
+       if (ring->scan_count)
                len = st->get_ring_element(st, data);
 
          /* Guaranteed to be aligned with 8 byte boundary */
-       if (st->indio_dev->scan_timestamp)
+       if (ring->scan_timestamp)
                *(s64 *)(((phys_addr_t)data + len
                                + sizeof(s64) - 1) & ~(sizeof(s64) - 1))
                        = st->last_timestamp;
-         st->indio_dev->ring->access.store_to(st->indio_dev->ring,
-                                       (u8 *)data,
+       ring->access.store_to(ring,
+                       (u8 *)data,
                        st->last_timestamp);
 
        iio_trigger_notify_done(st->indio_dev->trig);