diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2012-07-09 05:00:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2012-07-09 13:18:15 -0400 |
commit | 939546d1a9f47ed169554c711e1e05965b84ffe1 (patch) | |
tree | 80ee898547145c1b202a77d3ca5f642809ba9778 /drivers/iio | |
parent | c732a24c5a9392cf3738f5957e0d97d37c09e6e1 (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.c | 27 |
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 | } |
571 | EXPORT_SYMBOL(iio_sw_buffer_preenable); | 571 | EXPORT_SYMBOL(iio_sw_buffer_preenable); |
572 | 572 | ||
573 | static 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 | |
622 | err_invalid_mask: | ||
623 | kfree(trialmask); | ||
624 | return -EINVAL; | ||
625 | } | ||
613 | EXPORT_SYMBOL_GPL(iio_scan_mask_set); | 626 | EXPORT_SYMBOL_GPL(iio_scan_mask_set); |
614 | 627 | ||
615 | int iio_scan_mask_query(struct iio_dev *indio_dev, | 628 | int iio_scan_mask_query(struct iio_dev *indio_dev, |