/*
 * Device driver for MFD hi655x PMIC
 *
 * Copyright (c) 2016 Hisilicon.
 *
 * Authors:
 * Chen Feng <puck.chen@hisilicon.com>
 * Fei  Wang <w.f@huawei.com>
 *
 * 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/gpio.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/mfd/hi655x-pmic.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

static const struct regmap_irq hi655x_irqs[] = {
	{ .reg_offset = 0, .mask = OTMP_D1R_INT_MASK },
	{ .reg_offset = 0, .mask = VSYS_2P5_R_INT_MASK },
	{ .reg_offset = 0, .mask = VSYS_UV_D3R_INT_MASK },
	{ .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT_MASK },
	{ .reg_offset = 0, .mask = PWRON_D4SR_INT_MASK },
	{ .reg_offset = 0, .mask = PWRON_D20F_INT_MASK },
	{ .reg_offset = 0, .mask = PWRON_D20R_INT_MASK },
	{ .reg_offset = 0, .mask = RESERVE_INT_MASK },
};

static const struct regmap_irq_chip hi655x_irq_chip = {
	.name = "hi655x-pmic",
	.irqs = hi655x_irqs,
	.num_regs = 1,
	.num_irqs = ARRAY_SIZE(hi655x_irqs),
	.status_base = HI655X_IRQ_STAT_BASE,
	.ack_base = HI655X_IRQ_STAT_BASE,
	.mask_base = HI655X_IRQ_MASK_BASE,
};

static struct regmap_config hi655x_regmap_config = {
	.reg_bits = 32,
	.reg_stride = HI655X_STRIDE,
	.val_bits = 8,
	.max_register = HI655X_BUS_ADDR(0x400) - HI655X_STRIDE,
};

static struct resource pwrkey_resources[] = {
	{
		.name	= "down",
		.start	= PWRON_D20R_INT,
		.end	= PWRON_D20R_INT,
		.flags	= IORESOURCE_IRQ,
	}, {
		.name	= "up",
		.start	= PWRON_D20F_INT,
		.end	= PWRON_D20F_INT,
		.flags	= IORESOURCE_IRQ,
	}, {
		.name	= "hold 4s",
		.start	= PWRON_D4SR_INT,
		.end	= PWRON_D4SR_INT,
		.flags	= IORESOURCE_IRQ,
	},
};

static const struct mfd_cell hi655x_pmic_devs[] = {
	{
		.name		= "hi65xx-powerkey",
		.num_resources	= ARRAY_SIZE(pwrkey_resources),
		.resources	= &pwrkey_resources[0],
	},
	{	.name		= "hi655x-regulator",	},
	{	.name		= "hi655x-clk",		},
};

static void hi655x_local_irq_clear(struct regmap *map)
{
	int i;

	regmap_write(map, HI655X_ANA_IRQM_BASE, HI655X_IRQ_CLR);
	for (i = 0; i < HI655X_IRQ_ARRAY; i++) {
		regmap_write(map, HI655X_IRQ_STAT_BASE + i * HI655X_STRIDE,
			     HI655X_IRQ_CLR);
	}
}

static int hi655x_pmic_probe(struct platform_device *pdev)
{
	int ret;
	struct hi655x_pmic *pmic;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	void __iomem *base;

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

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

	pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
						 &hi655x_regmap_config);

	regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver);
	if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
		dev_warn(dev, "PMU version %d unsupported\n", pmic->ver);
		return -EINVAL;
	}

	hi655x_local_irq_clear(pmic->regmap);

	pmic->gpio = of_get_named_gpio(np, "pmic-gpios", 0);
	if (!gpio_is_valid(pmic->gpio)) {
		dev_err(dev, "Failed to get the pmic-gpios\n");
		return -ENODEV;
	}

	ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN,
				    "hi655x_pmic_irq");
	if (ret < 0) {
		dev_err(dev, "Failed to request gpio %d  ret = %d\n",
			pmic->gpio, ret);
		return ret;
	}

	ret = regmap_add_irq_chip(pmic->regmap, gpio_to_irq(pmic->gpio),
				  IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, 0,
				  &hi655x_irq_chip, &pmic->irq_data);
	if (ret) {
		dev_err(dev, "Failed to obtain 'hi655x_pmic_irq' %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, pmic);

	ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
			      ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
			      regmap_irq_get_domain(pmic->irq_data));
	if (ret) {
		dev_err(dev, "Failed to register device %d\n", ret);
		regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
		return ret;
	}

	return 0;
}

static int hi655x_pmic_remove(struct platform_device *pdev)
{
	struct hi655x_pmic *pmic = platform_get_drvdata(pdev);

	regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
	mfd_remove_devices(&pdev->dev);
	return 0;
}

static const struct of_device_id hi655x_pmic_match[] = {
	{ .compatible = "hisilicon,hi655x-pmic", },
	{},
};
MODULE_DEVICE_TABLE(of, hi655x_pmic_match);

static struct platform_driver hi655x_pmic_driver = {
	.driver	= {
		.name =	"hi655x-pmic",
		.of_match_table = of_match_ptr(hi655x_pmic_match),
	},
	.probe  = hi655x_pmic_probe,
	.remove = hi655x_pmic_remove,
};
module_platform_driver(hi655x_pmic_driver);

MODULE_AUTHOR("Chen Feng <puck.chen@hisilicon.com>");
MODULE_DESCRIPTION("Hisilicon hi655x PMIC driver");
MODULE_LICENSE("GPL v2");
