// SPDX-License-Identifier:     GPL-2.0+
/*
 * (C) 2018 Theobroma Systems Design und Consulting GmbH
 */

#include <common.h>
#include <bitfield.h>
#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <log.h>
#include <asm/gpio.h>
#include <linux/bitops.h>
#include <power/fan53555.h>
#include <power/pmic.h>
#include <power/regulator.h>

/**
 * struct ic_types - definition of fan53555-family devices
 *
 * @die_id: Identifies the DIE_ID (lower nibble of the ID1 register)
 * @die_rev: Identifies the DIE_REV (lower nibble of the ID2 register)
 * @vsel_min: starting voltage (step 0) in uV
 * @vsel_step: increment of the voltage in uV
 *
 * The voltage ramp (i.e. minimum voltage and step) is selected from the
 * combination of 2 nibbles: DIE_ID and DIE_REV.
 *
 * See http://www.onsemi.com/pub/Collateral/FAN53555-D.pdf for details.
 */
static const struct {
	unsigned int vendor;
	u8 die_id;
	u8 die_rev;
	bool check_rev;
	u32 vsel_min;
	u32 vsel_step;
} ic_types[] = {
	/* Option 00 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x0, 0x3, true,  600000, 10000 },
	/* Option 13 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x0, 0xf, true,  800000, 10000 },
	/* Option 23 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x0, 0xc, true,  600000, 12500 },
	/* Option 01 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x1, 0x3, true,  600000, 10000 },
	/* Option 03 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x3, 0x3, true,  600000, 10000 },
	/* Option 04 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x4, 0xf, true,  603000, 12826 },
	/* Option 05 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x5, 0x3, true,  600000, 10000 },
	/* Option 08 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x8, 0x1, true,  600000, 10000 },
	/* Option 08 */
	{ FAN53555_VENDOR_FAIRCHILD, 0x8, 0xf, true,  600000, 10000 },
	/* Option 09 */
	{ FAN53555_VENDOR_FAIRCHILD, 0xc, 0xf, true,  603000, 12826 },
	/* SYL82X */
	{ FAN53555_VENDOR_SILERGY,   0x8, 0x0, false, 712500, 12500 },
	/* SYL83X */
	{ FAN53555_VENDOR_SILERGY,   0x9, 0x0, false, 712500, 12500 },
};

/* I2C-accessible byte-sized registers */
enum {
	/* Voltage setting */
	FAN53555_VSEL0 = 0x00,
	FAN53555_VSEL1,
	/* Control register */
	FAN53555_CONTROL,
	/* IC Type */
	FAN53555_ID1,
	/* IC mask version */
	FAN53555_ID2,
	/* Monitor register */
	FAN53555_MONITOR,
};

struct fan53555_plat {
	/* Voltage setting register */
	unsigned int vol_reg;
	unsigned int sleep_reg;

};

struct fan53555_priv {
	/* IC Vendor */
	unsigned int vendor;
	/* IC Type and Rev */
	unsigned int die_id;
	unsigned int die_rev;
	/* Voltage range and step(linear) */
	unsigned int vsel_min;
	unsigned int vsel_step;
	/* Voltage slew rate limiting */
	unsigned int slew_rate;
	/* Sleep voltage cache */
	unsigned int sleep_vol_cache;
};

static int fan53555_regulator_of_to_plat(struct udevice *dev)
{
	struct fan53555_plat *dev_pdata = dev_get_plat(dev);
	struct dm_regulator_uclass_plat *uc_pdata =
		dev_get_uclass_plat(dev);
	u32 sleep_vsel;

	/* This is a buck regulator */
	uc_pdata->type = REGULATOR_TYPE_BUCK;

	sleep_vsel = dev_read_u32_default(dev, "fcs,suspend-voltage-selector",
					  FAN53555_VSEL1);

	/*
	 * Depending on the device-tree settings, the 'normal mode'
	 * voltage is either controlled by VSEL0 or VSEL1.
	 */
	switch (sleep_vsel) {
	case FAN53555_VSEL0:
		dev_pdata->sleep_reg = FAN53555_VSEL0;
		dev_pdata->vol_reg = FAN53555_VSEL1;
		break;
	case FAN53555_VSEL1:
		dev_pdata->sleep_reg = FAN53555_VSEL1;
		dev_pdata->vol_reg = FAN53555_VSEL0;
		break;
	default:
		pr_err("%s: invalid vsel id %d\n", dev->name, sleep_vsel);
		return -EINVAL;
	}

	return 0;
}

