/*
 * MFD core driver for Intel Broxton Whiskey Cove PMIC
 *
 * Copyright (C) 2015 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_bxtwc.h>
#include <asm/intel_pmc_ipc.h>

/* PMIC device registers */
#define REG_ADDR_MASK		0xFF00
#define REG_ADDR_SHIFT		8
#define REG_OFFSET_MASK		0xFF

/* Interrupt Status Registers */
#define BXTWC_IRQLVL1		0x4E02
#define BXTWC_PWRBTNIRQ		0x4E03

#define BXTWC_THRM0IRQ		0x4E04
#define BXTWC_THRM1IRQ		0x4E05
#define BXTWC_THRM2IRQ		0x4E06
#define BXTWC_BCUIRQ		0x4E07
#define BXTWC_ADCIRQ		0x4E08
#define BXTWC_CHGR0IRQ		0x4E09
#define BXTWC_CHGR1IRQ		0x4E0A
#define BXTWC_GPIOIRQ0		0x4E0B
#define BXTWC_GPIOIRQ1		0x4E0C
#define BXTWC_CRITIRQ		0x4E0D

/* Interrupt MASK Registers */
#define BXTWC_MIRQLVL1		0x4E0E
#define BXTWC_MPWRTNIRQ		0x4E0F

#define BXTWC_MIRQLVL1_MCHGR	BIT(5)

#define BXTWC_MTHRM0IRQ		0x4E12
#define BXTWC_MTHRM1IRQ		0x4E13
#define BXTWC_MTHRM2IRQ		0x4E14
#define BXTWC_MBCUIRQ		0x4E15
#define BXTWC_MADCIRQ		0x4E16
#define BXTWC_MCHGR0IRQ		0x4E17
#define BXTWC_MCHGR1IRQ		0x4E18
#define BXTWC_MGPIO0IRQ		0x4E19
#define BXTWC_MGPIO1IRQ		0x4E1A
#define BXTWC_MCRITIRQ		0x4E1B

/* Whiskey Cove PMIC share same ACPI ID between different platforms */
#define BROXTON_PMIC_WC_HRV	4

/* Manage in two IRQ chips since mask registers are not consecutive */
enum bxtwc_irqs {
	/* Level 1 */
	BXTWC_PWRBTN_LVL1_IRQ = 0,
	BXTWC_TMU_LVL1_IRQ,
	BXTWC_THRM_LVL1_IRQ,
	BXTWC_BCU_LVL1_IRQ,
	BXTWC_ADC_LVL1_IRQ,
	BXTWC_CHGR_LVL1_IRQ,
	BXTWC_GPIO_LVL1_IRQ,
	BXTWC_CRIT_LVL1_IRQ,

	/* Level 2 */
	BXTWC_PWRBTN_IRQ,
};

enum bxtwc_irqs_level2 {
	/* Level 2 */
	BXTWC_THRM0_IRQ = 0,
	BXTWC_THRM1_IRQ,
	BXTWC_THRM2_IRQ,
	BXTWC_BCU_IRQ,
	BXTWC_ADC_IRQ,
	BXTWC_USBC_IRQ,
	BXTWC_CHGR0_IRQ,
	BXTWC_CHGR1_IRQ,
	BXTWC_GPIO0_IRQ,
	BXTWC_GPIO1_IRQ,
	BXTWC_CRIT_IRQ,
};

static const struct regmap_irq bxtwc_regmap_irqs[] = {
	REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
	REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
	REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
	REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
	REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
	REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
	REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
	REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
	REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03),
};

static const struct regmap_irq bxtwc_regmap_irqs_level2[] = {
	REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff),
	REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf),
	REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
	REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
	REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
	REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 5, BIT(5)),
	REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
	REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
	REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
	REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
	REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
};

static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
	.name = "bxtwc_irq_chip",
	.status_base = BXTWC_IRQLVL1,
	.mask_base = BXTWC_MIRQLVL1,
	.irqs = bxtwc_regmap_irqs,
	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
	.num_regs = 2,
};

