// SPDX-License-Identifier: GPL-2.0+
//
// AMD ACP PCI Driver
//
//Copyright 2016 Advanced Micro Devices, Inc.

#include <linux/pci.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/delay.h>

#include "acp3x.h"

struct acp3x_dev_data {
	void __iomem *acp3x_base;
	bool acp3x_audio_mode;
	struct resource *res;
	struct platform_device *pdev[ACP3x_DEVS];
};

static int acp3x_power_on(void __iomem *acp3x_base)
{
	u32 val;
	int timeout;

	val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);

	if (val == 0)
		return val;

	if (!((val & ACP_PGFSM_STATUS_MASK) ==
				ACP_POWER_ON_IN_PROGRESS))
		rv_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
			acp3x_base + mmACP_PGFSM_CONTROL);
	timeout = 0;
	while (++timeout < 500) {
		val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
		if (!val)
			return 0;
		udelay(1);
	}
	return -ETIMEDOUT;
}

static int acp3x_reset(void __iomem *acp3x_base)
{
	u32 val;
	int timeout;

	rv_writel(1, acp3x_base + mmACP_SOFT_RESET);
	timeout = 0;
	while (++timeout < 500) {
		val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
		if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK)
			break;
		cpu_relax();
	}
	rv_writel(0, acp3x_base + mmACP_SOFT_RESET);
	timeout = 0;
	while (++timeout < 500) {
		val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
		if (!val)
			return 0;
		cpu_relax();
	}
	return -ETIMEDOUT;
}

static int acp3x_init(void __iomem *acp3x_base)
{
	int ret;

	/* power on */
	ret = acp3x_power_on(acp3x_base);
	if (ret) {
		pr_err("ACP3x power on failed\n");
		return ret;
	}
	/* Reset */
	ret = acp3x_reset(acp3x_base);
	if (ret) {
		pr_err("ACP3x reset failed\n");
		return ret;
	}
	return 0;
}

static int acp3x_deinit(void __iomem *acp3x_base)
{
	int ret;

	/* Reset */
	ret = acp3x_reset(acp3x_base);
	if (ret) {
		pr_err("ACP3x reset failed\n");
		return ret;
	}
	return 0;
}

static int snd_acp3x_probe(struct pci_dev *pci,
			   const struct pci_device_id *pci_id)
{
	struct acp3x_dev_data *adata;
	struct platform_device_info pdevinfo[ACP3x_DEVS];
	unsigned int irqflags;
	int ret, i;
	u32 addr, val;

	if (pci_enable_device(pci)) {
		dev_err(&pci->dev, "pci_enable_device failed\n");
		return -ENODEV;
	}

	ret = pci_request_regions(pci, "AMD ACP3x audio");
	if (ret < 0) {
		dev_err(&pci->dev, "pci_request_regions failed\n");
		goto disable_pci;
	}

	adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
			     GFP_KERNEL);
	if (!adata) {
		ret = -ENOMEM;
		goto release_regions;
	}

	/* check for msi interrupt support */
	ret = pci_enable_msi(pci);
	if (ret)
		/* msi is not enabled */
		irqflags = IRQF_SHARED;
	else
		/* msi is enabled */
		irqflags = 0;

	addr = pci_resource_start(pci, 0);
	adata->acp3x_base = devm_ioremap(&pci->dev, addr,
					pci_resource_len(pci, 0));
	if (!adata->acp3x_base) {
		ret = -ENOMEM;
		goto disable_msi;
	}
	pci_set_master(pci);
	pci_set_drvdata(pci, adata);
	ret = acp3x_init(adata->acp3x_base);
	if (ret)
		goto disable_msi;

	val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
	switch (val) {
	case I2S_MODE:
		adata->res = devm_kzalloc(&pci->dev,
					  sizeof(struct resource) * 4,
					  GFP_KERNEL);
		if (!adata->res) {
			ret = -ENOMEM;
			goto de_init;
		}

		adata->res[0].name = "acp3x_i2s_iomem";
		adata->res[0].flags = IORESOURCE_MEM;
		adata->res[0].start = addr;
		adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);

		adata->res[1].name = "acp3x_i2s_sp";
		adata->res[1].flags = IORESOURCE_MEM;
		adata->res[1].start = addr + ACP3x_I2STDM_REG_START;
		adata->res[1].end = addr + ACP3x_I2STDM_REG_END;

		adata->res[2].name = "acp3x_i2s_bt";
		adata->res[2].flags = IORESOURCE_MEM;
		adata->res[2].start = addr + ACP3x_BT_TDM_REG_START;
		adata->res[2].end = addr + ACP3x_BT_TDM_REG_END;

		adata->res[3].name = "acp3x_i2s_irq";
		adata->res[3].flags = IORESOURCE_IRQ;
		adata->res[3].start = pci->irq;
		adata->res[3].end = adata->res[3].start;

		adata->acp3x_audio_mode = ACP3x_I2S_MODE;

		memset(&pdevinfo, 0, sizeof(pdevinfo));
		pdevinfo[0].name = "acp3x_rv_i2s_dma";
		pdevinfo[0].id = 0;
		pdevinfo[0].parent = &pci->dev;
		pdevinfo[0].num_res = 4;
		pdevinfo[0].res = &adata->res[0];
		pdevinfo[0].data = &irqflags;
		pdevinfo[0].size_data = sizeof(irqflags);

		pdevinfo[1].name = "acp3x_i2s_playcap";
		pdevinfo[1].id = 0;
		pdevinfo[1].parent = &pci->dev;
		pdevinfo[1].num_res = 1;
		pdevinfo[1].res = &adata->res[1];

		pdevinfo[2].name = "acp3x_i2s_playcap";
		pdevinfo[2].id = 1;
		pdevinfo[2].parent = &pci->dev;
		pdevinfo[2].num_res = 1;
		pdevinfo[2].res = &adata->res[1];

		pdevinfo[3].name = "acp3x_i2s_playcap";
		pdevinfo[3].id = 2;
		pdevinfo[3].parent = &pci->dev;
		pdevinfo[3].num_res = 1;
		pdevinfo[3].res = &adata->res[2];
		for (i = 0; i < ACP3x_DEVS; i++) {
			adata->pdev[i] =
				platform_device_register_full(&pdevinfo[i]);
			if (IS_ERR(adata->pdev[i])) {
				dev_err(&pci->dev, "cannot register %s device\n",
					pdevinfo[i].name);
				ret = PTR_ERR(adata->pdev[i]);
				goto unregister_devs;
			}
		}
		break;
	default:
		dev_err(&pci->dev, "Invalid ACP audio mode : %d\n", val);
		ret = -ENODEV;
		goto disable_msi;
	}
	pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
	pm_runtime_use_autosuspend(&pci->dev);
	pm_runtime_set_active(&pci->dev);
	pm_runtime_put_noidle(&pci->dev);
	pm_runtime_enable(&pci->dev);
	pm_runtime_allow(&pci->dev);
	return 0;

