2012-01-13 14:34:57 +04:00
/*
* 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 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 ,
} ;
2012-11-19 22:23:06 +04:00
static int dw_mci_pci_probe ( struct pci_dev * pdev ,
2013-06-05 13:24:12 +04:00
const struct pci_device_id * entries )
2012-01-13 14:34:57 +04:00
{
struct dw_mci * host ;
int ret ;
2013-06-05 13:24:12 +04:00
ret = pcim_enable_device ( pdev ) ;
2012-01-13 14:34:57 +04:00
if ( ret )
return ret ;
2013-06-05 13:24:12 +04:00
host = devm_kzalloc ( & pdev - > dev , sizeof ( struct dw_mci ) , GFP_KERNEL ) ;
if ( ! host )
return - ENOMEM ;
2012-01-13 14:34:57 +04:00
host - > irq = pdev - > irq ;
host - > irq_flags = IRQF_SHARED ;
2012-09-17 22:16:35 +04:00
host - > dev = & pdev - > dev ;
2012-01-13 14:34:57 +04:00
host - > pdata = & pci_board_data ;
2013-06-05 13:24:12 +04:00
ret = pcim_iomap_regions ( pdev , 1 < < PCI_BAR_NO , pci_name ( pdev ) ) ;
if ( ret )
return ret ;
2013-08-08 14:44:57 +04:00
host - > regs = pcim_iomap_table ( pdev ) [ PCI_BAR_NO ] ;
2012-01-13 14:34:57 +04:00
2013-08-08 14:44:58 +04:00
pci_set_master ( pdev ) ;
2012-01-13 14:34:57 +04:00
ret = dw_mci_probe ( host ) ;
if ( ret )
2013-06-05 13:24:12 +04:00
return ret ;
pci_set_drvdata ( pdev , host ) ;
2012-01-13 14:34:57 +04:00
2013-06-05 13:24:12 +04:00
return 0 ;
2012-01-13 14:34:57 +04:00
}
2012-11-19 22:26:03 +04:00
static void dw_mci_pci_remove ( struct pci_dev * pdev )
2012-01-13 14:34:57 +04:00
{
struct dw_mci * host = pci_get_drvdata ( pdev ) ;
dw_mci_remove ( host ) ;
}
# ifdef CONFIG_PM_SLEEP
static int dw_mci_pci_suspend ( struct device * dev )
{
struct pci_dev * pdev = to_pci_dev ( dev ) ;
struct dw_mci * host = pci_get_drvdata ( pdev ) ;
2013-06-05 13:24:11 +04:00
return dw_mci_suspend ( host ) ;
2012-01-13 14:34:57 +04:00
}
static int dw_mci_pci_resume ( struct device * dev )
{
struct pci_dev * pdev = to_pci_dev ( dev ) ;
struct dw_mci * host = pci_get_drvdata ( pdev ) ;
2013-06-05 13:24:11 +04:00
return dw_mci_resume ( host ) ;
2012-01-13 14:34:57 +04:00
}
# endif /* CONFIG_PM_SLEEP */
static SIMPLE_DEV_PM_OPS ( dw_mci_pci_pmops , dw_mci_pci_suspend , dw_mci_pci_resume ) ;
2014-08-08 17:56:03 +04:00
static const struct pci_device_id dw_mci_pci_id [ ] = {
2012-01-13 14:34:57 +04:00
{ 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 ,
2012-12-22 03:05:47 +04:00
. remove = dw_mci_pci_remove ,
2012-01-13 14:34:57 +04:00
. driver = {
. pm = & dw_mci_pci_pmops
} ,
} ;
2012-08-27 10:29:17 +04:00
module_pci_driver ( dw_mci_pci_driver ) ;
2012-01-13 14:34:57 +04:00
MODULE_DESCRIPTION ( " DW Multimedia Card PCI Interface driver " ) ;
MODULE_AUTHOR ( " Shashidhar Hiremath <shashidharh@vayavyalabs.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;