// SPDX-License-Identifier: GPL-2.0
//
// Device driver for regulators in Hisi IC
//
// Copyright (c) 2013 Linaro Ltd.
// Copyright (c) 2011 HiSilicon Ltd.
// Copyright (c) 2020-2021 Huawei Technologies Co., Ltd.
//
// Guodong Xu <guodong.xu@linaro.org>

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/spmi.h>

struct hi6421_spmi_reg_priv {
	/* Serialize regulator enable logic */
	struct mutex enable_mutex;
};

struct hi6421_spmi_reg_info {
	struct regulator_desc	desc;
	u8			eco_mode_mask;
	u32			eco_uA;
};

static const unsigned int range_1v5_to_2v0[] = {
	1500000, 1550000, 1600000, 1650000,
	1700000, 1725000, 1750000, 1775000,
	1800000, 1825000, 1850000, 1875000,
	1900000, 1925000, 1950000, 2000000
};

static const unsigned int range_1v725_to_1v9[] = {
	1725000, 1750000, 1775000, 1800000,
	1825000, 1850000, 1875000, 1900000
};

static const unsigned int range_1v75_to_3v3[] = {
	1750000, 1800000, 1825000, 2800000,
	2850000, 2950000, 3000000, 3300000
};

static const unsigned int range_1v8_to_3v0[] = {
	1800000, 1850000, 2400000, 2600000,
	2700000, 2850000, 2950000, 3000000
};

static const unsigned int range_2v5_to_3v3[] = {
	2500000, 2600000, 2700000, 2800000,
	3000000, 3100000, 3200000, 3300000
};

static const unsigned int range_2v6_to_3v3[] = {
	2600000, 2700000, 2800000, 2900000,
	3000000, 3100000, 3200000, 3300000
};

/**
 * HI6421V600_LDO() - specify a LDO power line
 * @_id: LDO id name string
 * @vtable: voltage table
 * @ereg: enable register
 * @emask: enable mask
 * @vreg: voltage select register
 * @odelay: off/on delay time in uS
 * @etime: enable time in uS
 * @ecomask: eco mode mask
 * @ecoamp: eco mode load uppler limit in uA
 */
#define HI6421V600_LDO(_id, vtable, ereg, emask, vreg,			       \
		       odelay, etime, ecomask, ecoamp)			       \
	[hi6421v600_##_id] = {						       \
		.desc = {						       \
			.name		= #_id,				       \
			.of_match        = of_match_ptr(#_id),		       \
			.regulators_node = of_match_ptr("regulators"),	       \
			.ops		= &hi6421_spmi_ldo_rops,	       \
			.type		= REGULATOR_VOLTAGE,		       \
			.id		= hi6421v600_##_id,		       \
			.owner		= THIS_MODULE,			       \
			.volt_table	= vtable,			       \
			.n_voltages	= ARRAY_SIZE(vtable),		       \
			.vsel_mask	= ARRAY_SIZE(vtable) - 1,	       \
			.vsel_reg	= vreg,				       \
			.enable_reg	= ereg,				       \
			.enable_mask	= emask,			       \
			.enable_time	= etime,			       \
			.ramp_delay	= etime,			       \
			.off_on_delay	= odelay,			       \
		},							       \
		.eco_mode_mask		= ecomask,			       \
		.eco_uA			= ecoamp,			       \
	}

static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
{
	struct hi6421_spmi_reg_priv *priv = rdev_get_drvdata(rdev);
	int ret;

	/* cannot enable more than one regulator at one time */
	mutex_lock(&priv->enable_mutex);

	ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				 rdev->desc->enable_mask,
				 rdev->desc->enable_mask);

	/* Avoid powering up multiple devices at the same time */
	usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60);

	mutex_unlock(&priv->enable_mutex);

	return ret;
}

static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
{
	struct hi6421_spmi_reg_info *sreg;
	unsigned int reg_val;

	sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);
	regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);

	if (reg_val & sreg->eco_mode_mask)
		return REGULATOR_MODE_IDLE;

	return REGULATOR_MODE_NORMAL;
}

static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
					  unsigned int mode)
{
	struct hi6421_spmi_reg_info *sreg;
	unsigned int val;

	sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);
	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val = 0;
		break;
	case REGULATOR_MODE_IDLE:
		if (!sreg->eco_mode_mask)
			return -EINVAL;

		val = sreg->eco_mode_mask;
		break;
	default:
		return -EINVAL;
	}

	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				  sreg->eco_mode_mask, val);
}

