// SPDX-License-Identifier: GPL-2.0
/*
 * helpers to map values in a linear range to range index
 *
 * Original idea borrowed from regulator framework
 *
 * It might be useful if we could support also inversely proportional ranges?
 * Copyright 2020 ROHM Semiconductors
 */

#include <linux/errno.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/linear_range.h>
#include <linux/module.h>

/**
 * linear_range_values_in_range - return the amount of values in a range
 * @r:		pointer to linear range where values are counted
 *
 * Compute the amount of values in range pointed by @r. Note, values can
 * be all equal - range with selectors 0,...,2 with step 0 still contains
 * 3 values even though they are all equal.
 *
 * Return: the amount of values in range pointed by @r
 */
unsigned int linear_range_values_in_range(const struct linear_range *r)
{
	if (!r)
		return 0;
	return r->max_sel - r->min_sel + 1;
}
EXPORT_SYMBOL_GPL(linear_range_values_in_range);

/**
 * linear_range_values_in_range_array - return the amount of values in ranges
 * @r:		pointer to array of linear ranges where values are counted
 * @ranges:	amount of ranges we include in computation.
 *
 * Compute the amount of values in ranges pointed by @r. Note, values can
 * be all equal - range with selectors 0,...,2 with step 0 still contains
 * 3 values even though they are all equal.
 *
 * Return: the amount of values in first @ranges ranges pointed by @r
 */
unsigned int linear_range_values_in_range_array(const struct linear_range *r,
						int ranges)
{
	int i, values_in_range = 0;

	for (i = 0; i < ranges; i++) {
		int values;

		values = linear_range_values_in_range(&r[i]);
		if (!values)
			return values;

		values_in_range += values;
	}
	return values_in_range;
}
EXPORT_SYMBOL_GPL(linear_range_values_in_range_array);

/**
 * linear_range_get_max_value - return the largest value in a range
 * @r:		pointer to linear range where value is looked from
 *
 * Return: the largest value in the given range
 */
unsigned int linear_range_get_max_value(const struct linear_range *r)
{
	return r->min + (r->max_sel - r->min_sel) * r->step;
}
EXPORT_SYMBOL_GPL(linear_range_get_max_value);

/**
 * linear_range_get_value - fetch a value from given range
 * @r:		pointer to linear range where value is looked from
 * @selector:	selector for which the value is searched
 * @val:	address where found value is updated
 *
 * Search given ranges for value which matches given selector.
 *
 * Return: 0 on success, -EINVAL given selector is not found from any of the
 * ranges.
 */
int linear_range_get_value(const struct linear_range *r, unsigned int selector,
			   unsigned int *val)
{
	if (r->min_sel > selector || r->max_sel < selector)
		return -EINVAL;

	*val = r->min + (selector - r->min_sel) * r->step;

	return 0;
}
EXPORT_SYMBOL_GPL(linear_range_get_value);

/**
 * linear_range_get_value_array - fetch a value from array of ranges
 * @r:		pointer to array of linear ranges where value is looked from
 * @ranges:	amount of ranges in an array
 * @selector:	selector for which the value is searched
 * @val:	address where found value is updated
 *
 * Search through an array of ranges for value which matches given selector.
 *
 * Return: 0 on success, -EINVAL given selector is not found from any of the
 * ranges.
 */
int linear_range_get_value_array(const struct linear_range *r, int ranges,
				 unsigned int selector, unsigned int *val)
{
	int i;

	for (i = 0; i < ranges; i++)
		if (r[i].min_sel <= selector && r[i].max_sel >= selector)
			return linear_range_get_value(&r[i], selector, val);

	return -EINVAL;
}
EXPORT_SYMBOL_GPL(linear_range_get_value_array);

/**
 * linear_range_get_selector_low - return linear range selector for value
 * @r:		pointer to linear range where selector is looked from
 * @val:	value for which the selector is searched
 * @selector:	address where found selector value is updated
 * @found:	flag to indicate that given value was in the range
 *
 * Return selector which which range value is closest match for given
 * input value. Value is matching if it is equal or smaller than given
 * value. If given value is in the range, then @found is set true.
 *
 * Return: 0 on success, -EINVAL if range is invalid or does not contain
 * value smaller or equal to given value
 */
int linear_range_get_selector_low(const struct linear_range *r,
				  unsigned int val, unsigned int *selector,
				  bool *found)
{
	*found = false;

	if (r->min > val)
		return -EINVAL;

	if (linear_range_get_max_value(r) < val) {
		*selector = r->max_sel;
		return 0;
	}

	*found = true;

	if (r->step == 0)
		*selector = r->min_sel;
	else
		*selector = (val - r->min) / r->step + r->min_sel;

	return 0;
}
EXPORT_SYMBOL_GPL(linear_range_get_selector_low);

/**
 * linear_range_get_selector_low_array - return linear range selector for value
 * @r:		pointer to array of linear ranges where selector is looked from
 * @ranges:	amount of ranges to scan from array
 * @val:	value for which the selector is searched
 * @selector:	address where found selector value is updated
 * @found:	flag to indicate that given value was in the range
 *
 * Scan array of ranges for selector which which range value matches given
 * input value. Value is matching if it is equal or smaller than given
 * value. If given value is found to be in a range scanning is stopped and
 * @found is set true. If a range with values smaller than given value is found
 * but the range max is being smaller than given value, then the ranges
 * biggest selector is updated to @selector but scanning ranges is continued
 * and @found is set to false.
 *
 * Return: 0 on success, -EINVAL if range array is invalid or does not contain
 * range with a value smaller or equal to given value
 */
int linear_range_get_selector_low_array(const struct linear_range *r,
					int ranges, unsigned int val,
					unsigned int *selector, bool *found)
{
	int i;
	int ret = -EINVAL;

	for (i = 0; i < ranges; i++) {
		int tmpret;

		tmpret = linear_range_get_selector_low(&r[i], val, selector,
						       found);
		if (!tmpret)
			ret = 0;

		if (*found)
			break;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(linear_range_get_selector_low_array);

/**
 * linear_range_get_selector_high - return linear range selector for value
 * @r:		pointer to linear range where selector is looked from
 * @val:	value for which the selector is searched
 * @selector:	address where found selector value is updated
 * @found:	flag to indicate that given value was in the range
 *
 * Return selector which which range value is closest match for given
 * input value. Value is matching if it is equal or higher than given
 * value. If given value is in the range, then @found is set true.
 *
 * Return: 0 on success, -EINVAL if range is invalid or does not contain
 * value greater or equal to given value
 */
int linear_range_get_selector_high(const struct linear_range *r,
				   unsigned int val, unsigned int *selector,
				   bool *found)
{
	*found = false;

	if (linear_range_get_max_value(r) < val)
		return -EINVAL;

	if (r->min > val) {
		*selector = r->min_sel;
		return 0;
	}

	*found = true;

	if (r->step == 0)
		*selector = r->max_sel;
	else
		*selector = DIV_ROUND_UP(val - r->min, r->step) + r->min_sel;

	return 0;
}
EXPORT_SYMBOL_GPL(linear_range_get_selector_high);

MODULE_DESCRIPTION("linear-ranges helper");
MODULE_LICENSE("GPL");
