// SPDX-License-Identifier: GPL-2.0
/*
 * IIO rescale driver
 *
 * Copyright (C) 2018 Axentia Technologies AB
 * Copyright (C) 2022 Liam Beguin <liambeguin@gmail.com>
 *
 * Author: Peter Rosin <peda@axentia.se>
 */

#include <linux/err.h>
#include <linux/gcd.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/property.h>

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

int rescale_process_scale(struct rescale *rescale, int scale_type,
			  int *val, int *val2)
{
	s64 tmp;
	int _val, _val2;
	s32 rem, rem2;
	u32 mult;
	u32 neg;

	switch (scale_type) {
	case IIO_VAL_INT:
		*val *= rescale->numerator;
		if (rescale->denominator == 1)
			return scale_type;
		*val2 = rescale->denominator;
		return IIO_VAL_FRACTIONAL;
	case IIO_VAL_FRACTIONAL:
		/*
		 * When the product of both scales doesn't overflow, avoid
		 * potential accuracy loss (for in kernel consumers) by
		 * keeping a fractional representation.
		 */
		if (!check_mul_overflow(*val, rescale->numerator, &_val) &&
		    !check_mul_overflow(*val2, rescale->denominator, &_val2)) {
			*val = _val;
			*val2 = _val2;
			return IIO_VAL_FRACTIONAL;
		}
		fallthrough;
	case IIO_VAL_FRACTIONAL_LOG2:
		tmp = (s64)*val * 1000000000LL;
		tmp = div_s64(tmp, rescale->denominator);
		tmp *= rescale->numerator;

		tmp = div_s64_rem(tmp, 1000000000LL, &rem);
		*val = tmp;

		if (!rem)
			return scale_type;

		if (scale_type == IIO_VAL_FRACTIONAL)
			tmp = *val2;
		else
			tmp = ULL(1) << *val2;

		rem2 = *val % (int)tmp;
		*val = *val / (int)tmp;

		*val2 = rem / (int)tmp;
		if (rem2)
			*val2 += div_s64((s64)rem2 * 1000000000LL, tmp);

		return IIO_VAL_INT_PLUS_NANO;
	case IIO_VAL_INT_PLUS_NANO:
	case IIO_VAL_INT_PLUS_MICRO:
		mult = scale_type == IIO_VAL_INT_PLUS_NANO ? 1000000000L : 1000000L;

		/*
		 * For IIO_VAL_INT_PLUS_{MICRO,NANO} scale types if either *val
		 * OR *val2 is negative the schan scale is negative, i.e.
		 * *val = 1 and *val2 = -0.5 yields -1.5 not -0.5.
		 */
		neg = *val < 0 || *val2 < 0;

		tmp = (s64)abs(*val) * abs(rescale->numerator);
		*val = div_s64_rem(tmp, abs(rescale->denominator), &rem);

		tmp = (s64)rem * mult + (s64)abs(*val2) * abs(rescale->numerator);
		tmp = div_s64(tmp, abs(rescale->denominator));

		*val += div_s64_rem(tmp, mult, val2);

		/*
		 * If only one of the rescaler elements or the schan scale is
		 * negative, the combined scale is negative.
		 */
		if (neg ^ ((rescale->numerator < 0) ^ (rescale->denominator < 0))) {
			if (*val)
				*val = -*val;
			else
				*val2 = -*val2;
		}

		return scale_type;
	default:
		return -EOPNOTSUPP;
	}
}

int rescale_process_offset(struct rescale *rescale, int scale_type,
			   int scale, int scale2, int schan_off,
			   int *val, int *val2)
{
	s64 tmp, tmp2;

	switch (scale_type) {
	case IIO_VAL_FRACTIONAL:
		tmp = (s64)rescale->offset * scale2;
		*val = div_s64(tmp, scale) + schan_off;
		return IIO_VAL_INT;
	case IIO_VAL_INT:
		*val = div_s64(rescale->offset, scale) + schan_off;
		return IIO_VAL_INT;
	case IIO_VAL_FRACTIONAL_LOG2:
		tmp = (s64)rescale->offset * (1 << scale2);
		*val = div_s64(tmp, scale) + schan_off;
		return IIO_VAL_INT;
	case IIO_VAL_INT_PLUS_NANO:
		tmp = (s64)rescale->offset * 1000000000LL;
		tmp2 = ((s64)scale * 1000000000LL) + scale2;
		*val = div64_s64(tmp, tmp2) + schan_off;
		return IIO_VAL_INT;
	case IIO_VAL_INT_PLUS_MICRO:
		tmp = (s64)rescale->offset * 1000000LL;
		tmp2 = ((s64)scale * 1000000LL) + scale2;
		*val = div64_s64(tmp, tmp2) + schan_off;
		return IIO_VAL_INT;
	default:
		return -EOPNOTSUPP;
	}
}

