/*
 * pbias-regulator.c
 *
 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
 * Author: Balaji T K <balajitk@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>

struct pbias_reg_info {
	u32 enable;
	u32 enable_mask;
	u32 disable_val;
	u32 vmode;
	unsigned int enable_time;
	char *name;
	const unsigned int *pbias_volt_table;
	int n_voltages;
};

struct pbias_regulator_data {
	struct regulator_desc desc;
	void __iomem *pbias_addr;
	struct regulator_dev *dev;
	struct regmap *syscon;
	const struct pbias_reg_info *info;
	int voltage;
};

struct pbias_of_data {
	unsigned int offset;
};

static const unsigned int pbias_volt_table_3_0V[] = {
	1800000,
	3000000
};

static const unsigned int pbias_volt_table_3_3V[] = {
	1800000,
	3300000
};

static const struct regulator_ops pbias_regulator_voltage_ops = {
	.list_voltage = regulator_list_voltage_table,
	.get_voltage_sel = regulator_get_voltage_sel_regmap,
	.set_voltage_sel = regulator_set_voltage_sel_regmap,
	.enable = regulator_enable_regmap,
	.disable = regulator_disable_regmap,
	.is_enabled = regulator_is_enabled_regmap,
};

static const struct pbias_reg_info pbias_mmc_omap2430 = {
	.enable = BIT(1),
	.enable_mask = BIT(1),
	.vmode = BIT(0),
	.disable_val = 0,
	.enable_time = 100,
	.pbias_volt_table = pbias_volt_table_3_0V,
	.n_voltages = 2,
	.name = "pbias_mmc_omap2430"
};

static const struct pbias_reg_info pbias_sim_omap3 = {
	.enable = BIT(9),
	.enable_mask = BIT(9),
	.vmode = BIT(8),
	.enable_time = 100,
	.pbias_volt_table = pbias_volt_table_3_0V,
	.n_voltages = 2,
	.name = "pbias_sim_omap3"
};

static const struct pbias_reg_info pbias_mmc_omap4 = {
	.enable = BIT(26) | BIT(22),
	.enable_mask = BIT(26) | BIT(25) | BIT(22),
	.disable_val = BIT(25),
	.vmode = BIT(21),
	.enable_time = 100,
	.pbias_volt_table = pbias_volt_table_3_0V,
	.n_voltages = 2,
	.name = "pbias_mmc_omap4"
};

static const struct pbias_reg_info pbias_mmc_omap5 = {
	.enable = BIT(27) | BIT(26),
	.enable_mask = BIT(27) | BIT(25) | BIT(26),
	.disable_val = BIT(25),
	.vmode = BIT(21),
	.enable_time = 100,
	.pbias_volt_table = pbias_volt_table_3_3V,
	.n_voltages = 2,
	.name = "pbias_mmc_omap5"
};

static struct of_regulator_match pbias_matches[] = {
	{ .name = "pbias_mmc_omap2430", .driver_data = (void *)&pbias_mmc_omap2430},
	{ .name = "pbias_sim_omap3", .driver_data = (void *)&pbias_sim_omap3},
	{ .name = "pbias_mmc_omap4", .driver_data = (void *)&pbias_mmc_omap4},
	{ .name = "pbias_mmc_omap5", .driver_data = (void *)&pbias_mmc_omap5},
};
#define PBIAS_NUM_REGS	ARRAY_SIZE(pbias_matches)

/* Offset from SCM general area (and syscon) base */

static const struct pbias_of_data pbias_of_data_omap2 = {
	.offset = 0x230,
};

static const struct pbias_of_data pbias_of_data_omap3 = {
	.offset = 0x2b0,
};

static const struct pbias_of_data pbias_of_data_omap4 = {
	.offset = 0x60,
};

static const struct pbias_of_data pbias_of_data_omap5 = {
	.offset = 0x60,
};

static const struct pbias_of_data pbias_of_data_dra7 = {
	.offset = 0xe00,
};

