Commit bc437f75 authored by Liam Beguin's avatar Liam Beguin Committed by Jonathan Cameron
Browse files

iio: afe: rescale: expose scale processing function



In preparation for the addition of kunit tests, expose the logic
responsible for combining channel scales.

Signed-off-by: default avatarLiam Beguin <liambeguin@gmail.com>
Reviewed-by: default avatarPeter Rosin <peda@axentia.se>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220213025739.2561834-2-liambeguin@gmail.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent b59c0415
Loading
Loading
Loading
Loading
+28 −37
Original line number Original line Diff line number Diff line
@@ -15,32 +15,43 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/property.h>


#include <linux/iio/afe/rescale.h>
#include <linux/iio/consumer.h>
#include <linux/iio/consumer.h>
#include <linux/iio/iio.h>
#include <linux/iio/iio.h>


struct rescale;
int rescale_process_scale(struct rescale *rescale, int scale_type,

			  int *val, int *val2)
struct rescale_cfg {
{
	enum iio_chan_type type;
	s64 tmp;
	int (*props)(struct device *dev, struct rescale *rescale);
};


struct rescale {
	switch (scale_type) {
	const struct rescale_cfg *cfg;
	case IIO_VAL_FRACTIONAL:
	struct iio_channel *source;
		*val *= rescale->numerator;
	struct iio_chan_spec chan;
		*val2 *= rescale->denominator;
	struct iio_chan_spec_ext_info *ext_info;
		return scale_type;
	bool chan_processed;
	case IIO_VAL_INT:
	s32 numerator;
		*val *= rescale->numerator;
	s32 denominator;
		if (rescale->denominator == 1)
};
			return scale_type;
		*val2 = rescale->denominator;
		return IIO_VAL_FRACTIONAL;
	case IIO_VAL_FRACTIONAL_LOG2:
		tmp = (s64)*val * 1000000000LL;
		tmp = div_s64(tmp, rescale->denominator);
		tmp *= rescale->numerator;
		tmp = div_s64(tmp, 1000000000LL);
		*val = tmp;
		return scale_type;
	default:
		return -EOPNOTSUPP;
	}
}


static int rescale_read_raw(struct iio_dev *indio_dev,
static int rescale_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
			    int *val, int *val2, long mask)
{
{
	struct rescale *rescale = iio_priv(indio_dev);
	struct rescale *rescale = iio_priv(indio_dev);
	s64 tmp;
	int ret;
	int ret;


	switch (mask) {
	switch (mask) {
@@ -66,27 +77,7 @@ static int rescale_read_raw(struct iio_dev *indio_dev,
		} else {
		} else {
			ret = iio_read_channel_scale(rescale->source, val, val2);
			ret = iio_read_channel_scale(rescale->source, val, val2);
		}
		}
		switch (ret) {
		return rescale_process_scale(rescale, ret, val, val2);
		case IIO_VAL_FRACTIONAL:
			*val *= rescale->numerator;
			*val2 *= rescale->denominator;
			return ret;
		case IIO_VAL_INT:
			*val *= rescale->numerator;
			if (rescale->denominator == 1)
				return ret;
			*val2 = rescale->denominator;
			return IIO_VAL_FRACTIONAL;
		case IIO_VAL_FRACTIONAL_LOG2:
			tmp = (s64)*val * 1000000000LL;
			tmp = div_s64(tmp, rescale->denominator);
			tmp *= rescale->numerator;
			tmp = div_s64(tmp, 1000000000LL);
			*val = tmp;
			return ret;
		default:
			return -EOPNOTSUPP;
		}
	default:
	default:
		return -EINVAL;
		return -EINVAL;
	}
	}
+32 −0
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2018 Axentia Technologies AB
 */

#ifndef __IIO_RESCALE_H__
#define __IIO_RESCALE_H__

#include <linux/types.h>
#include <linux/iio/iio.h>

struct device;
struct rescale;

struct rescale_cfg {
	enum iio_chan_type type;
	int (*props)(struct device *dev, struct rescale *rescale);
};

struct rescale {
	const struct rescale_cfg *cfg;
	struct iio_channel *source;
	struct iio_chan_spec chan;
	struct iio_chan_spec_ext_info *ext_info;
	bool chan_processed;
	s32 numerator;
	s32 denominator;
};

int rescale_process_scale(struct rescale *rescale, int scale_type,
			  int *val, int *val2);
#endif /* __IIO_RESCALE_H__ */