diff options
author | Manuel Stahl <manuel.stahl@iis.fraunhofer.de> | 2010-08-31 11:32:52 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-31 11:42:02 -0700 |
commit | bf32963cbeb5d34fa32a4c1eeed1163ab1b4501c (patch) | |
tree | 221c5e12d26142d6b8b5a3cfff844c9ed9ad3899 /drivers | |
parent | 07e6229e42e4d679cdbaada8f7966491c69710e7 (diff) |
staging: iio move scan_elements into ring buffer
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/iio/accel/adis16209_ring.c | 41 | ||||
-rw-r--r-- | drivers/staging/iio/accel/adis16240_ring.c | 33 | ||||
-rw-r--r-- | drivers/staging/iio/accel/lis3l02dq_ring.c | 43 | ||||
-rw-r--r-- | drivers/staging/iio/accel/sca3000_ring.c | 2 | ||||
-rw-r--r-- | drivers/staging/iio/adc/max1363_core.c | 1 | ||||
-rw-r--r-- | drivers/staging/iio/adc/max1363_ring.c | 18 | ||||
-rw-r--r-- | drivers/staging/iio/gyro/adis16260_ring.c | 31 | ||||
-rw-r--r-- | drivers/staging/iio/iio.h | 98 | ||||
-rw-r--r-- | drivers/staging/iio/imu/adis16300_ring.c | 43 | ||||
-rw-r--r-- | drivers/staging/iio/imu/adis16350_ring.c | 47 | ||||
-rw-r--r-- | drivers/staging/iio/imu/adis16400_ring.c | 49 | ||||
-rw-r--r-- | drivers/staging/iio/industrialio-core.c | 12 | ||||
-rw-r--r-- | drivers/staging/iio/industrialio-ring.c | 38 | ||||
-rw-r--r-- | drivers/staging/iio/ring_generic.h | 100 | ||||
-rw-r--r-- | drivers/staging/iio/ring_sw.c | 25 |
15 files changed, 292 insertions, 289 deletions
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index d40b95f19232..120bf91e0aca 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -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; diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 462d4520ffc3..581d0e500489 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -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; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 9ad04f0bb709..a68a381836e1 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -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;; diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index eff5b9a2de3a..6d19d15c6d77 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -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; diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 6435e509dd56..1dc428fc0cce 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -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; diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index edac0ba6652e..1d6ce54e9a86 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -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; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 055d5e8609e8..03348605dd8c 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -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; diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 9d0ca128679e..3072c4562212 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -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 diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c index 854183c28258..742cad6163cb 100644 --- a/drivers/staging/iio/imu/adis16300_ring.c +++ b/drivers/staging/iio/imu/adis16300_ring.c @@ -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; diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c index 9620cbe67edc..a0b80e40d12b 100644 --- a/drivers/staging/iio/imu/adis16350_ring.c +++ b/drivers/staging/iio/imu/adis16350_ring.c @@ -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; diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index c8e23161d006..667f77bb7d71 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -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; diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index dd4d87a8bcaf..5c0e56a6935e 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -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); } diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 610c2b6fb678..f3c87edddafd 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -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); diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index ac017b13bfb3..6124353b2ed1 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -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); diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 99efb6b29143..52624ace0bc5 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -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); |