unregister_devs:
	if (val == I2S_MODE)
		for (i = 0; i < ACP3x_DEVS; i++)
			platform_device_unregister(adata->pdev[i]);
de_init:
	if (acp3x_deinit(adata->acp3x_base))
		dev_err(&pci->dev, "ACP de-init failed\n");
disable_msi:
	pci_disable_msi(pci);
release_regions:
	pci_release_regions(pci);
disable_pci:
	pci_disable_device(pci);

	return ret;
}

static int snd_acp3x_suspend(struct device *dev)
{
	int ret;
	struct acp3x_dev_data *adata;

	adata = dev_get_drvdata(dev);
	ret = acp3x_deinit(adata->acp3x_base);
	if (ret)
		dev_err(dev, "ACP de-init failed\n");
	else
		dev_dbg(dev, "ACP de-initialized\n");

	return 0;
}

static int snd_acp3x_resume(struct device *dev)
{
	int ret;
	struct acp3x_dev_data *adata;

	adata = dev_get_drvdata(dev);
	ret = acp3x_init(adata->acp3x_base);
	if (ret) {
		dev_err(dev, "ACP init failed\n");
		return ret;
	}
	return 0;
}

static const struct dev_pm_ops acp3x_pm = {
	.runtime_suspend = snd_acp3x_suspend,
	.runtime_resume =  snd_acp3x_resume,
	.resume =	snd_acp3x_resume,
};

static void snd_acp3x_remove(struct pci_dev *pci)
{
	struct acp3x_dev_data *adata;
	int i, ret;

	adata = pci_get_drvdata(pci);
	if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) {
		for (i = 0; i < ACP3x_DEVS; i++)
			platform_device_unregister(adata->pdev[i]);
	}
	ret = acp3x_deinit(adata->acp3x_base);
	if (ret)
		dev_err(&pci->dev, "ACP de-init failed\n");
	pm_runtime_disable(&pci->dev);
	pm_runtime_get_noresume(&pci->dev);
	pci_disable_msi(pci);
	pci_release_regions(pci);
	pci_disable_device(pci);
}

static const struct pci_device_id snd_acp3x_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2),
	.class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
	.class_mask = 0xffffff },
	{ 0, },
};
MODULE_DEVICE_TABLE(pci, snd_acp3x_ids);

static struct pci_driver acp3x_driver  = {
	.name = KBUILD_MODNAME,
	.id_table = snd_acp3x_ids,
	.probe = snd_acp3x_probe,
	.remove = snd_acp3x_remove,
	.driver = {
		.pm = &acp3x_pm,
	}
};

module_pci_driver(acp3x_driver);

MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
MODULE_DESCRIPTION("AMD ACP3x PCI driver");
MODULE_LICENSE("GPL v2");
