/*
 * Driver for voltage controller regulators
 *
 * Copyright (C) 2017 Google, Inc.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/sort.h>

struct vctrl_voltage_range {
	int min_uV;
	int max_uV;
};

struct vctrl_voltage_ranges {
	struct vctrl_voltage_range ctrl;
	struct vctrl_voltage_range out;
};

struct vctrl_voltage_table {
	int ctrl;
	int out;
	int ovp_min_sel;
};

struct vctrl_data {
	struct regulator_dev *rdev;
	struct regulator_desc desc;
	struct regulator *ctrl_reg;
	bool enabled;
	unsigned int min_slew_down_rate;
	unsigned int ovp_threshold;
	struct vctrl_voltage_ranges vrange;
	struct vctrl_voltage_table *vtable;
	unsigned int sel;
};

static int vctrl_calc_ctrl_voltage(struct vctrl_data *vctrl, int out_uV)
{
	struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
	struct vctrl_voltage_range *out = &vctrl->vrange.out;

	return ctrl->min_uV +
		DIV_ROUND_CLOSEST_ULL((s64)(out_uV - out->min_uV) *
				      (ctrl->max_uV - ctrl->min_uV),
				      out->max_uV - out->min_uV);
}

static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
{
	struct vctrl_voltage_range *ctrl = &vctrl->vrange.ctrl;
	struct vctrl_voltage_range *out = &vctrl->vrange.out;

	if (ctrl_uV < 0) {
		pr_err("vctrl: failed to get control voltage\n");
		return ctrl_uV;
	}

	if (ctrl_uV < ctrl->min_uV)
		return out->min_uV;

	if (ctrl_uV > ctrl->max_uV)
		return out->max_uV;

	return out->min_uV +
		DIV_ROUND_CLOSEST_ULL((s64)(ctrl_uV - ctrl->min_uV) *
				      (out->max_uV - out->min_uV),
				      ctrl->max_uV - ctrl->min_uV);
}

static int vctrl_get_voltage(struct regulator_dev *rdev)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
	int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);

	return vctrl_calc_output_voltage(vctrl, ctrl_uV);
}

static int vctrl_set_voltage(struct regulator_dev *rdev,
			     int req_min_uV, int req_max_uV,
			     unsigned int *selector)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
	struct regulator *ctrl_reg = vctrl->ctrl_reg;
	int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
	int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
	int ret;

	if (req_min_uV >= uV || !vctrl->ovp_threshold)
		/* voltage rising or no OVP */
		return regulator_set_voltage(
			ctrl_reg,
			vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
			vctrl_calc_ctrl_voltage(vctrl, req_max_uV));

	while (uV > req_min_uV) {
		int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
		int next_uV;
		int next_ctrl_uV;
		int delay;

		/* Make sure no infinite loop even in crazy cases */
		if (max_drop_uV == 0)
			max_drop_uV = 1;

		next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
		next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);

		ret = regulator_set_voltage(ctrl_reg,
					    next_ctrl_uV,
					    next_ctrl_uV);
		if (ret)
			goto err;

		delay = DIV_ROUND_UP(uV - next_uV, vctrl->min_slew_down_rate);
		usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));

		uV = next_uV;
	}

	return 0;

err:
	/* Try to go back to original voltage */
	regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);

	return ret;
}

static int vctrl_get_voltage_sel(struct regulator_dev *rdev)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);

	return vctrl->sel;
}

