/*
 *  Copyright (C) 2012-2015 Samsung Electronics
 *
 *  Rajeshwari Shinde <rajeshwari.s@samsung.com>
 *  Przemyslaw Marczak <p.marczak@samsung.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/max77686_pmic.h>

#define MODE(_id, _val, _name) { \
	.id = _id, \
	.register_value = _val, \
	.name = _name, \
}

/* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
	MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
};

/* LDO: 2,6,7,8,10,11,12,14,15,16 */
static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
	MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
};

/* Buck: 1 */
static struct dm_regulator_mode max77686_buck_mode_standby[] = {
	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
};

/* Buck: 2,3,4 */
static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
	MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
};

/* Buck: 5,6,7,8,9 */
static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
};

static const char max77686_buck_ctrl[] = {
	0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
};

static const char max77686_buck_out[] = {
	0xff, 0x11, 0x14, 0x1e, 0x28, 0x31, 0x33, 0x35, 0x37, 0x39
};

static int max77686_buck_volt2hex(int buck, int uV)
{
	int hex = 0;
	int hex_max = 0;

	switch (buck) {
	case 2:
	case 3:
	case 4:
		/* hex = (uV - 600000) / 12500; */
		hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
		break;
	default:
		/*
		 * hex = (uV - 750000) / 50000. We assume that dynamic voltage
		 * scaling via GPIOs is not enabled and don't support that.
		 * If this is enabled then the driver will need to take that
		 * into account and check different registers depending on
		 * the current setting. See the datasheet for details.
		 */
		hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
		break;
	}

	if (hex >= 0 && hex <= hex_max)
		return hex;

	pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
	return -EINVAL;
}

static int max77686_buck_hex2volt(int buck, int hex)
{
	unsigned uV = 0;
	int hex_max = 0;

	if (hex < 0)
		goto bad_hex;

	switch (buck) {
	case 2:
	case 3:
	case 4:
		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
		if (hex > hex_max)
			goto bad_hex;

		/* uV = hex * 12500 + 600000; */
		uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
		break;
	default:
		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
		if (hex > hex_max)
			goto bad_hex;

		/* uV = hex * 50000 + 750000; */
		uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
		break;
	}

	return uV;

bad_hex:
	pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
	return -EINVAL;
}

static int max77686_ldo_volt2hex(int ldo, int uV)
{
	int hex = 0;

	switch (ldo) {
	case 1:
	case 2:
	case 6:
	case 7:
	case 8:
	case 15:
		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
		/* hex = (uV - 800000) / 25000; */
		break;
	default:
		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
		/* hex = (uV - 800000) / 50000; */
	}

	if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
		return hex;

	pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
	return -EINVAL;
}

static int max77686_ldo_hex2volt(int ldo, int hex)
{
	unsigned int uV = 0;

	if (hex > MAX77686_LDO_VOLT_MAX_HEX)
		goto bad_hex;

	switch (ldo) {
	case 1:
	case 2:
	case 6:
	case 7:
	case 8:
	case 15:
		/* uV = hex * 25000 + 800000; */
		uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
		break;
	default:
		/* uV = hex * 50000 + 800000; */
		uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
	}

	return uV;

bad_hex:
	pr_err("Value: %#x is wrong for ldo%d", hex, ldo);
	return -EINVAL;
}

static int max77686_ldo_hex2mode(int ldo, int hex)
{
	if (hex > MAX77686_LDO_MODE_MASK)
		return -EINVAL;

	switch (hex) {
	case MAX77686_LDO_MODE_OFF:
		return OPMODE_OFF;
	case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
		/* The same mode values but different meaning for each ldo */
		switch (ldo) {
		case 2:
		case 6:
		case 7:
		case 8:
		case 10:
		case 11:
		case 12:
		case 14:
		case 15:
		case 16:
			return OPMODE_STANDBY;
		default:
			return OPMODE_LPM;
		}
	case MAX77686_LDO_MODE_STANDBY_LPM:
		return OPMODE_STANDBY_LPM;
	case MAX77686_LDO_MODE_ON:
		return OPMODE_ON;
	default:
		return -EINVAL;
	}
}