static int fan53555_regulator_get_value(struct udevice *dev)
{
	struct fan53555_plat *pdata = dev_get_plat(dev);
	struct fan53555_priv *priv = dev_get_priv(dev);
	int reg;
	int voltage;

	/* We only support a single voltage selector (i.e. 'normal' mode). */
	reg = pmic_reg_read(dev->parent, pdata->vol_reg);
	if (reg < 0)
		return reg;
	voltage = priv->vsel_min + (reg & 0x3f) * priv->vsel_step;

	debug("%s: %d uV\n", __func__, voltage);
	return voltage;
}

static int fan53555_regulator_set_value(struct udevice *dev, int uV)
{
	struct fan53555_plat *pdata = dev_get_plat(dev);
	struct fan53555_priv *priv = dev_get_priv(dev);
	u8 vol;

	vol = (uV - priv->vsel_min) / priv->vsel_step;
	debug("%s: uV=%d; writing volume %d: %02x\n",
	      __func__, uV, pdata->vol_reg, vol);

	return pmic_clrsetbits(dev->parent, pdata->vol_reg, GENMASK(6, 0), vol);
}

static int fan53555_voltages_setup(struct udevice *dev)
{
	struct fan53555_priv *priv = dev_get_priv(dev);
	int i;

	/* Init voltage range and step */
	for (i = 0; i < ARRAY_SIZE(ic_types); ++i) {
		if (ic_types[i].vendor != priv->vendor)
			continue;

		if (ic_types[i].die_id != priv->die_id)
			continue;

		if (ic_types[i].check_rev &&
		    ic_types[i].die_rev != priv->die_rev)
			continue;

		priv->vsel_min = ic_types[i].vsel_min;
		priv->vsel_step = ic_types[i].vsel_step;

		return 0;
	}

	pr_err("%s: %s: die id %d rev %d not supported!\n",
	       dev->name, __func__, priv->die_id, priv->die_rev);
	return -EINVAL;
}

enum {
	DIE_ID_SHIFT = 0,
	DIE_ID_WIDTH = 4,
	DIE_REV_SHIFT = 0,
	DIE_REV_WIDTH = 4,
};

static int fan53555_probe(struct udevice *dev)
{
	struct fan53555_priv *priv = dev_get_priv(dev);
	int ID1, ID2;

	debug("%s\n", __func__);

	/* read chip ID1 and ID2 (two registers, starting at ID1) */
	ID1 = pmic_reg_read(dev->parent, FAN53555_ID1);
	if (ID1 < 0)
		return ID1;

	ID2 = pmic_reg_read(dev->parent, FAN53555_ID2);
	if (ID2 < 0)
		return ID2;

	/* extract vendor, die_id and die_rev */
	priv->vendor = dev->driver_data;
	priv->die_id = ID1 & GENMASK(3, 0);
	priv->die_rev = ID2 & GENMASK(3, 0);

	if (fan53555_voltages_setup(dev) < 0)
		return -ENODATA;

	debug("%s: FAN53555 option %d rev %d detected\n",
	      __func__, priv->die_id, priv->die_rev);

	return 0;
}

static const struct dm_regulator_ops fan53555_regulator_ops = {
	.get_value	= fan53555_regulator_get_value,
	.set_value	= fan53555_regulator_set_value,
};

U_BOOT_DRIVER(fan53555_regulator) = {
	.name = "fan53555_regulator",
	.id = UCLASS_REGULATOR,
	.ops = &fan53555_regulator_ops,
	.of_to_plat = fan53555_regulator_of_to_plat,
	.plat_auto	= sizeof(struct fan53555_plat),
	.priv_auto	= sizeof(struct fan53555_priv),
	.probe = fan53555_probe,
};
