In preparation for the addition of kunit tests, expose the logic responsible for combining channel scales.
Unified · Split
| @@ -15,32 +15,43 @@ · 14 unmodified lines | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/property.h> | 16 | #include <linux/property.h> |
| 17 | 17 | ||
| 18 | #include <linux/iio/afe/rescale.h> | ||
| 18 | #include <linux/iio/consumer.h> | 19 | #include <linux/iio/consumer.h> |
| 19 | #include <linux/iio/iio.h> | 20 | #include <linux/iio/iio.h> |
| 20 | 21 | ||
| 21 | struct rescale; | 22 | int rescale_process_scale(struct rescale *rescale, int scale_type, |
| 22 | 23 | int *val, int *val2) | |
| 23 | struct rescale_cfg { | 24 | { |
| 24 | enum iio_chan_type type; | 25 | s64 tmp; |
| 25 | int (*props)(struct device *dev, struct rescale *rescale); | ||
| 26 | }; | ||
| 27 | 26 | ||
| 28 | struct rescale { | 27 | switch (scale_type) { |
| 29 | const struct rescale_cfg *cfg; | 28 | case IIO_VAL_FRACTIONAL: |
| 30 | struct iio_channel *source; | 29 | *val *= rescale->numerator; |
| 31 | struct iio_chan_spec chan; | 30 | *val2 *= rescale->denominator; |
| 32 | struct iio_chan_spec_ext_info *ext_info; | 31 | return scale_type; |
| 33 | bool chan_processed; | 32 | case IIO_VAL_INT: |
| 34 | s32 numerator; | 33 | *val *= rescale->numerator; |
| 35 | s32 denominator; | 34 | if (rescale->denominator == 1) |
| 36 | }; | 35 | return scale_type; |
| 36 | *val2 = rescale->denominator; | ||
| 37 | return IIO_VAL_FRACTIONAL; | ||
| 38 | case IIO_VAL_FRACTIONAL_LOG2: | ||
| 39 | tmp = (s64)*val * 1000000000LL; | ||
| 40 | tmp = div_s64(tmp, rescale->denominator); | ||
| 41 | tmp *= rescale->numerator; | ||
| 42 | tmp = div_s64(tmp, 1000000000LL); | ||
| 43 | *val = tmp; | ||
| 44 | return scale_type; | ||
| 45 | default: | ||
| 46 | return -EOPNOTSUPP; | ||
| 47 | } | ||
| 48 | } | ||
| 37 | 49 | ||
| 38 | static int rescale_read_raw(struct iio_dev *indio_dev, | 50 | static int rescale_read_raw(struct iio_dev *indio_dev, |
| 39 | struct iio_chan_spec const *chan, | 51 | struct iio_chan_spec const *chan, |
| 40 | int *val, int *val2, long mask) | 52 | int *val, int *val2, long mask) |
| 41 | { | 53 | { |
| 42 | struct rescale *rescale = iio_priv(indio_dev); | 54 | struct rescale *rescale = iio_priv(indio_dev); |
| 43 | s64 tmp; | ||
| 44 | int ret; | 55 | int ret; |
| 45 | 56 | ||
| 46 | switch (mask) { | 57 | switch (mask) { |
| @@ -66,27 +77,7 @@ static int rescale_read_raw(struct iio_dev *indio_dev, · 19 unmodified lines | |||
| 66 | } else { | 77 | } else { |
| 67 | ret = iio_read_channel_scale(rescale->source, val, val2); | 78 | ret = iio_read_channel_scale(rescale->source, val, val2); |
| 68 | } | 79 | } |
| 69 | switch (ret) { | 80 | return rescale_process_scale(rescale, ret, val, val2); |
| 70 | case IIO_VAL_FRACTIONAL: | ||
| 71 | *val *= rescale->numerator; | ||
| 72 | *val2 *= rescale->denominator; | ||
| 73 | return ret; | ||
| 74 | case IIO_VAL_INT: | ||
| 75 | *val *= rescale->numerator; | ||
| 76 | if (rescale->denominator == 1) | ||
| 77 | return ret; | ||
| 78 | *val2 = rescale->denominator; | ||
| 79 | return IIO_VAL_FRACTIONAL; | ||
| 80 | case IIO_VAL_FRACTIONAL_LOG2: | ||
| 81 | tmp = (s64)*val * 1000000000LL; | ||
| 82 | tmp = div_s64(tmp, rescale->denominator); | ||
| 83 | tmp *= rescale->numerator; | ||
| 84 | tmp = div_s64(tmp, 1000000000LL); | ||
| 85 | *val = tmp; | ||
| 86 | return ret; | ||
| 87 | default: | ||
| 88 | return -EOPNOTSUPP; | ||
| 89 | } | ||
| 90 | default: | 81 | default: |
| 91 | return -EINVAL; | 82 | return -EINVAL; |
| 92 | } | 83 | } |
| @@ -0,0 +1,32 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2018 Axentia Technologies AB | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __IIO_RESCALE_H__ | ||
| 7 | #define __IIO_RESCALE_H__ | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/iio/iio.h> | ||
| 11 | |||
| 12 | struct device; | ||
| 13 | struct rescale; | ||
| 14 | |||
| 15 | struct rescale_cfg { | ||
| 16 | enum iio_chan_type type; | ||
| 17 | int (*props)(struct device *dev, struct rescale *rescale); | ||
| 18 | }; | ||
| 19 | |||
| 20 | struct rescale { | ||
| 21 | const struct rescale_cfg *cfg; | ||
| 22 | struct iio_channel *source; | ||
| 23 | struct iio_chan_spec chan; | ||
| 24 | struct iio_chan_spec_ext_info *ext_info; | ||
| 25 | bool chan_processed; | ||
| 26 | s32 numerator; | ||
| 27 | s32 denominator; | ||
| 28 | }; | ||
| 29 | |||
| 30 | int rescale_process_scale(struct rescale *rescale, int scale_type, | ||
| 31 | int *val, int *val2); | ||
| 32 | #endif /* __IIO_RESCALE_H__ */ | ||