static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = {
	.name = "bxtwc_irq_chip_level2",
	.status_base = BXTWC_THRM0IRQ,
	.mask_base = BXTWC_MTHRM0IRQ,
	.irqs = bxtwc_regmap_irqs_level2,
	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2),
	.num_regs = 10,
};

static struct resource gpio_resources[] = {
	DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"),
	DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"),
};

static struct resource adc_resources[] = {
	DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
};

static struct resource usbc_resources[] = {
	DEFINE_RES_IRQ(BXTWC_USBC_IRQ),
};

static struct resource charger_resources[] = {
	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
};

static struct resource thermal_resources[] = {
	DEFINE_RES_IRQ(BXTWC_THRM0_IRQ),
	DEFINE_RES_IRQ(BXTWC_THRM1_IRQ),
	DEFINE_RES_IRQ(BXTWC_THRM2_IRQ),
};

static struct resource bcu_resources[] = {
	DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
};

static struct mfd_cell bxt_wc_dev[] = {
	{
		.name = "bxt_wcove_gpadc",
		.num_resources = ARRAY_SIZE(adc_resources),
		.resources = adc_resources,
	},
	{
		.name = "bxt_wcove_thermal",
		.num_resources = ARRAY_SIZE(thermal_resources),
		.resources = thermal_resources,
	},
	{
		.name = "bxt_wcove_usbc",
		.num_resources = ARRAY_SIZE(usbc_resources),
		.resources = usbc_resources,
	},
	{
		.name = "bxt_wcove_ext_charger",
		.num_resources = ARRAY_SIZE(charger_resources),
		.resources = charger_resources,
	},
	{
		.name = "bxt_wcove_bcu",
		.num_resources = ARRAY_SIZE(bcu_resources),
		.resources = bcu_resources,
	},
	{
		.name = "bxt_wcove_gpio",
		.num_resources = ARRAY_SIZE(gpio_resources),
		.resources = gpio_resources,
	},
	{
		.name = "bxt_wcove_region",
	},
};

static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
				    unsigned int *val)
{
	int ret;
	int i2c_addr;
	u8 ipc_in[2];
	u8 ipc_out[4];
	struct intel_soc_pmic *pmic = context;

	if (reg & REG_ADDR_MASK)
		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
	else {
		i2c_addr = BXTWC_DEVICE1_ADDR;
		if (!i2c_addr) {
			dev_err(pmic->dev, "I2C address not set\n");
			return -EINVAL;
		}
	}
	reg &= REG_OFFSET_MASK;

	ipc_in[0] = reg;
	ipc_in[1] = i2c_addr;
	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
			PMC_IPC_PMIC_ACCESS_READ,
			ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
	if (ret) {
		dev_err(pmic->dev, "Failed to read from PMIC\n");
		return ret;
	}
	*val = ipc_out[0];

	return 0;
}

static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
				       unsigned int val)
{
	int ret;
	int i2c_addr;
	u8 ipc_in[3];
	struct intel_soc_pmic *pmic = context;

	if (reg & REG_ADDR_MASK)
		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
	else {
		i2c_addr = BXTWC_DEVICE1_ADDR;
		if (!i2c_addr) {
			dev_err(pmic->dev, "I2C address not set\n");
			return -EINVAL;
		}
	}
	reg &= REG_OFFSET_MASK;

	ipc_in[0] = reg;
	ipc_in[1] = i2c_addr;
	ipc_in[2] = val;
	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
			PMC_IPC_PMIC_ACCESS_WRITE,
			ipc_in, sizeof(ipc_in), NULL, 0);
	if (ret) {
		dev_err(pmic->dev, "Failed to write to PMIC\n");
		return ret;
	}

	return 0;
}

/* sysfs interfaces to r/w PMIC registers, required by initial script */
static unsigned long bxtwc_reg_addr;
static ssize_t bxtwc_reg_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
}

static ssize_t bxtwc_reg_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
		dev_err(dev, "Invalid register address\n");
		return -EINVAL;
	}
	return (ssize_t)count;
}

