/*
 * Copyright (C) 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 *
 * Based on Rockchip's drivers/power/pmic/pmic_act8846.c:
 * Copyright (C) 2012 rockchips
 * zyw <zyw@rock-chips.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <power/act8846_pmic.h>
#include <power/pmic.h>
#include <power/regulator.h>

static const u16 voltage_map[] = {
	600, 625, 650, 675, 700, 725, 750, 775,
	800, 825, 850, 875, 900, 925, 950, 975,
	1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175,
	1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550,
	1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950,
	2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350,
	2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100,
	3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900,
};

enum {
	REG_SYS0,
	REG_SYS1,
	REG1_VOL	= 0x10,
	REG1_CTL	= 0X11,
	REG2_VOL0	= 0x20,
	REG2_VOL1,
	REG2_CTL,
	REG3_VOL0	= 0x30,
	REG3_VOL1,
	REG3_CTL,
	REG4_VOL0	= 0x40,
	REG4_VOL1,
	REG4_CTL,
	REG5_VOL	= 0x50,
	REG5_CTL,
	REG6_VOL	= 0X58,
	REG6_CTL,
	REG7_VOL	= 0x60,
	REG7_CTL,
	REG8_VOL	= 0x68,
	REG8_CTL,
	REG9_VOL	= 0x70,
	REG9_CTL,
	REG10_VOL	= 0x80,
	REG10_CTL,
	REG11_VOL	= 0x90,
	REG11_CTL,
	REG12_VOL	= 0xa0,
	REG12_CTL,
	REG13		= 0xb1,
};

static const u8 addr_vol[] = {
	0, REG1_VOL, REG2_VOL0, REG3_VOL0, REG4_VOL0,
	REG5_VOL, REG6_VOL, REG7_VOL, REG8_VOL, REG9_VOL,
	REG10_VOL, REG11_VOL, REG12_VOL,
};

static const u8 addr_ctl[] = {
	0, REG1_CTL, REG2_CTL, REG3_CTL, REG4_CTL,
	REG5_CTL, REG6_CTL, REG7_CTL, REG8_CTL, REG9_CTL,
	REG10_CTL, REG11_CTL, REG12_CTL,
};

static int check_volt_table(const u16 *volt_table, int uvolt)
{
	int i;

	for (i = VOL_MIN_IDX; i < VOL_MAX_IDX; i++) {
		if (uvolt <= (volt_table[i] * 1000))
			return i;
	}
	return -EINVAL;
}

static int reg_get_value(struct udevice *dev)
{
	int reg = dev->driver_data;
	int ret;

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

	return voltage_map[ret & LDO_VOL_MASK] * 1000;
}

static int reg_set_value(struct udevice *dev, int uvolt)
{
	int reg = dev->driver_data;
	int val;

	val = check_volt_table(voltage_map, uvolt);
	if (val < 0)
		return val;

	return pmic_clrsetbits(dev->parent, addr_vol[reg], LDO_VOL_MASK, val);
}

static int reg_set_enable(struct udevice *dev, bool enable)
{
	int reg = dev->driver_data;

	return pmic_clrsetbits(dev->parent, addr_ctl[reg], LDO_EN_MASK,
			       enable ? LDO_EN_MASK : 0);
}

static bool reg_get_enable(struct udevice *dev)
{
	int reg = dev->driver_data;
	int ret;

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

	return ret & LDO_EN_MASK ? true : false;
}

static int act8846_reg_probe(struct udevice *dev)
{
	struct dm_regulator_uclass_platdata *uc_pdata;
	int reg = dev->driver_data;

	uc_pdata = dev_get_uclass_platdata(dev);

	uc_pdata->type = reg <= 4 ? REGULATOR_TYPE_BUCK : REGULATOR_TYPE_LDO;
	uc_pdata->mode_count = 0;

	return 0;
}

static const struct dm_regulator_ops act8846_reg_ops = {
	.get_value  = reg_get_value,
	.set_value  = reg_set_value,
	.get_enable = reg_get_enable,
	.set_enable = reg_set_enable,
};

U_BOOT_DRIVER(act8846_buck) = {
	.name = "act8846_reg",
	.id = UCLASS_REGULATOR,
	.ops = &act8846_reg_ops,
	.probe = act8846_reg_probe,
};
