// 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/mod_devicetable.h>
#include <linux/module.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;
	}
}
EXPORT_SYMBOL_NS_GPL(rescale_process_scale, IIO_RESCALE);

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;
	}
}
EXPORT_SYMBOL_NS_GPL(rescale_process_offset, IIO_RESCALE);

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 = 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");
