Hello,
Is it possible to configure 2 SDIO ports at them same time on IMX233 ?
I need to use them for microSD and 88W8686 based SDIO card module.
IMX233 doesn't support SPI 16bit data mode, so I coudn't configure the libertas wifi driver by using GSPI interface.
Thanks and best regards.
OK,
After some time of modifing and testing, switching between sadness and happiness and pulling my hair out, I finally got my custome board work with two SDIO ports support.
Here is the job:
linux-2.6.35.3/arch/arm/mach-mx23/device.c
#if defined(CONFIG_MMC_MXS) || defined(CONFIG_MMC_MXS_MODULE)
#if !defined(CONFIG_SPI_MXS) && !defined(CONFIG_SPI_MXS_MODULE)
#if defined(CONFIG_MMC_ON_SSP1)
/* mmc0 platform data */
static struct mxs_mmc_platform_data mx23_mmc0_data = {
.hw_init = mxs_mmc_hw_init_mmc0,
.hw_release = mxs_mmc_hw_release_mmc0,
.get_wp = mxs_mmc_get_wp_mmc0,
.cmd_pullup = mxs_mmc_cmd_pullup_mmc0,
/*
Don't change ssp clock because ssp1 and ssp2 share one ssp clock source
ssp module have own divider.
.setclock = mxs_mmc_setclock_mmc0,
*/
.caps = MMC_CAP_4_BIT_DATA,
.min_clk = 400000,
.max_clk = 48000000,
.read_uA = 50000,
.write_uA = 70000,
.clock_mmc = "ssp.0",
.power_mmc = NULL,
};
/* mmc0 resource */
static struct resource mx23_mmc0_resource[] = {
{
.flags = IORESOURCE_MEM,
.start = SSP1_PHYS_ADDR,
.end = SSP1_PHYS_ADDR + 0x2000 - 1,
},
{
.flags = IORESOURCE_DMA,
.start = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
.end = MXS_DMA_CHANNEL_AHB_APBH_SSP1,
},
{
.flags = IORESOURCE_IRQ,
.start = IRQ_SSP1_DMA,
.end = IRQ_SSP1_DMA,
},
{
.flags = IORESOURCE_IRQ,
.start = IRQ_SSP_ERROR,
.end = IRQ_SSP_ERROR,
},
};
static void __init mx23_init_mmc0(void)
{
struct platform_device *pdev;
pdev = mxs_get_device("mxs-mmc", 0);
if (pdev == NULL || IS_ERR(pdev)) {
printk ("mxs-mmc0 get device failed\n");
return;
}
pdev->resource = mx23_mmc0_resource;
pdev->num_resources = ARRAY_SIZE(mx23_mmc0_resource);
pdev->dev.platform_data = &mx23_mmc0_data;
mxs_add_device(pdev, 2);
}
#else /* CONFIG_MMC_ON_SSP1*/
static void mx23_init_mmc0(void)
{
}
#endif /* CONFIG_MMC_ON_SSP1 */
#endif /* !defined(CONFIG_SPI_MXS) */
#if defined(CONFIG_MMC_ON_SSP2)
/* mmc1 platform data */
static struct mxs_mmc_platform_data mx23_mmc1_data = {
.hw_init = mxs_mmc_hw_init_mmc1,
.hw_release = mxs_mmc_hw_release_mmc1,
.get_wp = mxs_mmc_get_wp_mmc1,
.cmd_pullup = mxs_mmc_cmd_pullup_mmc1,
/*
Don't change ssp clock because ssp1 and ssp2 share one ssp clock source
ssp module have own divider.
.setclock = mxs_mmc_setclock_mmc1,
*/
.caps = MMC_CAP_4_BIT_DATA,
.min_clk = 400000,
.max_clk = 48000000,
.read_uA = 50000,
.write_uA = 70000,
.clock_mmc = "ssp.0",
.power_mmc = NULL,
};
/* mmc1 resource */
static struct resource mx23_mmc1_resource[] = {
{
.flags = IORESOURCE_MEM,
.start = SSP2_PHYS_ADDR,
.end = SSP2_PHYS_ADDR + 0x2000 - 1,
},
{
.flags = IORESOURCE_DMA,
.start = MXS_DMA_CHANNEL_AHB_APBH_SSP2,
.end = MXS_DMA_CHANNEL_AHB_APBH_SSP2,
},
{
.flags = IORESOURCE_IRQ,
.start = IRQ_SSP2_DMA,
.end = IRQ_SSP2_DMA,
},
{
.flags = IORESOURCE_IRQ,
.start = IRQ_SSP_ERROR,
.end = IRQ_SSP_ERROR,
},
};
static void __init mx23_init_mmc1(void)
{
struct platform_device *pdev;
pdev = mxs_get_device("mxs-mmc", 1);
if (pdev == NULL || IS_ERR(pdev)) {
printk ("mxs-mmc1 get device failed\n");
return;
}
pdev->resource = mx23_mmc1_resource;
pdev->num_resources = ARRAY_SIZE(mx23_mmc1_resource);
pdev->dev.platform_data = &mx23_mmc1_data;
mxs_add_device(pdev, 2);
}
#else /* CONFIG_MMC_ON_SSP2 */
static void mx23_init_mmc1(void)
{
}
#endif /* CONFIG_MMC_ON_SSP2 */
#else /* defined(CONFIG_MMC_MXS) */
#endif /* defined(CONFIG_MMC_MXS) */
...
#if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
CMDLINE_DEVICE_CHOOSE(ssp1, spi1, spi1)
#else
CMDLINE_DEVICE_CHOOSE(ssp1, mmc0, mmc0)
#endif
CMDLINE_DEVICE_CHOOSE(ssp2, mmc1, mmc1)
#if defined(CONFIG_MMC_MXS) || defined(CONFIG_MMC_MXS_MODULE)
#if defined(CONFIG_MMC_ON_SSP1)
linux-2.6.35.3/arch/arm/mach-mx23/mx23evk_pins.c
static struct pin_desc mx23evk_mmc0_pins[] = {
/* Configurations of SSP1 SD/MMC port pins */
{
.name = "SSP1_DATA0",
.id = PINID_SSP1_DATA0,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP1_DATA1",
.id = PINID_SSP1_DATA1,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP1_DATA2",
.id = PINID_SSP1_DATA2,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP1_DATA3",
.id = PINID_SSP1_DATA3,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP1_CMD",
.id = PINID_SSP1_CMD,
.fun = PIN_FUN1,
.strength = PAD_4MA,
.voltage = PAD_3_3V,
.drive = 1,
},
{
.name = "SSP1_SCK",
.id = PINID_SSP1_SCK,
.fun = PIN_FUN1,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.drive = 1,
},
};
#endif /* CONFIG_MMC_ON_SSP1 */
#if defined(CONFIG_MMC_ON_SSP2)
static struct pin_desc mx23evk_mmc1_pins[] = {
/* Configurations of SSP2 SD/MMC port pins */
{
.name = "SSP2_DATA0",
.id = PINID_SSP2_DATA0,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 1,
.drive = 1,
.pull = 1,
},
{
.name = "SSP2_DATA1",
.id = PINID_SSP2_DATA1,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 1,
.drive = 1,
.pull = 1,
},
{
.name = "SSP2_DATA2",
.id = PINID_SSP2_DATA2,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 1,
.drive = 1,
.pull = 1,
},
{
.name = "SSP2_DATA3",
.id = PINID_SSP2_DATA3,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 1,
.drive = 1,
.pull = 1,
},
{
.name = "SSP2_CMD",
.id = PINID_SSP2_CMD,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 1,
.drive = 1,
.pull = 1,
},
{
.name = "SSP2_SCK",
.id = PINID_SSP2_SCK,
.fun = PIN_FUN3,
.strength = PAD_8MA,
.voltage = PAD_3_3V,
.pullup = 0,
.drive = 1,
.pull = 0,
},
};
#endif /* CONFIG_MMC_ON_SSP2 */
#endif /* CONFIG_MMC_MXS */
...
linux-2.6.35.3/drivers/mmc/host/Kconfig
config MMC_ON_SSP1
tristate "MMC0 on SSP1"
depends on MMC_MXS && MACH_MX23EVK
help
Select Y to enable MMC0 on SSP1.
config MMC_ON_SSP2
tristate "MMC1 on SSP2"
depends on MMC_MXS && MACH_MX23EVK
help
Select Y to enable MMC0 on SSP2.