diff options
Diffstat (limited to 'arch/arm/mach-omap2/msdi.c')
| -rw-r--r-- | arch/arm/mach-omap2/msdi.c | 73 | 
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index ef2a6924731..fb5bc6cf377 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -22,11 +22,15 @@   */  #include <linux/kernel.h> +#include <linux/err.h>  #include <plat/omap_hwmod.h> +#include <plat/omap_device.h>  #include <plat/mmc.h>  #include "common.h" +#include "control.h" +#include "mux.h"  /*   * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register @@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh)  	return 0;  } + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static inline void omap242x_mmc_mux(struct omap_mmc_platform_data +				    *mmc_controller) +{ +	if ((mmc_controller->slots[0].switch_pin > 0) && \ +		(mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) +		omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, +					OMAP_PIN_INPUT_PULLUP); +	if ((mmc_controller->slots[0].gpio_wp > 0) && \ +		(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) +		omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, +					OMAP_PIN_INPUT_PULLUP); + +	omap_mux_init_signal("sdmmc_cmd", 0); +	omap_mux_init_signal("sdmmc_clki", 0); +	omap_mux_init_signal("sdmmc_clko", 0); +	omap_mux_init_signal("sdmmc_dat0", 0); +	omap_mux_init_signal("sdmmc_dat_dir0", 0); +	omap_mux_init_signal("sdmmc_cmd_dir", 0); +	if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { +		omap_mux_init_signal("sdmmc_dat1", 0); +		omap_mux_init_signal("sdmmc_dat2", 0); +		omap_mux_init_signal("sdmmc_dat3", 0); +		omap_mux_init_signal("sdmmc_dat_dir1", 0); +		omap_mux_init_signal("sdmmc_dat_dir2", 0); +		omap_mux_init_signal("sdmmc_dat_dir3", 0); +	} + +	/* +	 * Use internal loop-back in MMC/SDIO Module Input Clock +	 * selection +	 */ +	if (mmc_controller->slots[0].internal_clock) { +		u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); +		v |= (1 << 24); +		omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); +	} +} + +void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) +{ +	struct platform_device *pdev; +	struct omap_hwmod *oh; +	int id = 0; +	char *oh_name = "msdi1"; +	char *dev_name = "mmci-omap"; + +	if (!mmc_data[0]) { +		pr_err("%s fails: Incomplete platform data\n", __func__); +		return; +	} + +	omap242x_mmc_mux(mmc_data[0]); + +	oh = omap_hwmod_lookup(oh_name); +	if (!oh) { +		pr_err("Could not look up %s\n", oh_name); +		return; +	} +	pdev = omap_device_build(dev_name, id, oh, mmc_data[0], +				 sizeof(struct omap_mmc_platform_data), NULL, 0, 0); +	if (IS_ERR(pdev)) +		WARN(1, "Can'd build omap_device for %s:%s.\n", +					dev_name, oh->name); +} + +#endif  |