// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Synopsys DesignWare I2C adapter driver.
 *
 * Based on the TI DAVINCI I2C adapter driver.
 *
 * Copyright (C) 2006 Texas Instruments.
 * Copyright (C) 2007 MontaVista Software Inc.
 * Copyright (C) 2009 Provigent Ltd.
 */
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/units.h>

#include "i2c-designware-core.h"

static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
{
	return clk_get_rate(dev->clk) / HZ_PER_KHZ;
}

static int dw_i2c_get_parent_regmap(struct dw_i2c_dev *dev)
{
	dev->map = dev_get_regmap(dev->dev->parent, NULL);
	if (!dev->map)
		return -ENODEV;

	return 0;
}

static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
{
	pm_runtime_disable(dev->dev);

	if (dev->shared_with_punit)
		pm_runtime_put_noidle(dev->dev);
}

static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev)
{
	struct platform_device *pdev = to_platform_device(dev->dev);
	int ret;

	if (device_is_compatible(dev->dev, "intel,xe-i2c"))
		return dw_i2c_get_parent_regmap(dev);

	switch (dev->flags & MODEL_MASK) {
	case MODEL_WANGXUN_SP:
		ret = dw_i2c_get_parent_regmap(dev);
		break;
	default:
		dev->base = devm_platform_ioremap_resource(pdev, 0);
		ret = PTR_ERR_OR_ZERO(dev->base);
		break;
	}

	return ret;
}

static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = {
	{
		.ident = "Qtechnology QT5222",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Qtechnology"),
			DMI_MATCH(DMI_PRODUCT_NAME, "QT5222"),
		},
	},
	{ } /* terminate list */
};

static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = {
#ifdef CONFIG_I2C_DESIGNWARE_BAYTRAIL
	{
		.probe = i2c_dw_baytrail_probe_lock_support,
	},
#endif
#ifdef CONFIG_I2C_DESIGNWARE_AMDPSP
	{
		.probe = i2c_dw_amdpsp_probe_lock_support,
	},
#endif
	{}
};

static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev)
{
	const struct i2c_dw_semaphore_callbacks *ptr;
	int i = 0;
	int ret;

	dev->semaphore_idx = -1;

	for (ptr = i2c_dw_semaphore_cb_table; ptr->probe; ptr++) {
		ret = ptr->probe(dev);
		if (ret) {
			/*
			 * If there is no semaphore device attached to this
			 * controller, we shouldn't abort general i2c_controller
			 * probe.
			 */
			if (ret != -ENODEV)
				return ret;

			i++;
			continue;
		}

		dev->semaphore_idx = i;
		break;
	}

	return 0;
}

static int dw_i2c_plat_probe(struct platform_device *pdev)
{
	u32 flags = (uintptr_t)device_get_match_data(&pdev->dev);
	struct device *device = &pdev->dev;
	struct i2c_adapter *adap;
	struct dw_i2c_dev *dev;
	int irq, ret;

	irq = platform_get_irq_optional(pdev, 0);
	if (irq == -ENXIO)
		flags |= ACCESS_POLLING;
	else if (irq < 0)
		return irq;

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

	if (device_property_present(device, "wx,i2c-snps-model"))
		flags = MODEL_WANGXUN_SP | ACCESS_POLLING;

	dev->dev = device;
	dev->irq = irq;
	dev->flags = flags;
	platform_set_drvdata(pdev, dev);

	ret = dw_i2c_plat_request_regs(dev);
	if (ret)
		return ret;

	dev->rst = devm_reset_control_get_optional_exclusive_deasserted(device, NULL);
	if (IS_ERR(dev->rst))
		return dev_err_probe(device, PTR_ERR(dev->rst), "failed to acquire reset\n");

	ret = i2c_dw_fw_parse_and_configure(dev);
	if (ret)
		return ret;

	ret = i2c_dw_probe_lock_support(dev);
	if (ret)
		return dev_err_probe(device, ret, "failed to probe lock support\n");

	i2c_dw_configure(dev);

	/* Optional interface clock */
	dev->pclk = devm_clk_get_optional(device, "pclk");
	if (IS_ERR(dev->pclk))
		return dev_err_probe(device, PTR_ERR(dev->pclk), "failed to acquire pclk\n");

	dev->clk = devm_clk_get_optional(device, NULL);
	if (IS_ERR(dev->clk))
		return dev_err_probe(device, PTR_ERR(dev->clk), "failed to acquire clock\n");

	ret = i2c_dw_prepare_clk(dev, true);
	if (ret)
		return ret;

	if (dev->clk) {
		struct i2c_timings *t = &dev->timings;
		u64 clk_khz;

		dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
		clk_khz = dev->get_clk_rate_khz(dev);

		if (!dev->sda_hold_time && t->sda_hold_ns)
			dev->sda_hold_time =
				DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO);
	}

	adap = &dev->adapter;
	adap->owner = THIS_MODULE;
	adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ?
				       I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED;
	adap->nr = -1;

	if (dev->flags & ACCESS_NO_IRQ_SUSPEND)
		dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE);
	else
		dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE | DPM_FLAG_SMART_SUSPEND);

	device_enable_async_suspend(device);

	/* The code below assumes runtime PM to be disabled. */
	WARN_ON(pm_runtime_enabled(device));

	pm_runtime_set_autosuspend_delay(device, 1000);
	pm_runtime_use_autosuspend(device);
	pm_runtime_set_active(device);

	if (dev->shared_with_punit)
		pm_runtime_get_noresume(device);

	pm_runtime_enable(device);

	ret = i2c_dw_probe(dev);
	if (ret) {
		dw_i2c_plat_pm_cleanup(dev);
		i2c_dw_prepare_clk(dev, false);
	}

	return ret;
}

