/*
 * Device driver for Hi6421 PMIC
 *
 * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
 *              http://www.hisilicon.com
 * Copyright (c) <2013-2017> Linaro Ltd.
 *              http://www.linaro.org
 *
 * Author: Guodong Xu <guodong.xu@linaro.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/hi6421-pmic.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

static const struct mfd_cell hi6421_devs[] = {
	{ .name = "hi6421-regulator", },
};

static const struct mfd_cell hi6421v530_devs[] = {
	{ .name = "hi6421v530-regulator", },
};

static const struct regmap_config hi6421_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 8,
	.max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX),
};

static const struct of_device_id of_hi6421_pmic_match[] = {
	{
		.compatible = "hisilicon,hi6421-pmic",
		.data = (void *)HI6421
	},
	{
		.compatible = "hisilicon,hi6421v530-pmic",
		.data = (void *)HI6421_V530
	},
	{ },
};
MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);

static int hi6421_pmic_probe(struct platform_device *pdev)
{
	struct hi6421_pmic *pmic;
	struct resource *res;
	const struct of_device_id *id;
	const struct mfd_cell *subdevs;
	enum hi6421_type type;
	void __iomem *base;
	int n_subdevs, ret;

	id = of_match_device(of_hi6421_pmic_match, &pdev->dev);
	if (!id)
		return -EINVAL;
	type = (enum hi6421_type)id->data;

	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
	if (!pmic)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
						 &hi6421_regmap_config);
	if (IS_ERR(pmic->regmap)) {
		dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n",
						PTR_ERR(pmic->regmap));
		return PTR_ERR(pmic->regmap);
	}

	platform_set_drvdata(pdev, pmic);

	switch (type) {
	case HI6421:
		/* set over-current protection debounce 8ms */
		regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
				(HI6421_OCP_DEB_SEL_MASK
				 | HI6421_OCP_EN_DEBOUNCE_MASK
				 | HI6421_OCP_AUTO_STOP_MASK),
				(HI6421_OCP_DEB_SEL_8MS
				 | HI6421_OCP_EN_DEBOUNCE_ENABLE));

		subdevs = hi6421_devs;
		n_subdevs = ARRAY_SIZE(hi6421_devs);
		break;
	case HI6421_V530:
		subdevs = hi6421v530_devs;
		n_subdevs = ARRAY_SIZE(hi6421v530_devs);
		break;
	default:
		dev_err(&pdev->dev, "Unknown device type %d\n",
						(unsigned int)type);
		return -EINVAL;
	}

	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
				   subdevs, n_subdevs, NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
		return ret;
	}

	return 0;
}

static struct platform_driver hi6421_pmic_driver = {
	.driver = {
		.name = "hi6421_pmic",
		.of_match_table = of_hi6421_pmic_match,
	},
	.probe	= hi6421_pmic_probe,
};
module_platform_driver(hi6421_pmic_driver);

MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
MODULE_DESCRIPTION("Hi6421 PMIC driver");
MODULE_LICENSE("GPL v2");
