// 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/mod_devicetable.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 const 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;

	base = devm_platform_ioremap_resource(pdev, 0);
	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 void 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);
}

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 = hi655x_pmic_match,
	},
	.probe  = hi655x_pmic_probe,
	.remove_new = 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");
