// SPDX-License-Identifier: GPL-2.0
/*
 * DesignWare PWM Controller driver (PCI part)
 *
 * Copyright (C) 2018-2020 Intel Corporation
 *
 * Author: Felipe Balbi (Intel)
 * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
 * Author: Raymond Tan <raymond.tan@intel.com>
 *
 * Limitations:
 * - The hardware cannot generate a 0 % or 100 % duty cycle. Both high and low
 *   periods are one or more input clock periods long.
 */

#define DEFAULT_MOUDLE_NAMESPACE dwc_pwm

#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>

#include "pwm-dwc.h"

/* Elkhart Lake */
static const struct dwc_pwm_info ehl_pwm_info = {
	.nr = 2,
	.size = 0x1000,
};

static int dwc_pwm_init_one(struct device *dev, struct dwc_pwm_drvdata *ddata, unsigned int idx)
{
	struct pwm_chip *chip;
	struct dwc_pwm *dwc;
	int ret;

	chip = dwc_pwm_alloc(dev);
	if (IS_ERR(chip))
		return PTR_ERR(chip);

	dwc = to_dwc_pwm(chip);
	dwc->base = ddata->io_base + (ddata->info->size * idx);

	ret = devm_pwmchip_add(dev, chip);
	if (ret)
		return ret;

	ddata->chips[idx] = chip;
	return 0;
}

static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
{
	const struct dwc_pwm_info *info;
	struct device *dev = &pci->dev;
	struct dwc_pwm_drvdata *ddata;
	unsigned int idx;
	int ret;

	ret = pcim_enable_device(pci);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to enable device\n");

	pci_set_master(pci);

	ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
	if (ret)
		return dev_err_probe(dev, ret, "Failed to iomap PCI BAR\n");

	info = (const struct dwc_pwm_info *)id->driver_data;
	ddata = devm_kzalloc(dev, struct_size(ddata, chips, info->nr), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	/*
	 * No need to check for pcim_iomap_table() failure,
	 * pcim_iomap_regions() already does it for us.
	 */
	ddata->io_base = pcim_iomap_table(pci)[0];
	ddata->info = info;

	for (idx = 0; idx < ddata->info->nr; idx++) {
		ret = dwc_pwm_init_one(dev, ddata, idx);
		if (ret)
			return ret;
	}

	dev_set_drvdata(dev, ddata);

	pm_runtime_put(dev);
	pm_runtime_allow(dev);

	return 0;
}

static void dwc_pwm_remove(struct pci_dev *pci)
{
	pm_runtime_forbid(&pci->dev);
	pm_runtime_get_noresume(&pci->dev);
}

static int dwc_pwm_suspend(struct device *dev)
{
	struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
	unsigned int idx;

	for (idx = 0; idx < ddata->info->nr; idx++) {
		struct pwm_chip *chip = ddata->chips[idx];
		struct dwc_pwm *dwc = to_dwc_pwm(chip);
		unsigned int i;

		for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
			if (chip->pwms[i].state.enabled) {
				dev_err(dev, "PWM %u in use by consumer (%s)\n",
					i, chip->pwms[i].label);
				return -EBUSY;
			}
			dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
			dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
			dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
		}
	}

	return 0;
}

static int dwc_pwm_resume(struct device *dev)
{
	struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
	unsigned int idx;

	for (idx = 0; idx < ddata->info->nr; idx++) {
		struct pwm_chip *chip = ddata->chips[idx];
		struct dwc_pwm *dwc = to_dwc_pwm(chip);
		unsigned int i;

		for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
			dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
			dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
			dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
		}
	}

	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume);

static const struct pci_device_id dwc_pwm_id_table[] = {
	{ PCI_VDEVICE(INTEL, 0x4bb7), (kernel_ulong_t)&ehl_pwm_info },
	{  }	/* Terminating Entry */
};
MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);

static struct pci_driver dwc_pwm_driver = {
	.name = "pwm-dwc",
	.probe = dwc_pwm_probe,
	.remove = dwc_pwm_remove,
	.id_table = dwc_pwm_id_table,
	.driver = {
		.pm = pm_sleep_ptr(&dwc_pwm_pm_ops),
	},
};

module_pci_driver(dwc_pwm_driver);

MODULE_AUTHOR("Felipe Balbi (Intel)");
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
MODULE_DESCRIPTION("DesignWare PWM Controller");
MODULE_LICENSE("GPL");
