// SPDX-License-Identifier: GPL-2.0-only
/*
 * Device driver for MFD hi655x PMIC
 *
 * Copyright (c) 2016 HiSilicon Ltd.
 *
 * Authors:
 * Chen Feng <puck.chen@hisilicon.com>
 * Fei  Wang <w.f@huawei.com>
 */

#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/gpio/consumer.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 const 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;
	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);
	if (IS_ERR(pmic->regmap))
		return PTR_ERR(pmic->regmap);

	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 = devm_gpiod_get_optional(dev, "pmic", GPIOD_IN);
	if (IS_ERR(pmic->gpio))
		return dev_err_probe(dev, PTR_ERR(pmic->gpio),
				"Failed to request hi655x pmic-gpio");

	ret = regmap_add_irq_chip(pmic->regmap, gpiod_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(gpiod_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(gpiod_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");