static int max77686_buck_hex2mode(int buck, int hex)
{
	if (hex > MAX77686_BUCK_MODE_MASK)
		return -EINVAL;

	switch (hex) {
	case MAX77686_BUCK_MODE_OFF:
		return OPMODE_OFF;
	case MAX77686_BUCK_MODE_ON:
		return OPMODE_ON;
	case MAX77686_BUCK_MODE_STANDBY:
		switch (buck) {
		case 1:
		case 2:
		case 3:
		case 4:
			return OPMODE_STANDBY;
		default:
			return -EINVAL;
		}
	case MAX77686_BUCK_MODE_LPM:
		switch (buck) {
		case 2:
		case 3:
		case 4:
			return OPMODE_LPM;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
{
	int ret = -EINVAL;

	if (buck < 1 || buck > MAX77686_BUCK_NUM)
		return ret;

	switch (buck) {
	case 1:
		*modesp = max77686_buck_mode_standby;
		ret = ARRAY_SIZE(max77686_buck_mode_standby);
		break;
	case 2:
	case 3:
	case 4:
		*modesp = max77686_buck_mode_lpm;
		ret = ARRAY_SIZE(max77686_buck_mode_lpm);
		break;
	default:
		*modesp = max77686_buck_mode_onoff;
		ret = ARRAY_SIZE(max77686_buck_mode_onoff);
	}

	return ret;
}

static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
				struct udevice *dev)
{
	int ret = -EINVAL;

	if (ldo < 1 || ldo > MAX77686_LDO_NUM)
		return ret;

	switch (ldo) {
	case 2:
	case 6:
	case 7:
	case 8:
	case 10:
	case 11:
	case 12:
	case 14:
	case 15:
	case 16:
		*modesp = max77686_ldo_mode_standby2;
		ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
		break;
	default:
		*modesp = max77686_ldo_mode_standby1;
		ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
	}

	return ret;
}

static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
{
	unsigned int adr;
	unsigned char val;
	int hex, ldo, ret;

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

	ldo = dev->driver_data;
	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
		pr_err("Wrong ldo number: %d", ldo);
		return -EINVAL;
	}

	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;

	ret = pmic_read(dev->parent, adr, &val, 1);
	if (ret)
		return ret;

	if (op == PMIC_OP_GET) {
		val &= MAX77686_LDO_VOLT_MASK;
		ret = max77686_ldo_hex2volt(ldo, val);
		if (ret < 0)
			return ret;
		*uV = ret;
		return 0;
	}

	hex = max77686_ldo_volt2hex(ldo, *uV);
	if (hex < 0)
		return hex;

	val &= ~MAX77686_LDO_VOLT_MASK;
	val |= hex;
	ret = pmic_write(dev->parent, adr, &val, 1);

	return ret;
}

static int max77686_buck_val(struct udevice *dev, int op, int *uV)
{
	unsigned int mask, adr;
	unsigned char val;
	int hex, buck, ret;

	buck = dev->driver_data;
	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
		pr_err("Wrong buck number: %d", buck);
		return -EINVAL;
	}

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

	/* &buck_out = ctrl + 1 */
	adr = max77686_buck_out[buck];

	/* mask */
	switch (buck) {
	case 2:
	case 3:
	case 4:
		mask = MAX77686_BUCK234_VOLT_MASK;
		break;
	default:
		mask = MAX77686_BUCK_VOLT_MASK;
		break;
	}

	ret = pmic_read(dev->parent, adr, &val, 1);
	if (ret)
		return ret;

	if (op == PMIC_OP_GET) {
		val &= mask;
		ret = max77686_buck_hex2volt(buck, val);
		if (ret < 0)
			return ret;
		*uV = ret;
		return 0;
	}

	hex = max77686_buck_volt2hex(buck, *uV);
	if (hex < 0)
		return hex;

	val &= ~mask;
	val |= hex;
	ret = pmic_write(dev->parent, adr, &val, 1);

	return ret;
}

static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
{
	unsigned int adr, mode;
	unsigned char val;
	int ldo, ret;

	if (op == PMIC_OP_GET)
		*opmode = -EINVAL;

	ldo = dev->driver_data;
	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
		pr_err("Wrong ldo number: %d", ldo);
		return -EINVAL;
	}

	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;

	ret = pmic_read(dev->parent, adr, &val, 1);
	if (ret)
		return ret;

	if (op == PMIC_OP_GET) {
		val &= MAX77686_LDO_MODE_MASK;
		ret = max77686_ldo_hex2mode(ldo, val);
		if (ret < 0)
			return ret;
		*opmode = ret;
		return 0;
	}

	/* mode */
	switch (*opmode) {
	case OPMODE_OFF:
		mode = MAX77686_LDO_MODE_OFF;
		break;
	case OPMODE_LPM:
		switch (ldo) {
		case 2:
		case 6:
		case 7:
		case 8:
		case 10:
		case 11:
		case 12:
		case 14:
		case 15:
		case 16:
			return -EINVAL;
		default:
			mode = MAX77686_LDO_MODE_LPM;
		}
		break;
	case OPMODE_STANDBY:
		switch (ldo) {
		case 2:
		case 6:
		case 7:
		case 8:
		case 10:
		case 11:
		case 12:
		case 14:
		case 15:
		case 16:
			mode = MAX77686_LDO_MODE_STANDBY;
			break;
		default:
			return -EINVAL;
		}
		break;
	case OPMODE_STANDBY_LPM:
		mode = MAX77686_LDO_MODE_STANDBY_LPM;
		break;
	case OPMODE_ON:
		mode = MAX77686_LDO_MODE_ON;
		break;
	default:
		mode = 0xff;
	}

	if (mode == 0xff) {
		pr_err("Wrong mode: %d for ldo%d", *opmode, ldo);
		return -EINVAL;
	}

	val &= ~MAX77686_LDO_MODE_MASK;
	val |= mode;
	ret = pmic_write(dev->parent, adr, &val, 1);

	return ret;
}

