// SPDX-License-Identifier: GPL-2.0
/*
 * Device access for Basin Cove PMIC
 *
 * Copyright (c) 2019, Intel Corporation.
 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 */

#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/mfd/intel_soc_pmic_mrfld.h>
#include <linux/module.h>
#include <linux/platform_data/x86/intel_scu_ipc.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

/*
 * Level 2 IRQs
 *
 * Firmware on the systems with Basin Cove PMIC services Level 1 IRQs
 * without an assistance. Thus, each of the Level 1 IRQ is represented
 * as a separate RTE in IOAPIC.
 */
static struct resource irq_level2_resources[] = {
	DEFINE_RES_IRQ(0), /* power button */
	DEFINE_RES_IRQ(0), /* TMU */
	DEFINE_RES_IRQ(0), /* thermal */
	DEFINE_RES_IRQ(0), /* BCU */
	DEFINE_RES_IRQ(0), /* ADC */
	DEFINE_RES_IRQ(0), /* charger */
	DEFINE_RES_IRQ(0), /* GPIO */
};

static const struct mfd_cell bcove_dev[] = {
	{
		.name = "mrfld_bcove_pwrbtn",
		.num_resources = 1,
		.resources = &irq_level2_resources[0],
	}, {
		.name = "mrfld_bcove_tmu",
		.num_resources = 1,
		.resources = &irq_level2_resources[1],
	}, {
		.name = "mrfld_bcove_thermal",
		.num_resources = 1,
		.resources = &irq_level2_resources[2],
	}, {
		.name = "mrfld_bcove_bcu",
		.num_resources = 1,
		.resources = &irq_level2_resources[3],
	}, {
		.name = "mrfld_bcove_adc",
		.num_resources = 1,
		.resources = &irq_level2_resources[4],
	}, {
		.name = "mrfld_bcove_charger",
		.num_resources = 1,
		.resources = &irq_level2_resources[5],
	}, {
		.name = "mrfld_bcove_pwrsrc",
		.num_resources = 1,
		.resources = &irq_level2_resources[5],
	}, {
		.name = "mrfld_bcove_gpio",
		.num_resources = 1,
		.resources = &irq_level2_resources[6],
	},
	{	.name = "mrfld_bcove_region", },
};

static int bcove_ipc_byte_reg_read(void *context, unsigned int reg,
				    unsigned int *val)
{
	struct intel_soc_pmic *pmic = context;
	u8 ipc_out;
	int ret;

	ret = intel_scu_ipc_dev_ioread8(pmic->scu, reg, &ipc_out);
	if (ret)
		return ret;

	*val = ipc_out;
	return 0;
}

static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
				     unsigned int val)
{
	struct intel_soc_pmic *pmic = context;
	u8 ipc_in = val;

	return intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
}

static const struct regmap_config bcove_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.max_register = 0xff,
	.reg_write = bcove_ipc_byte_reg_write,
	.reg_read = bcove_ipc_byte_reg_read,
};

static int bcove_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct intel_soc_pmic *pmic;
	unsigned int i;
	int ret;

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

	pmic->scu = devm_intel_scu_ipc_dev_get(dev);
	if (!pmic->scu)
		return -ENOMEM;

	platform_set_drvdata(pdev, pmic);
	pmic->dev = &pdev->dev;

	pmic->regmap = devm_regmap_init(dev, NULL, pmic, &bcove_regmap_config);
	if (IS_ERR(pmic->regmap))
		return PTR_ERR(pmic->regmap);

	for (i = 0; i < ARRAY_SIZE(irq_level2_resources); i++) {
		ret = platform_get_irq(pdev, i);
		if (ret < 0)
			return ret;

		irq_level2_resources[i].start = ret;
		irq_level2_resources[i].end = ret;
	}

	return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
				    bcove_dev, ARRAY_SIZE(bcove_dev),
				    NULL, 0, NULL);
}

static const struct acpi_device_id bcove_acpi_ids[] = {
	{ "INTC100E" },
	{}
};
MODULE_DEVICE_TABLE(acpi, bcove_acpi_ids);

static struct platform_driver bcove_driver = {
	.driver = {
		.name = "intel_soc_pmic_mrfld",
		.acpi_match_table = bcove_acpi_ids,
	},
	.probe = bcove_probe,
};
module_platform_driver(bcove_driver);

MODULE_DESCRIPTION("IPC driver for Intel SoC Basin Cove PMIC");
MODULE_LICENSE("GPL v2");
