aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-07-09 05:00:00 -0400
committerJonathan Cameron <jic23@kernel.org>2012-07-09 13:18:15 -0400
commit939546d1a9f47ed169554c711e1e05965b84ffe1 (patch)
tree80ee898547145c1b202a77d3ca5f642809ba9778 /drivers/iio
parentc732a24c5a9392cf3738f5957e0d97d37c09e6e1 (diff)
iio: Add callback to check whether a scan mask is valid
This is useful for cases where the number of valid scan masks grows exponentially, but it is rather easy to check whether a mask is valid or not programmatically. An example of such a case is a device with multiple ADCs where each ADC has a upstream MUX, which allows to select from a number of physical channels. +-------+ +-------+ | | | | --- Channel 1 | ADC 1 |---| MUX 1 | --- ... | | | | --- Channel M +-------+ +-------+ . . . . . . . . . +-------+ +-------+ | | | | --- Channel M * N + 1 | ADC N |---| MUX N | --- ... | | | | --- Channel M * N + M +-------+ +-------+ The number of necessary scan masks for this case is (M+1)**N - 1, on the other hand it is easy to check whether subsets for each ADC of the scanmask have only one bit set. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/industrialio-buffer.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 3d8d187eef2a..cc5db36fb75a 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -570,6 +570,15 @@ int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
570} 570}
571EXPORT_SYMBOL(iio_sw_buffer_preenable); 571EXPORT_SYMBOL(iio_sw_buffer_preenable);
572 572
573static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
574 const unsigned long *mask)
575{
576 if (!indio_dev->setup_ops->validate_scan_mask)
577 return true;
578
579 return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask);
580}
581
573/** 582/**
574 * iio_scan_mask_set() - set particular bit in the scan mask 583 * iio_scan_mask_set() - set particular bit in the scan mask
575 * @buffer: the buffer whose scan mask we are interested in 584 * @buffer: the buffer whose scan mask we are interested in
@@ -589,27 +598,31 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
589 return -ENOMEM; 598 return -ENOMEM;
590 if (!indio_dev->masklength) { 599 if (!indio_dev->masklength) {
591 WARN_ON("trying to set scanmask prior to registering buffer\n"); 600 WARN_ON("trying to set scanmask prior to registering buffer\n");
592 kfree(trialmask); 601 goto err_invalid_mask;
593 return -EINVAL;
594 } 602 }
595 bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); 603 bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
596 set_bit(bit, trialmask); 604 set_bit(bit, trialmask);
597 605
606 if (!iio_validate_scan_mask(indio_dev, trialmask))
607 goto err_invalid_mask;
608
598 if (indio_dev->available_scan_masks) { 609 if (indio_dev->available_scan_masks) {
599 mask = iio_scan_mask_match(indio_dev->available_scan_masks, 610 mask = iio_scan_mask_match(indio_dev->available_scan_masks,
600 indio_dev->masklength, 611 indio_dev->masklength,
601 trialmask); 612 trialmask);
602 if (!mask) { 613 if (!mask)
603 kfree(trialmask); 614 goto err_invalid_mask;
604 return -EINVAL;
605 }
606 } 615 }
607 bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); 616 bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
608 617
609 kfree(trialmask); 618 kfree(trialmask);
610 619
611 return 0; 620 return 0;
612}; 621
622err_invalid_mask:
623 kfree(trialmask);
624 return -EINVAL;
625}
613EXPORT_SYMBOL_GPL(iio_scan_mask_set); 626EXPORT_SYMBOL_GPL(iio_scan_mask_set);
614 627
615int iio_scan_mask_query(struct iio_dev *indio_dev, 628int iio_scan_mask_query(struct iio_dev *indio_dev,