static unsigned int
hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
				       int input_uV, int output_uV,
				       int load_uA)
{
	struct hi6421_spmi_reg_info *sreg;

	sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);

	if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA))
		return REGULATOR_MODE_NORMAL;

	return REGULATOR_MODE_IDLE;
}

static const struct regulator_ops hi6421_spmi_ldo_rops = {
	.is_enabled = regulator_is_enabled_regmap,
	.enable = hi6421_spmi_regulator_enable,
	.disable = regulator_disable_regmap,
	.list_voltage = regulator_list_voltage_table,
	.map_voltage = regulator_map_voltage_ascend,
	.get_voltage_sel = regulator_get_voltage_sel_regmap,
	.set_voltage_sel = regulator_set_voltage_sel_regmap,
	.get_mode = hi6421_spmi_regulator_get_mode,
	.set_mode = hi6421_spmi_regulator_set_mode,
	.get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
};

/* HI6421v600 regulators with known registers */
enum hi6421_spmi_regulator_id {
	hi6421v600_ldo3,
	hi6421v600_ldo4,
	hi6421v600_ldo9,
	hi6421v600_ldo15,
	hi6421v600_ldo16,
	hi6421v600_ldo17,
	hi6421v600_ldo33,
	hi6421v600_ldo34,
};

static struct hi6421_spmi_reg_info regulator_info[] = {
	HI6421V600_LDO(ldo3, range_1v5_to_2v0,
		       0x16, 0x01, 0x51,
		       20000, 120,
		       0, 0),
	HI6421V600_LDO(ldo4, range_1v725_to_1v9,
		       0x17, 0x01, 0x52,
		       20000, 120,
		       0x10, 10000),
	HI6421V600_LDO(ldo9, range_1v75_to_3v3,
		       0x1c, 0x01, 0x57,
		       20000, 360,
		       0x10, 10000),
	HI6421V600_LDO(ldo15, range_1v8_to_3v0,
		       0x21, 0x01, 0x5c,
		       20000, 360,
		       0x10, 10000),
	HI6421V600_LDO(ldo16, range_1v8_to_3v0,
		       0x22, 0x01, 0x5d,
		       20000, 360,
		       0x10, 10000),
	HI6421V600_LDO(ldo17, range_2v5_to_3v3,
		       0x23, 0x01, 0x5e,
		       20000, 120,
		       0x10, 10000),
	HI6421V600_LDO(ldo33, range_2v5_to_3v3,
		       0x32, 0x01, 0x6d,
		       20000, 120,
		       0, 0),
	HI6421V600_LDO(ldo34, range_2v6_to_3v3,
		       0x33, 0x01, 0x6e,
		       20000, 120,
		       0, 0),
};

static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
{
	struct device *pmic_dev = pdev->dev.parent;
	struct regulator_config config = { };
	struct hi6421_spmi_reg_priv *priv;
	struct hi6421_spmi_reg_info *info;
	struct device *dev = &pdev->dev;
	struct regmap *regmap;
	struct regulator_dev *rdev;
	int i;

	/*
	 * This driver is meant to be called by hi6421-spmi-core,
	 * which should first set drvdata. If this doesn't happen, hit
	 * a warn on and return.
	 */
	regmap = dev_get_drvdata(pmic_dev);
	if (WARN_ON(!regmap))
		return -ENODEV;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	mutex_init(&priv->enable_mutex);

	for (i = 0; i < ARRAY_SIZE(regulator_info); i++) {
		info = &regulator_info[i];

		config.dev = pdev->dev.parent;
		config.driver_data = priv;
		config.regmap = regmap;

		rdev = devm_regulator_register(dev, &info->desc, &config);
		if (IS_ERR(rdev)) {
			dev_err(dev, "failed to register %s\n",
				info->desc.name);
			return PTR_ERR(rdev);
		}
	}

	return 0;
}

static const struct platform_device_id hi6421_spmi_regulator_table[] = {
	{ .name = "hi6421v600-regulator" },
	{},
};
MODULE_DEVICE_TABLE(platform, hi6421_spmi_regulator_table);

static struct platform_driver hi6421_spmi_regulator_driver = {
	.id_table = hi6421_spmi_regulator_table,
	.driver = {
		.name = "hi6421v600-regulator",
	},
	.probe	= hi6421_spmi_regulator_probe,
};
module_platform_driver(hi6421_spmi_regulator_driver);

MODULE_DESCRIPTION("Hi6421v600 SPMI regulator driver");
MODULE_LICENSE("GPL v2");