static const struct of_device_id pbias_of_match[] = {
	{ .compatible = "ti,pbias-omap", },
	{ .compatible = "ti,pbias-omap2", .data = &pbias_of_data_omap2, },
	{ .compatible = "ti,pbias-omap3", .data = &pbias_of_data_omap3, },
	{ .compatible = "ti,pbias-omap4", .data = &pbias_of_data_omap4, },
	{ .compatible = "ti,pbias-omap5", .data = &pbias_of_data_omap5, },
	{ .compatible = "ti,pbias-dra7", .data = &pbias_of_data_dra7, },
	{},
};
MODULE_DEVICE_TABLE(of, pbias_of_match);

static int pbias_regulator_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct pbias_regulator_data *drvdata;
	struct resource *res;
	struct regulator_config cfg = { };
	struct regmap *syscon;
	const struct pbias_reg_info *info;
	int ret = 0;
	int count, idx, data_idx = 0;
	const struct of_device_id *match;
	const struct pbias_of_data *data;
	unsigned int offset;

	count = of_regulator_match(&pdev->dev, np, pbias_matches,
						PBIAS_NUM_REGS);
	if (count < 0)
		return count;

	drvdata = devm_kcalloc(&pdev->dev,
			       count, sizeof(struct pbias_regulator_data),
			       GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	syscon = syscon_regmap_lookup_by_phandle(np, "syscon");
	if (IS_ERR(syscon))
		return PTR_ERR(syscon);

	match = of_match_device(of_match_ptr(pbias_of_match), &pdev->dev);
	if (match && match->data) {
		data = match->data;
		offset = data->offset;
	} else {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		if (!res)
			return -EINVAL;

		offset = res->start;
		dev_WARN(&pdev->dev,
			 "using legacy dt data for pbias offset\n");
	}

	cfg.regmap = syscon;
	cfg.dev = &pdev->dev;

	for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) {
		if (!pbias_matches[idx].init_data ||
			!pbias_matches[idx].of_node)
			continue;

		info = pbias_matches[idx].driver_data;
		if (!info)
			return -ENODEV;

		drvdata[data_idx].syscon = syscon;
		drvdata[data_idx].info = info;
		drvdata[data_idx].desc.name = info->name;
		drvdata[data_idx].desc.owner = THIS_MODULE;
		drvdata[data_idx].desc.type = REGULATOR_VOLTAGE;
		drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops;
		drvdata[data_idx].desc.volt_table = info->pbias_volt_table;
		drvdata[data_idx].desc.n_voltages = info->n_voltages;
		drvdata[data_idx].desc.enable_time = info->enable_time;
		drvdata[data_idx].desc.vsel_reg = offset;
		drvdata[data_idx].desc.vsel_mask = info->vmode;
		drvdata[data_idx].desc.enable_reg = offset;
		drvdata[data_idx].desc.enable_mask = info->enable_mask;
		drvdata[data_idx].desc.enable_val = info->enable;
		drvdata[data_idx].desc.disable_val = info->disable_val;

		cfg.init_data = pbias_matches[idx].init_data;
		cfg.driver_data = &drvdata[data_idx];
		cfg.of_node = pbias_matches[idx].of_node;

		drvdata[data_idx].dev = devm_regulator_register(&pdev->dev,
					&drvdata[data_idx].desc, &cfg);
		if (IS_ERR(drvdata[data_idx].dev)) {
			ret = PTR_ERR(drvdata[data_idx].dev);
			dev_err(&pdev->dev,
				"Failed to register regulator: %d\n", ret);
			goto err_regulator;
		}
		data_idx++;
	}

	platform_set_drvdata(pdev, drvdata);

err_regulator:
	return ret;
}

static struct platform_driver pbias_regulator_driver = {
	.probe		= pbias_regulator_probe,
	.driver		= {
		.name		= "pbias-regulator",
		.of_match_table = of_match_ptr(pbias_of_match),
	},
};

module_platform_driver(pbias_regulator_driver);

MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
MODULE_DESCRIPTION("pbias voltage regulator");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pbias-regulator");