static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
				 unsigned int selector)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
	struct regulator *ctrl_reg = vctrl->ctrl_reg;
	unsigned int orig_sel = vctrl->sel;
	int ret;

	if (selector >= rdev->desc->n_voltages)
		return -EINVAL;

	if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
		/* voltage rising or no OVP */
		ret = regulator_set_voltage(ctrl_reg,
					    vctrl->vtable[selector].ctrl,
					    vctrl->vtable[selector].ctrl);
		if (!ret)
			vctrl->sel = selector;

		return ret;
	}

	while (vctrl->sel != selector) {
		unsigned int next_sel;
		int delay;

		if (selector >= vctrl->vtable[vctrl->sel].ovp_min_sel)
			next_sel = selector;
		else
			next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;

		ret = regulator_set_voltage(ctrl_reg,
					    vctrl->vtable[next_sel].ctrl,
					    vctrl->vtable[next_sel].ctrl);
		if (ret) {
			dev_err(&rdev->dev,
				"failed to set control voltage to %duV\n",
				vctrl->vtable[next_sel].ctrl);
			goto err;
		}
		vctrl->sel = next_sel;

		delay = DIV_ROUND_UP(vctrl->vtable[vctrl->sel].out -
				     vctrl->vtable[next_sel].out,
				     vctrl->min_slew_down_rate);
		usleep_range(delay, delay + DIV_ROUND_UP(delay, 10));
	}

	return 0;

err:
	if (vctrl->sel != orig_sel) {
		/* Try to go back to original voltage */
		if (!regulator_set_voltage(ctrl_reg,
					   vctrl->vtable[orig_sel].ctrl,
					   vctrl->vtable[orig_sel].ctrl))
			vctrl->sel = orig_sel;
		else
			dev_warn(&rdev->dev,
				 "failed to restore original voltage\n");
	}

	return ret;
}

static int vctrl_list_voltage(struct regulator_dev *rdev,
			      unsigned int selector)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);

	if (selector >= rdev->desc->n_voltages)
		return -EINVAL;

	return vctrl->vtable[selector].out;
}

static int vctrl_parse_dt(struct platform_device *pdev,
			  struct vctrl_data *vctrl)
{
	int ret;
	struct device_node *np = pdev->dev.of_node;
	u32 pval;
	u32 vrange_ctrl[2];

	vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl");
	if (IS_ERR(vctrl->ctrl_reg))
		return PTR_ERR(vctrl->ctrl_reg);

	ret = of_property_read_u32(np, "ovp-threshold-percent", &pval);
	if (!ret) {
		vctrl->ovp_threshold = pval;
		if (vctrl->ovp_threshold > 100) {
			dev_err(&pdev->dev,
				"ovp-threshold-percent (%u) > 100\n",
				vctrl->ovp_threshold);
			return -EINVAL;
		}
	}

	ret = of_property_read_u32(np, "min-slew-down-rate", &pval);
	if (!ret) {
		vctrl->min_slew_down_rate = pval;

		/* We use the value as int and as divider; sanity check */
		if (vctrl->min_slew_down_rate == 0) {
			dev_err(&pdev->dev,
				"min-slew-down-rate must not be 0\n");
			return -EINVAL;
		} else if (vctrl->min_slew_down_rate > INT_MAX) {
			dev_err(&pdev->dev, "min-slew-down-rate (%u) too big\n",
				vctrl->min_slew_down_rate);
			return -EINVAL;
		}
	}

	if (vctrl->ovp_threshold && !vctrl->min_slew_down_rate) {
		dev_err(&pdev->dev,
			"ovp-threshold-percent requires min-slew-down-rate\n");
		return -EINVAL;
	}

	ret = of_property_read_u32(np, "regulator-min-microvolt", &pval);
	if (ret) {
		dev_err(&pdev->dev,
			"failed to read regulator-min-microvolt: %d\n", ret);
		return ret;
	}
	vctrl->vrange.out.min_uV = pval;

	ret = of_property_read_u32(np, "regulator-max-microvolt", &pval);
	if (ret) {
		dev_err(&pdev->dev,
			"failed to read regulator-max-microvolt: %d\n", ret);
		return ret;
	}
	vctrl->vrange.out.max_uV = pval;

	ret = of_property_read_u32_array(np, "ctrl-voltage-range", vrange_ctrl,
					 2);
	if (ret) {
		dev_err(&pdev->dev, "failed to read ctrl-voltage-range: %d\n",
			ret);
		return ret;
	}