static int rescale_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct rescale *rescale = iio_priv(indio_dev);
	int scale, scale2;
	int schan_off = 0;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (rescale->chan_processed)
			/*
			 * When only processed channels are supported, we
			 * read the processed data and scale it by 1/1
			 * augmented with whatever the rescaler has calculated.
			 */
			return iio_read_channel_processed(rescale->source, val);
		else
			return iio_read_channel_raw(rescale->source, val);

	case IIO_CHAN_INFO_SCALE:
		if (rescale->chan_processed) {
			/*
			 * Processed channels are scaled 1-to-1
			 */
			*val = 1;
			*val2 = 1;
			ret = IIO_VAL_FRACTIONAL;
		} else {
			ret = iio_read_channel_scale(rescale->source, val, val2);
		}
		return rescale_process_scale(rescale, ret, val, val2);
	case IIO_CHAN_INFO_OFFSET:
		/*
		 * Processed channels are scaled 1-to-1 and source offset is
		 * already taken into account.
		 *
		 * In other cases, real world measurement are expressed as:
		 *
		 *	schan_scale * (raw + schan_offset)
		 *
		 * Given that the rescaler parameters are applied recursively:
		 *
		 *	rescaler_scale * (schan_scale * (raw + schan_offset) +
		 *		rescaler_offset)
		 *
		 * Or,
		 *
		 *	(rescaler_scale * schan_scale) * (raw +
		 *		(schan_offset +	rescaler_offset / schan_scale)
		 *
		 * Thus, reusing the original expression the parameters exposed
		 * to userspace are:
		 *
		 *	scale = schan_scale * rescaler_scale
		 *	offset = schan_offset + rescaler_offset / schan_scale
		 */
		if (rescale->chan_processed) {
			*val = rescale->offset;
			return IIO_VAL_INT;
		}

		if (iio_channel_has_info(rescale->source->channel,
					 IIO_CHAN_INFO_OFFSET)) {
			ret = iio_read_channel_offset(rescale->source,
						      &schan_off, NULL);
			if (ret != IIO_VAL_INT)
				return ret < 0 ? ret : -EOPNOTSUPP;
		}

		ret = iio_read_channel_scale(rescale->source, &scale, &scale2);
		return rescale_process_offset(rescale, ret, scale, scale2,
					      schan_off, val, val2);
	default:
		return -EINVAL;
	}
}

static int rescale_read_avail(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      const int **vals, int *type, int *length,
			      long mask)
{
	struct rescale *rescale = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		*type = IIO_VAL_INT;
		return iio_read_avail_channel_raw(rescale->source,
						  vals, length);
	default:
		return -EINVAL;
	}
}

static const struct iio_info rescale_info = {
	.read_raw = rescale_read_raw,
	.read_avail = rescale_read_avail,
};

static ssize_t rescale_read_ext_info(struct iio_dev *indio_dev,
				     uintptr_t private,
				     struct iio_chan_spec const *chan,
				     char *buf)
{
	struct rescale *rescale = iio_priv(indio_dev);

	return iio_read_channel_ext_info(rescale->source,
					 rescale->ext_info[private].name,
					 buf);
}

static ssize_t rescale_write_ext_info(struct iio_dev *indio_dev,
				      uintptr_t private,
				      struct iio_chan_spec const *chan,
				      const char *buf, size_t len)
{
	struct rescale *rescale = iio_priv(indio_dev);

	return iio_write_channel_ext_info(rescale->source,
					  rescale->ext_info[private].name,
					  buf, len);
}

static int rescale_configure_channel(struct device *dev,
				     struct rescale *rescale)
{
	struct iio_chan_spec *chan = &rescale->chan;
	struct iio_chan_spec const *schan = rescale->source->channel;

	chan->indexed = 1;
	chan->output = schan->output;
	chan->ext_info = rescale->ext_info;
	chan->type = rescale->cfg->type;

