/*
 * Synopsys DesignWare Multimedia Card PCI Interface driver
 *
 * Copyright (C) 2012 Vayavya Labs Pvt. Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/dw_mmc.h>
#include "dw_mmc.h"

#define PCI_BAR_NO 2
#define COMPLETE_BAR 0
#define SYNOPSYS_DW_MCI_VENDOR_ID 0x700
#define SYNOPSYS_DW_MCI_DEVICE_ID 0x1107
/* Defining the Capabilities */
#define DW_MCI_CAPABILITIES (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |\
				MMC_CAP_SD_HIGHSPEED | MMC_CAP_8_BIT_DATA |\
				MMC_CAP_SDIO_IRQ)

static struct dw_mci_board pci_board_data = {
	.num_slots			= 1,
	.caps				= DW_MCI_CAPABILITIES,
	.bus_hz				= 33 * 1000 * 1000,
	.detect_delay_ms		= 200,
	.fifo_depth			= 32,
};

static int __devinit dw_mci_pci_probe(struct pci_dev *pdev,
				  const struct pci_device_id *entries)
{
	struct dw_mci *host;
	int ret;

	ret = pci_enable_device(pdev);
	if (ret)
		return ret;
	if (pci_request_regions(pdev, "dw_mmc_pci")) {
		ret = -ENODEV;
		goto err_disable_dev;
	}

	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
	if (!host) {
		ret = -ENOMEM;
		goto err_release;
	}

	host->irq = pdev->irq;
	host->irq_flags = IRQF_SHARED;
	host->dev = pdev->dev;
	host->pdata = &pci_board_data;

	host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
	if (!host->regs) {
		ret = -EIO;
		goto err_unmap;
	}

	pci_set_drvdata(pdev, host);
	ret = dw_mci_probe(host);
	if (ret)
		goto err_probe_failed;
	return ret;

err_probe_failed:
	pci_iounmap(pdev, host->regs);
err_unmap:
	kfree(host);
err_release:
	pci_release_regions(pdev);
err_disable_dev:
	pci_disable_device(pdev);
	return ret;
}

static void __devexit dw_mci_pci_remove(struct pci_dev *pdev)
{
	struct dw_mci *host = pci_get_drvdata(pdev);

	dw_mci_remove(host);
	pci_set_drvdata(pdev, NULL);
	pci_release_regions(pdev);
	pci_iounmap(pdev, host->regs);
	kfree(host);
	pci_disable_device(pdev);
}

#ifdef CONFIG_PM_SLEEP
static int dw_mci_pci_suspend(struct device *dev)
{
	int ret;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct dw_mci *host = pci_get_drvdata(pdev);

	ret = dw_mci_suspend(host);
	return ret;
}

static int dw_mci_pci_resume(struct device *dev)
{
	int ret;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct dw_mci *host = pci_get_drvdata(pdev);

	ret = dw_mci_resume(host);
	return ret;
}
#else
#define dw_mci_pci_suspend	NULL
#define dw_mci_pci_resume	NULL
#endif /* CONFIG_PM_SLEEP */

static SIMPLE_DEV_PM_OPS(dw_mci_pci_pmops, dw_mci_pci_suspend, dw_mci_pci_resume);

static DEFINE_PCI_DEVICE_TABLE(dw_mci_pci_id) = {
	{ PCI_DEVICE(SYNOPSYS_DW_MCI_VENDOR_ID, SYNOPSYS_DW_MCI_DEVICE_ID) },
	{}
};
MODULE_DEVICE_TABLE(pci, dw_mci_pci_id);

static struct pci_driver dw_mci_pci_driver = {
	.name		= "dw_mmc_pci",
	.id_table	= dw_mci_pci_id,
	.probe		= dw_mci_pci_probe,
	.remove		= dw_mci_pci_remove,
	.driver		=	{
		.pm =   &dw_mci_pci_pmops
	},
};

static int __init dw_mci_init(void)
{
	return pci_register_driver(&dw_mci_pci_driver);
}

static void __exit dw_mci_exit(void)
{
	pci_unregister_driver(&dw_mci_pci_driver);
}

module_init(dw_mci_init);
module_exit(dw_mci_exit);

MODULE_DESCRIPTION("DW Multimedia Card PCI Interface driver");
MODULE_AUTHOR("Shashidhar Hiremath <shashidharh@vayavyalabs.com>");
MODULE_LICENSE("GPL v2");