	if (vrange_ctrl[0] >= vrange_ctrl[1]) {
		dev_err(&pdev->dev, "ctrl-voltage-range is invalid: %d-%d\n",
			vrange_ctrl[0], vrange_ctrl[1]);
		return -EINVAL;
	}

	vctrl->vrange.ctrl.min_uV = vrange_ctrl[0];
	vctrl->vrange.ctrl.max_uV = vrange_ctrl[1];

	return 0;
}

static int vctrl_cmp_ctrl_uV(const void *a, const void *b)
{
	const struct vctrl_voltage_table *at = a;
	const struct vctrl_voltage_table *bt = b;

	return at->ctrl - bt->ctrl;
}

static int vctrl_init_vtable(struct platform_device *pdev)
{
	struct vctrl_data *vctrl = platform_get_drvdata(pdev);
	struct regulator_desc *rdesc = &vctrl->desc;
	struct regulator *ctrl_reg = vctrl->ctrl_reg;
	struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl;
	int n_voltages;
	int ctrl_uV;
	int i, idx_vt;

	n_voltages = regulator_count_voltages(ctrl_reg);

	rdesc->n_voltages = n_voltages;

	/* determine number of steps within the range of the vctrl regulator */
	for (i = 0; i < n_voltages; i++) {
		ctrl_uV = regulator_list_voltage(ctrl_reg, i);

		if (ctrl_uV < vrange_ctrl->min_uV ||
		    ctrl_uV > vrange_ctrl->max_uV) {
			rdesc->n_voltages--;
			continue;
		}
	}

	if (rdesc->n_voltages == 0) {
		dev_err(&pdev->dev, "invalid configuration\n");
		return -EINVAL;
	}

	vctrl->vtable = devm_kcalloc(&pdev->dev, rdesc->n_voltages,
				     sizeof(struct vctrl_voltage_table),
				     GFP_KERNEL);
	if (!vctrl->vtable)
		return -ENOMEM;

	/* create mapping control <=> output voltage */
	for (i = 0, idx_vt = 0; i < n_voltages; i++) {
		ctrl_uV = regulator_list_voltage(ctrl_reg, i);

		if (ctrl_uV < vrange_ctrl->min_uV ||
		    ctrl_uV > vrange_ctrl->max_uV)
			continue;

		vctrl->vtable[idx_vt].ctrl = ctrl_uV;
		vctrl->vtable[idx_vt].out =
			vctrl_calc_output_voltage(vctrl, ctrl_uV);
		idx_vt++;
	}

	/* we rely on the table to be ordered by ascending voltage */
	sort(vctrl->vtable, rdesc->n_voltages,
	     sizeof(struct vctrl_voltage_table), vctrl_cmp_ctrl_uV,
	     NULL);

	/* pre-calculate OVP-safe downward transitions */
	for (i = rdesc->n_voltages - 1; i > 0; i--) {
		int j;
		int ovp_min_uV = (vctrl->vtable[i].out *
				  (100 - vctrl->ovp_threshold)) / 100;

		for (j = 0; j < i; j++) {
			if (vctrl->vtable[j].out >= ovp_min_uV) {
				vctrl->vtable[i].ovp_min_sel = j;
				break;
			}
		}

		if (j == i) {
			dev_warn(&pdev->dev, "switching down from %duV may cause OVP shutdown\n",
				vctrl->vtable[i].out);
			/* use next lowest voltage */
			vctrl->vtable[i].ovp_min_sel = i - 1;
		}
	}

	return 0;
}

static int vctrl_enable(struct regulator_dev *rdev)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
	int ret = regulator_enable(vctrl->ctrl_reg);

	if (!ret)
		vctrl->enabled = true;

	return ret;
}

static int vctrl_disable(struct regulator_dev *rdev)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
	int ret = regulator_disable(vctrl->ctrl_reg);

	if (!ret)
		vctrl->enabled = false;

	return ret;
}