static void dw_i2c_plat_remove(struct platform_device *pdev)
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
	struct device *device = &pdev->dev;

	pm_runtime_get_sync(device);

	i2c_del_adapter(&dev->adapter);

	i2c_dw_disable(dev);

	pm_runtime_dont_use_autosuspend(device);
	pm_runtime_put_noidle(device);
	dw_i2c_plat_pm_cleanup(dev);

	i2c_dw_prepare_clk(dev, false);
}

static const struct of_device_id dw_i2c_of_match[] = {
	{ .compatible = "mobileye,eyeq6lplus-i2c" },
	{ .compatible = "mscc,ocelot-i2c" },
	{ .compatible = "snps,designware-i2c" },
	{}
};
MODULE_DEVICE_TABLE(of, dw_i2c_of_match);

static const struct acpi_device_id dw_i2c_acpi_match[] = {
	{ "80860F41", ACCESS_NO_IRQ_SUSPEND },
	{ "808622C1", ACCESS_NO_IRQ_SUSPEND },
	{ "AMD0010", ACCESS_INTR_MASK },
	{ "AMDI0010", ACCESS_INTR_MASK },
	{ "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE },
	{ "AMDI0510", 0 },
	{ "APMC0D0F", 0 },
	{ "FUJI200B", 0 },
	{ "GOOG5000", 0 },
	{ "HISI02A1", 0 },
	{ "HISI02A2", 0 },
	{ "HISI02A3", 0 },
	{ "HJMC3001", 0 },
	{ "HYGO0010", ACCESS_INTR_MASK },
	{ "INT33C2", 0 },
	{ "INT33C3", 0 },
	{ "INT3432", 0 },
	{ "INT3433", 0 },
	{ "INTC10EF", 0 },
	{}
};
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);

static const struct platform_device_id dw_i2c_platform_ids[] = {
	{ "i2c_designware" },
	{}
};
MODULE_DEVICE_TABLE(platform, dw_i2c_platform_ids);

static struct platform_driver dw_i2c_driver = {
	.probe = dw_i2c_plat_probe,
	.remove = dw_i2c_plat_remove,
	.driver		= {
		.name	= "i2c_designware",
		.of_match_table = dw_i2c_of_match,
		.acpi_match_table = dw_i2c_acpi_match,
		.pm	= pm_ptr(&i2c_dw_dev_pm_ops),
	},
	.id_table = dw_i2c_platform_ids,
};

static int __init dw_i2c_init_driver(void)
{
	return platform_driver_register(&dw_i2c_driver);
}
subsys_initcall(dw_i2c_init_driver);

static void __exit dw_i2c_exit_driver(void)
{
	platform_driver_unregister(&dw_i2c_driver);
}
module_exit(dw_i2c_exit_driver);

MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("I2C_DW");
MODULE_IMPORT_NS("I2C_DW_COMMON");
