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 | 15 | #include <linux/platform_device.h> |
| 16 | 16 | #include <linux/property.h> |
| 17 | 17 | |
| 18 | +#include <linux/iio/afe/rescale.h> | |
| 18 | 19 | #include <linux/iio/consumer.h> |
| 19 | 20 | #include <linux/iio/iio.h> |
| 20 | 21 | |
| 21 | −struct rescale; | |
| 22 | − | |
| 23 | −struct rescale_cfg { | |
| 24 | − enum iio_chan_type type; | |
| 25 | − int (*props)(struct device *dev, struct rescale *rescale); | |
| 26 | −}; | |
| 22 | +int rescale_process_scale(struct rescale *rescale, int scale_type, | |
| 23 | + int *val, int *val2) | |
| 24 | +{ | |
| 25 | + s64 tmp; | |
| 27 | 26 | |
| 28 | −struct rescale { | |
| 29 | − const struct rescale_cfg *cfg; | |
| 30 | − struct iio_channel *source; | |
| 31 | − struct iio_chan_spec chan; | |
| 32 | − struct iio_chan_spec_ext_info *ext_info; | |
| 33 | − bool chan_processed; | |
| 34 | − s32 numerator; | |
| 35 | − s32 denominator; | |
| 36 | −}; | |
| 27 | + switch (scale_type) { | |
| 28 | + case IIO_VAL_FRACTIONAL: | |
| 29 | + *val *= rescale->numerator; | |
| 30 | + *val2 *= rescale->denominator; | |
| 31 | + return scale_type; | |
| 32 | + case IIO_VAL_INT: | |
| 33 | + *val *= rescale->numerator; | |
| 34 | + if (rescale->denominator == 1) | |
| 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 | 50 | static int rescale_read_raw(struct iio_dev *indio_dev, |
| 39 | 51 | struct iio_chan_spec const *chan, |
| 40 | 52 | int *val, int *val2, long mask) |
| 41 | 53 | { |
| 42 | 54 | struct rescale *rescale = iio_priv(indio_dev); |
| 43 | − s64 tmp; | |
| 44 | 55 | int ret; |
| 45 | 56 | |
| 46 | 57 | switch (mask) { |
| @@ -66,27 +77,7 @@ static int rescale_read_raw(struct iio_dev *indio_dev, · 19 unmodified lines | ||
| 66 | 77 | } else { |
| 67 | 78 | ret = iio_read_channel_scale(rescale->source, val, val2); |
| 68 | 79 | } |
| 69 | − switch (ret) { | |
| 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 | − } | |
| 80 | + return rescale_process_scale(rescale, ret, val, val2); | |
| 90 | 81 | default: |
| 91 | 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__ */ | |