/*
 * (C) Copyright 2016
 * Texas Instruments Incorporated, <www.ti.com>
 *
 * Keerthy <j-keerthy@ti.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/lp873x.h>

DECLARE_GLOBAL_DATA_PTR;

static const char lp873x_buck_ctrl[LP873X_BUCK_NUM] = {0x2, 0x4};
static const char lp873x_buck_volt[LP873X_BUCK_NUM] = {0x6, 0x7};
static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9};
static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB};

static int lp873x_buck_enable(struct udevice *dev, int op, bool *enable)
{
	int ret;
	unsigned int adr;
	struct dm_regulator_uclass_platdata *uc_pdata;

	uc_pdata = dev_get_uclass_platdata(dev);
	adr = uc_pdata->ctrl_reg;

	ret = pmic_reg_read(dev->parent, adr);
	if (ret < 0)
		return ret;

	if (op == PMIC_OP_GET) {
		ret &= LP873X_BUCK_MODE_MASK;

		if (ret)
			*enable = true;
		else
			*enable = false;

		return 0;
	} else if (op == PMIC_OP_SET) {
		if (*enable)
			ret |= LP873X_BUCK_MODE_MASK;
		else
			ret &= ~(LP873X_BUCK_MODE_MASK);
		ret = pmic_reg_write(dev->parent, adr, ret);
		if (ret)
			return ret;
	}

	return 0;
}

static int lp873x_buck_volt2hex(int uV)
{
	if (uV > LP873X_BUCK_VOLT_MAX)
		return -EINVAL;
	else if (uV > 1400000)
		return (uV - 1420000) / 20000 + 0x9E;
	else if (uV > 730000)
		return (uV - 735000) / 5000 + 0x18;
	else if (uV >= 700000)
		return (uV - 700000) / 10000 + 0x1;
	else
		return -EINVAL;
}

static int lp873x_buck_hex2volt(int hex)
{
	if (hex > LP873X_BUCK_VOLT_MAX_HEX)
		return -EINVAL;
	else if (hex > 0x9D)
		return 1400000 + (hex - 0x9D) * 20000;
	else if (hex > 0x17)
		return 730000 + (hex - 0x17) * 5000;
	else if (hex >= 0x14)
		return 700000 + (hex - 0x14) * 10000;
	else
		return -EINVAL;
}

static int lp873x_buck_val(struct udevice *dev, int op, int *uV)
{
	unsigned int hex, adr;
	int ret;
	struct dm_regulator_uclass_platdata *uc_pdata;

	uc_pdata = dev_get_uclass_platdata(dev);

	if (op == PMIC_OP_GET)
		*uV = 0;

	adr = uc_pdata->volt_reg;

	ret = pmic_reg_read(dev->parent, adr);
	if (ret < 0)
		return ret;

	if (op == PMIC_OP_GET) {
		ret &= LP873X_BUCK_VOLT_MASK;
		ret = lp873x_buck_hex2volt(ret);
		if (ret < 0)
			return ret;
		*uV = ret;

		return 0;
	}

	hex = lp873x_buck_volt2hex(*uV);
	if (hex < 0)
		return hex;

	ret &= 0x0;
	ret |= hex;

	ret = pmic_reg_write(dev->parent, adr, ret);

	return ret;
}

static int lp873x_ldo_enable(struct udevice *dev, int op, bool *enable)
{
	int ret;
	unsigned int adr;
	struct dm_regulator_uclass_platdata *uc_pdata;

	uc_pdata = dev_get_uclass_platdata(dev);
	adr = uc_pdata->ctrl_reg;

	ret = pmic_reg_read(dev->parent, adr);
	if (ret < 0)
		return ret;

	if (op == PMIC_OP_GET) {
		ret &= LP873X_LDO_MODE_MASK;

		if (ret)
			*enable = true;
		else
			*enable = false;

		return 0;
	} else if (op == PMIC_OP_SET) {
		if (*enable)
			ret |= LP873X_LDO_MODE_MASK;
		else
			ret &= ~(LP873X_LDO_MODE_MASK);

		ret = pmic_reg_write(dev->parent, adr, ret);
		if (ret)
			return ret;
	}

	return 0;
}

static int lp873x_ldo_volt2hex(int uV)
{
	if (uV > LP873X_LDO_VOLT_MAX)
		return -EINVAL;

	return (uV - 800000) / 100000;
}

static int lp873x_ldo_hex2volt(int hex)
{
	if (hex > LP873X_LDO_VOLT_MAX_HEX)
		return -EINVAL;

	if (!hex)
		return 0;

	return (hex * 100000) + 800000;
}

static int lp873x_ldo_val(struct udevice *dev, int op, int *uV)
{
	unsigned int hex, adr;
	int ret;

	struct dm_regulator_uclass_platdata *uc_pdata;

	if (op == PMIC_OP_GET)
		*uV = 0;

	uc_pdata = dev_get_uclass_platdata(dev);

	adr = uc_pdata->volt_reg;

	ret = pmic_reg_read(dev->parent, adr);
	if (ret < 0)
		return ret;

	if (op == PMIC_OP_GET) {
		ret &= LP873X_LDO_VOLT_MASK;
		ret = lp873x_ldo_hex2volt(ret);
		if (ret < 0)
			return ret;
		*uV = ret;
		return 0;
	}

	hex = lp873x_ldo_volt2hex(*uV);
	if (hex < 0)
		return hex;

	ret &= ~LP873X_LDO_VOLT_MASK;
	ret |= hex;
	if (*uV > 1650000)
		ret |= 0x80;
	ret = pmic_reg_write(dev->parent, adr, ret);

	return ret;
}

static int lp873x_ldo_probe(struct udevice *dev)
{
	struct dm_regulator_uclass_platdata *uc_pdata;

	uc_pdata = dev_get_uclass_platdata(dev);
	uc_pdata->type = REGULATOR_TYPE_LDO;

	int idx = dev->driver_data;
	if (idx >= LP873X_LDO_NUM) {
		printf("Wrong ID for regulator\n");
		return -1;
	}

	uc_pdata->ctrl_reg = lp873x_ldo_ctrl[idx];
	uc_pdata->volt_reg = lp873x_ldo_volt[idx];

	return 0;
}

static int ldo_get_value(struct udevice *dev)
{
	int uV;
	int ret;

	ret = lp873x_ldo_val(dev, PMIC_OP_GET, &uV);
	if (ret)
		return ret;

	return uV;
}

static int ldo_set_value(struct udevice *dev, int uV)
{
	return lp873x_ldo_val(dev, PMIC_OP_SET, &uV);
}

static bool ldo_get_enable(struct udevice *dev)
{
	bool enable = false;
	int ret;

	ret = lp873x_ldo_enable(dev, PMIC_OP_GET, &enable);
	if (ret)
		return ret;

	return enable;
}

static int ldo_set_enable(struct udevice *dev, bool enable)
{
	return lp873x_ldo_enable(dev, PMIC_OP_SET, &enable);
}

static int lp873x_buck_probe(struct udevice *dev)
{
	struct dm_regulator_uclass_platdata *uc_pdata;
	int idx;

	uc_pdata = dev_get_uclass_platdata(dev);
	uc_pdata->type = REGULATOR_TYPE_BUCK;

	idx = dev->driver_data;
	if (idx >= LP873X_BUCK_NUM) {
		printf("Wrong ID for regulator\n");
		return -1;
	}

	uc_pdata->ctrl_reg = lp873x_buck_ctrl[idx];
	uc_pdata->volt_reg = lp873x_buck_volt[idx];

	return 0;
}

static int buck_get_value(struct udevice *dev)
{
	int uV;
	int ret;

	ret = lp873x_buck_val(dev, PMIC_OP_GET, &uV);
	if (ret)
		return ret;

	return uV;
}

static int buck_set_value(struct udevice *dev, int uV)
{
	return lp873x_buck_val(dev, PMIC_OP_SET, &uV);
}

static bool buck_get_enable(struct udevice *dev)
{
	bool enable = false;
	int ret;


	ret = lp873x_buck_enable(dev, PMIC_OP_GET, &enable);
	if (ret)
		return ret;

	return enable;
}

static int buck_set_enable(struct udevice *dev, bool enable)
{
	return lp873x_buck_enable(dev, PMIC_OP_SET, &enable);
}

static const struct dm_regulator_ops lp873x_ldo_ops = {
	.get_value  = ldo_get_value,
	.set_value  = ldo_set_value,
	.get_enable = ldo_get_enable,
	.set_enable = ldo_set_enable,
};

U_BOOT_DRIVER(lp873x_ldo) = {
	.name = LP873X_LDO_DRIVER,
	.id = UCLASS_REGULATOR,
	.ops = &lp873x_ldo_ops,
	.probe = lp873x_ldo_probe,
};

static const struct dm_regulator_ops lp873x_buck_ops = {
	.get_value  = buck_get_value,
	.set_value  = buck_set_value,
	.get_enable = buck_get_enable,
	.set_enable = buck_set_enable,
};

U_BOOT_DRIVER(lp873x_buck) = {
	.name = LP873X_BUCK_DRIVER,
	.id = UCLASS_REGULATOR,
	.ops = &lp873x_buck_ops,
	.probe = lp873x_buck_probe,
};