static int vctrl_is_enabled(struct regulator_dev *rdev)
{
	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);

	return vctrl->enabled;
}

static const struct regulator_ops vctrl_ops_cont = {
	.enable		  = vctrl_enable,
	.disable	  = vctrl_disable,
	.is_enabled	  = vctrl_is_enabled,
	.get_voltage	  = vctrl_get_voltage,
	.set_voltage	  = vctrl_set_voltage,
};

static const struct regulator_ops vctrl_ops_non_cont = {
	.enable		  = vctrl_enable,
	.disable	  = vctrl_disable,
	.is_enabled	  = vctrl_is_enabled,
	.set_voltage_sel = vctrl_set_voltage_sel,
	.get_voltage_sel = vctrl_get_voltage_sel,
	.list_voltage    = vctrl_list_voltage,
	.map_voltage     = regulator_map_voltage_iterate,
};

static int vctrl_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct vctrl_data *vctrl;
	const struct regulator_init_data *init_data;
	struct regulator_desc *rdesc;
	struct regulator_config cfg = { };
	struct vctrl_voltage_range *vrange_ctrl;
	int ctrl_uV;
	int ret;

	vctrl = devm_kzalloc(&pdev->dev, sizeof(struct vctrl_data),
			     GFP_KERNEL);
	if (!vctrl)
		return -ENOMEM;

	platform_set_drvdata(pdev, vctrl);

	ret = vctrl_parse_dt(pdev, vctrl);
	if (ret)
		return ret;

	vrange_ctrl = &vctrl->vrange.ctrl;

	rdesc = &vctrl->desc;
	rdesc->name = "vctrl";
	rdesc->type = REGULATOR_VOLTAGE;
	rdesc->owner = THIS_MODULE;

	if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) ||
	    (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) {
		rdesc->continuous_voltage_range = true;
		rdesc->ops = &vctrl_ops_cont;
	} else {
		rdesc->ops = &vctrl_ops_non_cont;
	}

	init_data = of_get_regulator_init_data(&pdev->dev, np, rdesc);
	if (!init_data)
		return -ENOMEM;

	cfg.of_node = np;
	cfg.dev = &pdev->dev;
	cfg.driver_data = vctrl;
	cfg.init_data = init_data;

	if (!rdesc->continuous_voltage_range) {
		ret = vctrl_init_vtable(pdev);
		if (ret)
			return ret;

		ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
		if (ctrl_uV < 0) {
			dev_err(&pdev->dev, "failed to get control voltage\n");
			return ctrl_uV;
		}

		/* determine current voltage selector from control voltage */
		if (ctrl_uV < vrange_ctrl->min_uV) {
			vctrl->sel = 0;
		} else if (ctrl_uV > vrange_ctrl->max_uV) {
			vctrl->sel = rdesc->n_voltages - 1;
		} else {
			int i;

			for (i = 0; i < rdesc->n_voltages; i++) {
				if (ctrl_uV == vctrl->vtable[i].ctrl) {
					vctrl->sel = i;
					break;
				}
			}
		}
	}

	vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg);
	if (IS_ERR(vctrl->rdev)) {
		ret = PTR_ERR(vctrl->rdev);
		dev_err(&pdev->dev, "failed to register regulator: %d\n", ret);
		return ret;
	}

	return 0;
}

static const struct of_device_id vctrl_of_match[] = {
	{ .compatible = "vctrl-regulator", },
	{},
};
MODULE_DEVICE_TABLE(of, vctrl_of_match);

static struct platform_driver vctrl_driver = {
	.probe		= vctrl_probe,
	.driver		= {
		.name		= "vctrl-regulator",
		.of_match_table = of_match_ptr(vctrl_of_match),
	},
};

module_platform_driver(vctrl_driver);

MODULE_DESCRIPTION("Voltage Controlled Regulator Driver");
MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
MODULE_LICENSE("GPL v2");