	if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) ||
	    iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) {
		dev_info(dev, "using raw+scale source channel\n");
	} else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) {
		dev_info(dev, "using processed channel\n");
		rescale->chan_processed = true;
	} else {
		dev_err(dev, "source channel is not supported\n");
		return -EINVAL;
	}

	chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
		BIT(IIO_CHAN_INFO_SCALE);

	if (rescale->offset)
		chan->info_mask_separate |= BIT(IIO_CHAN_INFO_OFFSET);

	/*
	 * Using .read_avail() is fringe to begin with and makes no sense
	 * whatsoever for processed channels, so we make sure that this cannot
	 * be called on a processed channel.
	 */
	if (iio_channel_has_available(schan, IIO_CHAN_INFO_RAW) &&
	    !rescale->chan_processed)
		chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);

	return 0;
}

static int rescale_current_sense_amplifier_props(struct device *dev,
						 struct rescale *rescale)
{
	u32 sense;
	u32 gain_mult = 1;
	u32 gain_div = 1;
	u32 factor;
	int ret;

	ret = device_property_read_u32(dev, "sense-resistor-micro-ohms",
				       &sense);
	if (ret) {
		dev_err(dev, "failed to read the sense resistance: %d\n", ret);
		return ret;
	}

	device_property_read_u32(dev, "sense-gain-mult", &gain_mult);
	device_property_read_u32(dev, "sense-gain-div", &gain_div);

	/*
	 * Calculate the scaling factor, 1 / (gain * sense), or
	 * gain_div / (gain_mult * sense), while trying to keep the
	 * numerator/denominator from overflowing.
	 */
	factor = gcd(sense, 1000000);
	rescale->numerator = 1000000 / factor;
	rescale->denominator = sense / factor;

	factor = gcd(rescale->numerator, gain_mult);
	rescale->numerator /= factor;
	rescale->denominator *= gain_mult / factor;

	factor = gcd(rescale->denominator, gain_div);
	rescale->numerator *= gain_div / factor;
	rescale->denominator /= factor;

	return 0;
}

static int rescale_current_sense_shunt_props(struct device *dev,
					     struct rescale *rescale)
{
	u32 shunt;
	u32 factor;
	int ret;

	ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms",
				       &shunt);
	if (ret) {
		dev_err(dev, "failed to read the shunt resistance: %d\n", ret);
		return ret;
	}

	factor = gcd(shunt, 1000000);
	rescale->numerator = 1000000 / factor;
	rescale->denominator = shunt / factor;

	return 0;
}

static int rescale_voltage_divider_props(struct device *dev,
					 struct rescale *rescale)
{
	int ret;
	u32 factor;

	ret = device_property_read_u32(dev, "output-ohms",
				       &rescale->denominator);
	if (ret) {
		dev_err(dev, "failed to read output-ohms: %d\n", ret);
		return ret;
	}

	ret = device_property_read_u32(dev, "full-ohms",
				       &rescale->numerator);
	if (ret) {
		dev_err(dev, "failed to read full-ohms: %d\n", ret);
		return ret;
	}

	factor = gcd(rescale->numerator, rescale->denominator);
	rescale->numerator /= factor;
	rescale->denominator /= factor;

	return 0;
}

static int rescale_temp_sense_rtd_props(struct device *dev,
					struct rescale *rescale)
{
	u32 factor;
	u32 alpha;
	u32 iexc;
	u32 tmp;
	int ret;
	u32 r0;

	ret = device_property_read_u32(dev, "excitation-current-microamp",
				       &iexc);
	if (ret) {
		dev_err(dev, "failed to read excitation-current-microamp: %d\n",
			ret);
		return ret;
	}

	ret = device_property_read_u32(dev, "alpha-ppm-per-celsius", &alpha);
	if (ret) {
		dev_err(dev, "failed to read alpha-ppm-per-celsius: %d\n",
			ret);
		return ret;
	}

	ret = device_property_read_u32(dev, "r-naught-ohms", &r0);
	if (ret) {
		dev_err(dev, "failed to read r-naught-ohms: %d\n", ret);
		return ret;
	}

	tmp = r0 * iexc * alpha / 1000000;
	factor = gcd(tmp, 1000000);
	rescale->numerator = 1000000 / factor;
	rescale->denominator = tmp / factor;

	rescale->offset = -1 * ((r0 * iexc) / 1000);

	return 0;
}

static int rescale_temp_transducer_props(struct device *dev,
					 struct rescale *rescale)
{
	s32 offset = 0;
	s32 sense = 1;
	s32 alpha;
	int ret;

	device_property_read_u32(dev, "sense-offset-millicelsius", &offset);
	device_property_read_u32(dev, "sense-resistor-ohms", &sense);
	ret = device_property_read_u32(dev, "alpha-ppm-per-celsius", &alpha);
	if (ret) {
		dev_err(dev, "failed to read alpha-ppm-per-celsius: %d\n", ret);
		return ret;
	}