static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
{
	int ret, on_off;

	if (op == PMIC_OP_GET) {
		ret = max77686_ldo_mode(dev, op, &on_off);
		if (ret)
			return ret;

		switch (on_off) {
		case OPMODE_OFF:
			*enable = false;
			break;
		case OPMODE_ON:
			*enable = true;
			break;
		default:
			return -EINVAL;
		}
	} else if (op == PMIC_OP_SET) {
		if (*enable)
			on_off = OPMODE_ON;
		else
			on_off = OPMODE_OFF;

		ret = max77686_ldo_mode(dev, op, &on_off);
		if (ret)
			return ret;
	}

	return 0;
}

static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
{
	unsigned int mask, adr, mode, mode_shift;
	unsigned char val;
	int buck, ret;

	buck = dev->driver_data;
	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
		pr_err("Wrong buck number: %d", buck);
		return -EINVAL;
	}

	adr = max77686_buck_ctrl[buck];

	/* mask */
	switch (buck) {
	case 2:
	case 3:
	case 4:
		mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
		break;
	default:
		mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
	}

	mask = MAX77686_BUCK_MODE_MASK << mode_shift;

	ret = pmic_read(dev->parent, adr, &val, 1);
	if (ret)
		return ret;

	if (op == PMIC_OP_GET) {
		val &= mask;
		val >>= mode_shift;
		ret = max77686_buck_hex2mode(buck, val);
		if (ret < 0)
			return ret;
		*opmode = ret;
		return 0;
	}

	/* mode */
	switch (*opmode) {
	case OPMODE_OFF:
		mode = MAX77686_BUCK_MODE_OFF;
		break;
	case OPMODE_STANDBY:
		switch (buck) {
		case 1:
		case 2:
		case 3:
		case 4:
			mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
			break;
		default:
			mode = 0xff;
		}
		break;
	case OPMODE_LPM:
		switch (buck) {
		case 2:
		case 3:
		case 4:
			mode = MAX77686_BUCK_MODE_LPM << mode_shift;
			break;
		default:
			mode = 0xff;
		}
		break;
	case OPMODE_ON:
		mode = MAX77686_BUCK_MODE_ON << mode_shift;
		break;
	default:
		mode = 0xff;
	}

	if (mode == 0xff) {
		pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
		return -EINVAL;
	}

	val &= ~mask;
	val |= mode;
	ret = pmic_write(dev->parent, adr, &val, 1);

	return ret;
}

static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
{
	int ret, on_off;

	if (op == PMIC_OP_GET) {
		ret = max77686_buck_mode(dev, op, &on_off);
		if (ret)
			return ret;

		switch (on_off) {
		case OPMODE_OFF:
			*enable = false;
			break;
		case OPMODE_ON:
			*enable = true;
			break;
		default:
			return -EINVAL;
		}
	} else if (op == PMIC_OP_SET) {
		if (*enable)
			on_off = OPMODE_ON;
		else
			on_off = OPMODE_OFF;

		ret = max77686_buck_mode(dev, op, &on_off);
		if (ret)
			return ret;
	}

	return 0;
}

static int max77686_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;
	uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
						  &uc_pdata->mode, dev);

	return 0;
}

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

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

	return uV;
}

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

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

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

	return enable;
}

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

static int ldo_get_mode(struct udevice *dev)
{
	int mode;
	int ret;

	ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
	if (ret)
		return ret;

	return mode;
}

static int ldo_set_mode(struct udevice *dev, int mode)
{
	return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
}

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

	uc_pdata = dev_get_uclass_platdata(dev);

	uc_pdata->type = REGULATOR_TYPE_BUCK;
	uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
						   &uc_pdata->mode);

	return 0;
}

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

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

	return uV;
}

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

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

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

	return enable;
}

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

static int buck_get_mode(struct udevice *dev)
{
	int mode;
	int ret;

	ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
	if (ret)
		return ret;

	return mode;
}

static int buck_set_mode(struct udevice *dev, int mode)
{
	return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
}

static const struct dm_regulator_ops max77686_ldo_ops = {
	.get_value  = ldo_get_value,
	.set_value  = ldo_set_value,
	.get_enable = ldo_get_enable,
	.set_enable = ldo_set_enable,
	.get_mode   = ldo_get_mode,
	.set_mode   = ldo_set_mode,
};

U_BOOT_DRIVER(max77686_ldo) = {
	.name = MAX77686_LDO_DRIVER,
	.id = UCLASS_REGULATOR,
	.ops = &max77686_ldo_ops,
	.probe = max77686_ldo_probe,
};

static const struct dm_regulator_ops max77686_buck_ops = {
	.get_value  = buck_get_value,
	.set_value  = buck_set_value,
	.get_enable = buck_get_enable,
	.set_enable = buck_set_enable,
	.get_mode   = buck_get_mode,
	.set_mode   = buck_set_mode,
};

U_BOOT_DRIVER(max77686_buck) = {
	.name = MAX77686_BUCK_DRIVER,
	.id = UCLASS_REGULATOR,
	.ops = &max77686_buck_ops,
	.probe = max77686_buck_probe,
};
