/*
 * CE4100 PCI-I2C glue code for PXA's driver
 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 * License: GPL v2
 *
 * The CE4100's I2C device is more or less the same one as found on PXA.
 * It does not support slave mode, the register slightly moved. This PCI
 * device provides three bars, every contains a single I2C controller.
 */
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>

#define CE4100_PCI_I2C_DEVS	3

struct ce4100_devices {
	struct platform_device *pdev[CE4100_PCI_I2C_DEVS];
};

static struct platform_device *add_i2c_device(struct pci_dev *dev, int bar)
{
	struct platform_device *pdev;
	struct i2c_pxa_platform_data pdata;
	struct resource res[2];
	struct device_node *child;
	static int devnum;
	int ret;

	memset(&pdata, 0, sizeof(struct i2c_pxa_platform_data));
	memset(&res, 0, sizeof(res));

	res[0].flags = IORESOURCE_MEM;
	res[0].start = pci_resource_start(dev, bar);
	res[0].end = pci_resource_end(dev, bar);

	res[1].flags = IORESOURCE_IRQ;
	res[1].start = dev->irq;
	res[1].end = dev->irq;

	for_each_child_of_node(dev->dev.of_node, child) {
		const void *prop;
		struct resource r;
		int ret;

		ret = of_address_to_resource(child, 0, &r);
		if (ret < 0)
			continue;
		if (r.start != res[0].start)
			continue;
		if (r.end != res[0].end)
			continue;
		if (r.flags != res[0].flags)
			continue;

		prop = of_get_property(child, "fast-mode", NULL);
		if (prop)
			pdata.fast_mode = 1;

		break;
	}

	if (!child) {
		dev_err(&dev->dev, "failed to match a DT node for bar %d.\n",
				bar);
		ret = -EINVAL;
		goto out;
	}

	pdev = platform_device_alloc("ce4100-i2c", devnum);
	if (!pdev) {
		of_node_put(child);
		ret = -ENOMEM;
		goto out;
	}
	pdev->dev.parent = &dev->dev;
	pdev->dev.of_node = child;

	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
	if (ret)
		goto err;

	ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
	if (ret)
		goto err;

	ret = platform_device_add(pdev);
	if (ret)
		goto err;
	devnum++;
	return pdev;
err:
	platform_device_put(pdev);
out:
	return ERR_PTR(ret);
}

static int ce4100_i2c_probe(struct pci_dev *dev,
		const struct pci_device_id *ent)
{
	int ret;
	int i;
	struct ce4100_devices *sds;

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

	if (!dev->dev.of_node) {
		dev_err(&dev->dev, "Missing device tree node.\n");
		return -EINVAL;
	}
	sds = kzalloc(sizeof(*sds), GFP_KERNEL);
	if (!sds)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
		sds->pdev[i] = add_i2c_device(dev, i);
		if (IS_ERR(sds->pdev[i])) {
			ret = PTR_ERR(sds->pdev[i]);
			while (--i >= 0)
				platform_device_unregister(sds->pdev[i]);
			goto err_dev_add;
		}
	}
	pci_set_drvdata(dev, sds);
	return 0;

err_dev_add:
	kfree(sds);
	return ret;
}

static const struct pci_device_id ce4100_i2c_devices[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
	{ },
};

static struct pci_driver ce4100_i2c_driver = {
	.driver = {
		.suppress_bind_attrs = true,
	},
	.name           = "ce4100_i2c",
	.id_table       = ce4100_i2c_devices,
	.probe          = ce4100_i2c_probe,
};
builtin_pci_driver(ce4100_i2c_driver);
