2010-11-07 16:57:12 -05:00
/*
* sdhci - dove . c Support for SDHCI on Marvell ' s Dove SoC
*
* Author : Saeed Bishara < saeed @ marvell . com >
* Mike Rapoport < mike @ compulab . co . il >
* Based on sdhci - cns3xxx . c
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2012-07-05 12:14:01 +02:00
# include <linux/clk.h>
# include <linux/err.h>
2012-11-22 23:55:51 +00:00
# include <linux/io.h>
2010-11-07 16:57:12 -05:00
# include <linux/mmc/host.h>
2012-11-22 23:55:51 +00:00
# include <linux/module.h>
2012-07-31 10:12:59 +02:00
# include <linux/of.h>
2010-11-07 16:57:12 -05:00
# include "sdhci-pltfm.h"
static u16 sdhci_dove_readw ( struct sdhci_host * host , int reg )
{
u16 ret ;
switch ( reg ) {
case SDHCI_HOST_VERSION :
case SDHCI_SLOT_INT_STATUS :
/* those registers don't exist */
return 0 ;
default :
ret = readw ( host - > ioaddr + reg ) ;
}
return ret ;
}
static u32 sdhci_dove_readl ( struct sdhci_host * host , int reg )
{
u32 ret ;
2012-11-22 23:55:51 +00:00
ret = readl ( host - > ioaddr + reg ) ;
2010-11-07 16:57:12 -05:00
switch ( reg ) {
case SDHCI_CAPABILITIES :
/* Mask the support for 3.0V */
ret & = ~ SDHCI_CAN_VDD_300 ;
break ;
}
return ret ;
}
2013-03-13 19:26:05 +01:00
static const struct sdhci_ops sdhci_dove_ops = {
2010-11-07 16:57:12 -05:00
. read_w = sdhci_dove_readw ,
. read_l = sdhci_dove_readl ,
2014-04-25 12:58:55 +01:00
. set_clock = sdhci_set_clock ,
2014-04-25 12:57:07 +01:00
. set_bus_width = sdhci_set_bus_width ,
2014-04-25 12:57:12 +01:00
. reset = sdhci_reset ,
2014-04-25 12:59:26 +01:00
. set_uhs_signaling = sdhci_set_uhs_signaling ,
2010-11-07 16:57:12 -05:00
} ;
2013-03-13 19:26:03 +01:00
static const struct sdhci_pltfm_data sdhci_dove_pdata = {
2010-11-07 16:57:12 -05:00
. ops = & sdhci_dove_ops ,
. quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
SDHCI_QUIRK_NO_BUSY_IRQ |
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
2012-07-21 19:26:19 -04:00
SDHCI_QUIRK_FORCE_DMA |
SDHCI_QUIRK_NO_HISPD_BIT ,
2010-11-07 16:57:12 -05:00
} ;
2011-05-27 23:48:12 +08:00
2012-11-19 13:23:06 -05:00
static int sdhci_dove_probe ( struct platform_device * pdev )
2011-05-27 23:48:12 +08:00
{
2012-07-05 12:14:01 +02:00
struct sdhci_host * host ;
struct sdhci_pltfm_host * pltfm_host ;
int ret ;
2013-05-29 13:50:05 -07:00
host = sdhci_pltfm_init ( pdev , & sdhci_dove_pdata , 0 ) ;
2014-05-23 00:16:52 +02:00
if ( IS_ERR ( host ) )
return PTR_ERR ( host ) ;
2012-10-29 21:43:07 +00:00
2012-07-05 12:14:01 +02:00
pltfm_host = sdhci_priv ( host ) ;
2015-02-27 15:47:26 +08:00
pltfm_host - > clk = devm_clk_get ( & pdev - > dev , NULL ) ;
2012-07-05 12:14:01 +02:00
2015-02-27 15:47:26 +08:00
if ( ! IS_ERR ( pltfm_host - > clk ) )
clk_prepare_enable ( pltfm_host - > clk ) ;
2012-11-22 23:55:30 +00:00
2014-05-23 00:16:52 +02:00
ret = mmc_of_parse ( host - > mmc ) ;
if ( ret )
goto err_sdhci_add ;
2012-11-22 23:55:30 +00:00
ret = sdhci_add_host ( host ) ;
if ( ret )
goto err_sdhci_add ;
2012-07-05 12:14:01 +02:00
return 0 ;
2012-11-22 23:55:30 +00:00
err_sdhci_add :
2015-02-27 15:47:26 +08:00
clk_disable_unprepare ( pltfm_host - > clk ) ;
2012-11-22 23:55:30 +00:00
sdhci_pltfm_free ( pdev ) ;
2012-07-05 12:14:01 +02:00
return ret ;
2011-05-27 23:48:12 +08:00
}
2012-11-19 13:24:22 -05:00
static const struct of_device_id sdhci_dove_of_match_table [ ] = {
2012-07-31 10:12:59 +02:00
{ . compatible = " marvell,dove-sdhci " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , sdhci_dove_of_match_table ) ;
2011-05-27 23:48:12 +08:00
static struct platform_driver sdhci_dove_driver = {
. driver = {
. name = " sdhci-dove " ,
2011-11-03 11:09:45 +01:00
. pm = SDHCI_PLTFM_PMOPS ,
2014-02-25 15:18:24 +05:30
. of_match_table = sdhci_dove_of_match_table ,
2011-05-27 23:48:12 +08:00
} ,
. probe = sdhci_dove_probe ,
2015-02-27 15:47:31 +08:00
. remove = sdhci_pltfm_unregister ,
2011-05-27 23:48:12 +08:00
} ;
2011-11-26 12:55:43 +08:00
module_platform_driver ( sdhci_dove_driver ) ;
2011-05-27 23:48:12 +08:00
MODULE_DESCRIPTION ( " SDHCI driver for Dove " ) ;
MODULE_AUTHOR ( " Saeed Bishara <saeed@marvell.com>, "
" Mike Rapoport <mike@compulab.co.il> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;