static ssize_t bxtwc_val_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int ret;
	unsigned int val;
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

	ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
	if (ret < 0) {
		dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
		return -EIO;
	}

	return sprintf(buf, "0x%02x\n", val);
}

static ssize_t bxtwc_val_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int ret;
	unsigned int val;
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

	ret = kstrtouint(buf, 0, &val);
	if (ret)
		return ret;

	ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
	if (ret) {
		dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
			val, bxtwc_reg_addr);
		return -EIO;
	}
	return count;
}

static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store);
static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store);
static struct attribute *bxtwc_attrs[] = {
	&dev_attr_addr.attr,
	&dev_attr_val.attr,
	NULL
};

static const struct attribute_group bxtwc_group = {
	.attrs = bxtwc_attrs,
};

static const struct regmap_config bxtwc_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.reg_write = regmap_ipc_byte_reg_write,
	.reg_read = regmap_ipc_byte_reg_read,
};

static int bxtwc_probe(struct platform_device *pdev)
{
	int ret;
	acpi_handle handle;
	acpi_status status;
	unsigned long long hrv;
	struct intel_soc_pmic *pmic;

	handle = ACPI_HANDLE(&pdev->dev);
	status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
	if (ACPI_FAILURE(status)) {
		dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
		return -ENODEV;
	}
	if (hrv != BROXTON_PMIC_WC_HRV) {
		dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
			hrv);
		return -ENODEV;
	}

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

	ret = platform_get_irq(pdev, 0);
	if (ret < 0) {
		dev_err(&pdev->dev, "Invalid IRQ\n");
		return ret;
	}
	pmic->irq = ret;

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

	pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
					&bxtwc_regmap_config);
	if (IS_ERR(pmic->regmap)) {
		ret = PTR_ERR(pmic->regmap);
		dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
		return ret;
	}

	ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
				  IRQF_ONESHOT | IRQF_SHARED,
				  0, &bxtwc_regmap_irq_chip,
				  &pmic->irq_chip_data);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add IRQ chip\n");
		return ret;
	}

	ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
				  IRQF_ONESHOT | IRQF_SHARED,
				  0, &bxtwc_regmap_irq_chip_level2,
				  &pmic->irq_chip_data_level2);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n");
		goto err_irq_chip_level2;
	}

	ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
			      ARRAY_SIZE(bxt_wc_dev), NULL, 0,
			      NULL);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add devices\n");
		goto err_mfd;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
	if (ret) {
		dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
		goto err_sysfs;
	}

	/*
	 * There is known hw bug. Upon reset BIT 5 of register
	 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
	 * later it's set to 1(masked) automatically by hardware. So we
	 * have the software workaround here to unmaksed it in order to let
	 * charger interrutp work.
	 */
	regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
				BXTWC_MIRQLVL1_MCHGR, 0);

	return 0;

err_sysfs:
	mfd_remove_devices(&pdev->dev);
err_mfd:
	regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
err_irq_chip_level2:
	regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);

	return ret;
}

static int bxtwc_remove(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);

	sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
	mfd_remove_devices(&pdev->dev);
	regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
	regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);

	return 0;
}

static void bxtwc_shutdown(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);

	disable_irq(pmic->irq);
}

#ifdef CONFIG_PM_SLEEP
static int bxtwc_suspend(struct device *dev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

	disable_irq(pmic->irq);

	return 0;
}

static int bxtwc_resume(struct device *dev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

	enable_irq(pmic->irq);
	return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);

static const struct acpi_device_id bxtwc_acpi_ids[] = {
	{ "INT34D3", },
	{ }
};
MODULE_DEVICE_TABLE(acpi, pmic_acpi_ids);

static struct platform_driver bxtwc_driver = {
	.probe = bxtwc_probe,
	.remove	= bxtwc_remove,
	.shutdown = bxtwc_shutdown,
	.driver	= {
		.name	= "BXTWC PMIC",
		.pm     = &bxtwc_pm_ops,
		.acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
	},
};

module_platform_driver(bxtwc_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>");