	rescale->numerator = 1000000;
	rescale->denominator = alpha * sense;

	rescale->offset = div_s64((s64)offset * rescale->denominator,
				  rescale->numerator);

	return 0;
}

enum rescale_variant {
	CURRENT_SENSE_AMPLIFIER,
	CURRENT_SENSE_SHUNT,
	VOLTAGE_DIVIDER,
	TEMP_SENSE_RTD,
	TEMP_TRANSDUCER,
};

static const struct rescale_cfg rescale_cfg[] = {
	[CURRENT_SENSE_AMPLIFIER] = {
		.type = IIO_CURRENT,
		.props = rescale_current_sense_amplifier_props,
	},
	[CURRENT_SENSE_SHUNT] = {
		.type = IIO_CURRENT,
		.props = rescale_current_sense_shunt_props,
	},
	[VOLTAGE_DIVIDER] = {
		.type = IIO_VOLTAGE,
		.props = rescale_voltage_divider_props,
	},
	[TEMP_SENSE_RTD] = {
		.type = IIO_TEMP,
		.props = rescale_temp_sense_rtd_props,
	},
	[TEMP_TRANSDUCER] = {
		.type = IIO_TEMP,
		.props = rescale_temp_transducer_props,
	},
};

static const struct of_device_id rescale_match[] = {
	{ .compatible = "current-sense-amplifier",
	  .data = &rescale_cfg[CURRENT_SENSE_AMPLIFIER], },
	{ .compatible = "current-sense-shunt",
	  .data = &rescale_cfg[CURRENT_SENSE_SHUNT], },
	{ .compatible = "voltage-divider",
	  .data = &rescale_cfg[VOLTAGE_DIVIDER], },
	{ .compatible = "temperature-sense-rtd",
	  .data = &rescale_cfg[TEMP_SENSE_RTD], },
	{ .compatible = "temperature-transducer",
	  .data = &rescale_cfg[TEMP_TRANSDUCER], },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rescale_match);

static int rescale_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct iio_dev *indio_dev;
	struct iio_channel *source;
	struct rescale *rescale;
	int sizeof_ext_info;
	int sizeof_priv;
	int i;
	int ret;

	source = devm_iio_channel_get(dev, NULL);
	if (IS_ERR(source))
		return dev_err_probe(dev, PTR_ERR(source),
				     "failed to get source channel\n");

	sizeof_ext_info = iio_get_channel_ext_info_count(source);
	if (sizeof_ext_info) {
		sizeof_ext_info += 1; /* one extra entry for the sentinel */
		sizeof_ext_info *= sizeof(*rescale->ext_info);
	}

	sizeof_priv = sizeof(*rescale) + sizeof_ext_info;

	indio_dev = devm_iio_device_alloc(dev, sizeof_priv);
	if (!indio_dev)
		return -ENOMEM;

	rescale = iio_priv(indio_dev);

	rescale->cfg = of_device_get_match_data(dev);
	rescale->numerator = 1;
	rescale->denominator = 1;
	rescale->offset = 0;

	ret = rescale->cfg->props(dev, rescale);
	if (ret)
		return ret;

	if (!rescale->numerator || !rescale->denominator) {
		dev_err(dev, "invalid scaling factor.\n");
		return -EINVAL;
	}

	platform_set_drvdata(pdev, indio_dev);

	rescale->source = source;

	indio_dev->name = dev_name(dev);
	indio_dev->info = &rescale_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = &rescale->chan;
	indio_dev->num_channels = 1;
	if (sizeof_ext_info) {
		rescale->ext_info = devm_kmemdup(dev,
						 source->channel->ext_info,
						 sizeof_ext_info, GFP_KERNEL);
		if (!rescale->ext_info)
			return -ENOMEM;

		for (i = 0; rescale->ext_info[i].name; ++i) {
			struct iio_chan_spec_ext_info *ext_info =
				&rescale->ext_info[i];

			if (source->channel->ext_info[i].read)
				ext_info->read = rescale_read_ext_info;
			if (source->channel->ext_info[i].write)
				ext_info->write = rescale_write_ext_info;
			ext_info->private = i;
		}
	}

	ret = rescale_configure_channel(dev, rescale);
	if (ret)
		return ret;

	return devm_iio_device_register(dev, indio_dev);
}

static struct platform_driver rescale_driver = {
	.probe = rescale_probe,
	.driver = {
		.name = "iio-rescale",
		.of_match_table = rescale_match,
	},
};
module_platform_driver(rescale_driver);

MODULE_DESCRIPTION("IIO rescale driver");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
