return 0;
}
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init omap_2430sdp_init(void)
{
omap2430_i2c_init();
spi_register_board_info(sdp2430_spi_board_info,
ARRAY_SIZE(sdp2430_spi_board_info));
ads7846_dev_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
/* turn off secondary LCD backlight */
omap_set_gpio_direction(SECONDARY_LCD_GPIO, 0);
#include <mach/control.h>
#include "sdram-qimonda-hyb18m512160af-6.h"
+#include "mmc-twl4030.h"
#define CONFIG_DISABLE_HFCLK 1
return 0;
}
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 8,
+ .gpio_cd = -EINVAL,
+ },
+ {
+ .mmc = 2,
+ .wires = 8,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
extern void __init sdp3430_flash_init(void);
static void __init omap_3430sdp_init(void)
omap_serial_init();
usb_musb_init();
usb_ehci_init();
- hsmmc_init(HSMMC1 | HSMMC2);
+ hsmmc_init(mmc);
}
static void __init omap_3430sdp_map_io(void)
.cleanup = apollon_mmc_cleanup,
.dma_mask = 0xffffffff,
.slots[0] = {
- .wire4 = 1,
+ .wires = 4,
/*
* Use internal loop-back in MMC/SDIO Module Input Clock
.cleanup = h4_mmc_cleanup,
.dma_mask = 0xffffffff,
.slots[0] = {
- .wire4 = 1,
+ .wires = 4,
.set_power = h4_mmc_set_power,
.set_bus_mode = h4_mmc_set_bus_mode,
.get_cover_state= h4_mmc_slot1_cover_state,
.name = "slot1",
},
.slots[1] = {
- .wire4 = 1,
+ .wires = 4,
.set_power = h4_mmc_set_power,
.set_bus_mode = h4_mmc_set_bus_mode,
.get_cover_state= h4_mmc_slot2_cover_state,
return 0;
}
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init omap_ldp_init(void)
{
omap_i2c_init();
ads7846_dev_init();
omap_serial_init();
usb_musb_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
}
static void __init omap_ldp_map_io(void)
.max_freq = 24000000,
.dma_mask = 0xffffffff,
.slots[0] = {
- .wire4 = 1,
+ .wires = 4,
.set_power = n800_mmc_set_power,
.set_bus_mode = n800_mmc_set_bus_mode,
.get_cover_state= n800_mmc_get_cover_state,
&omap2evm_smc911x_device,
};
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init omap2_evm_init(void)
{
omap2_evm_i2c_init();
spi_register_board_info(omap2evm_spi_board_info,
ARRAY_SIZE(omap2evm_spi_board_info));
omap_serial_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
omap2evm_flash_init();
ads7846_dev_init();
}
}
}
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 8,
+ .gpio_cd = TWL4030_GPIO_IRQ_NO(0),
+ },
+ {} /* Terminator */
+};
+
static void __init omap3_beagle_init(void)
{
omap3_beagle_i2c_init();
omap_cfg_reg(AH8_34XX_GPIO29);
gpio_request(29, "mmc0_wp");
gpio_direction_input(29);
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
omap_cfg_reg(J25_34XX_GPIO170);
gpio_request(170, "DVI_nPD");
&omap3evm_smc911x_device,
};
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init omap3_evm_init(void)
{
omap3_evm_i2c_init();
ARRAY_SIZE(omap3evm_spi_board_info));
omap_serial_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
omap3evm_flash_init();
&omap3pandora_lcd_device,
};
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init omap3pandora_init(void)
{
omap3pandora_i2c_init();
omap_board_config = omap3pandora_config;
omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
omap_serial_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
omap3pandora_flash_init();
#include "sdram-micron-mt46h32m32lf-6.h"
#include "twl4030-generic-scripts.h"
+#include "mmc-twl4030.h"
#define NAND_BLOCK_SIZE SZ_128K
#define GPMC_CS0_BASE 0x60
&overo_lcd_device,
};
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {
+ .mmc = 2,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
static void __init overo_init(void)
{
overo_i2c_init();
omap_board_config = overo_config;
omap_board_config_size = ARRAY_SIZE(overo_config);
omap_serial_init();
- hsmmc_init(HSMMC1);
+ hsmmc_init(mmc);
usb_musb_init();
usb_ehci_init();
overo_flash_init();
omap_cfg_reg(F20_24XX_MMC_DAT0);
omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
- if (mmc_controller->slots[0].wire4) {
+ if (mmc_controller->slots[0].wires == 4) {
omap_cfg_reg(H14_24XX_MMC_DAT1);
omap_cfg_reg(E19_24XX_MMC_DAT2);
omap_cfg_reg(D19_24XX_MMC_DAT3);
#include <mach/mmc.h>
#include <mach/board.h>
+#include "mmc-twl4030.h"
+
#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
#define TWL_GPIO_IMR1A 0x1C
{
int ret = 0;
- disable_irq(TWL4030_GPIO_IRQ_NO(0));
+ disable_irq(hsmmc[0].card_detect_gpio);
ret = mask_cd_interrupt(1);
return ret;
{
int ret = 0;
- enable_irq(TWL4030_GPIO_IRQ_NO(0));
+ enable_irq(hsmmc[0].card_detect_gpio);
ret = mask_cd_interrupt(0);
return ret;
}
+#else
+#define hsmmc1_suspend NULL
+#define hsmmc1_resume NULL
#endif
/*
return ret;
}
-static struct omap_mmc_platform_data mmc1_data = {
- .nr_slots = 1,
- .init = hsmmc1_late_init,
- .cleanup = hsmmc1_cleanup,
-#ifdef CONFIG_PM
- .suspend = hsmmc1_suspend,
- .resume = hsmmc1_resume,
-#endif
- .dma_mask = 0xffffffff,
- .slots[0] = {
- .wire4 = 1,
- .set_power = hsmmc1_set_power,
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34 |
- MMC_VDD_165_195,
- .name = "first slot",
-
- .card_detect_irq = TWL4030_GPIO_IRQ_NO(0),
- .card_detect = hsmmc1_card_detect,
- },
-};
-
-static struct omap_mmc_platform_data mmc2_data = {
- .nr_slots = 1,
- .slots[0] = {
- .set_power = hsmmc2_set_power,
- .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 |
- MMC_VDD_29_30 | MMC_VDD_30_31 |
- MMC_VDD_31_32 | MMC_VDD_32_33,
- .name = "second slot",
- },
-};
-
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC];
-void __init hsmmc_init(int controller_mask)
+#define HSMMC_NAME_LEN 9
+
+void __init hsmmc_init(struct twl4030_hsmmc_info *controllers)
{
+ struct twl4030_hsmmc_info *c;
+
if (cpu_is_omap2430()) {
control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
hsmmc[1].control_devconf_offset = OMAP243X_CONTROL_DEVCONF1;
hsmmc[1].control_devconf_offset = OMAP343X_CONTROL_DEVCONF1;
}
- if (controller_mask & HSMMC1)
- hsmmc_data[0] = &mmc1_data;
- if (controller_mask & HSMMC2)
- hsmmc_data[1] = &mmc2_data;
- if (controller_mask & HSMMC3)
- pr_err("HSMMC: Unknown configuration for controller 3\n");
+ for (c = controllers; c->mmc; c++) {
+ struct omap_mmc_platform_data *mmc;
+ char *name;
+
+ mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+ if (!mmc) {
+ pr_err("Cannot allocate memory for mmc device!\n");
+ return;
+ }
+
+ name = kzalloc(HSMMC_NAME_LEN, GFP_KERNEL);
+ if (!name) {
+ kfree(mmc);
+ pr_err("Cannot allocate memory for mmc name!\n");
+ return;
+ }
+
+ sprintf(name, "mmc%islot%i", c->mmc, 1);
+ mmc->slots[0].name = name;
+ mmc->nr_slots = 1;
+ mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
+ MMC_VDD_26_27 | MMC_VDD_27_28 |
+ MMC_VDD_29_30 |
+ MMC_VDD_30_31 | MMC_VDD_31_32;
+ mmc->slots[0].wires = c->wires;
+ if (c->gpio_cd != -EINVAL)
+ mmc->slots[0].card_detect_irq = c->gpio_cd;
+ mmc->dma_mask = 0xffffffff;
+
+ switch (c->mmc) {
+ case 1:
+ mmc->init = hsmmc1_late_init;
+ mmc->cleanup = hsmmc1_cleanup;
+ mmc->suspend = hsmmc1_suspend;
+ mmc->resume = hsmmc1_resume;
+ mmc->slots[0].set_power = hsmmc1_set_power;
+ mmc->slots[0].card_detect = hsmmc1_card_detect;
+ hsmmc_data[0] = mmc;
+ break;
+ case 2:
+ mmc->slots[0].set_power = hsmmc2_set_power;
+ hsmmc_data[1] = mmc;
+ break;
+ default:
+ pr_err("Unknown MMC configuration!\n");
+ return;
+ }
+ }
+
omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
}
--- /dev/null
+/*
+ * MMC definitions for OMAP2
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+struct twl4030_hsmmc_info {
+ u8 mmc; /* controller 1/2/3 */
+ u8 wires; /* 1/4/8 wires */
+ int gpio_cd; /* or -EINVAL */
+};
+
+void hsmmc_init(struct twl4030_hsmmc_info *);
+
+#else
+
+static inline void hsmmc_init(struct twl4030_hsmmc_info *)
+{
+}
+
+#endif
unsigned cover:1;
/* 4 wire signaling is optional, and is only used for SD/SDIO */
- unsigned wire4:1;
+ u8 wires;
/* use the internal clock */
unsigned internal_clock:1;
int nr_controllers);
void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers);
-void hsmmc_init(int controller_mask);
int omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data);
#else
int nr_controllers)
{
}
-static inline void hsmmc_init(int controller_mask)
-{
-}
static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
unsigned int irq, struct omap_mmc_platform_data *data)
{
host->slots[id] = slot;
mmc->caps = 0;
- if (host->pdata->slots[id].wire4)
+ if (host->pdata->slots[id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
mmc->ops = &mmc_omap_ops;
mmc->ocr_avail = mmc_slot(host).ocr_mask;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
- if (pdata->slots[host->slot_id].wire4)
+ if (pdata->slots[host->slot_id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
/* Only MMC1 supports 3.0V */