void __init hsmmc_init(void) { rhandlemmc1 = resource_get("hsmmc1", "t2_vmmc1"); rhandlemmc2 = resource_get("hsmmc2", "t2_vmmc2"); rhandlevsim = resource_get("vsim", "t2_vsim"); hsmmc_data[0] = &mmc1_data; #ifdef CONFIG_OMAP_HS_MMC2 hsmmc_data[1] = &mmc2_data; #endif #ifdef CONFIG_OMAP_HS_MMC3 hsmmc_data[2] = &mmc3_data; #endif omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); }
static void __init n8x0_mmc_init(void) { int err; if (machine_is_nokia_n810()) { mmc1_data.slots[0].name = "external"; /* * Some Samsung Movinand chips do not like open-ended * multi-block reads and fall to braind-dead state * while doing so. Reducing the number of blocks in * the transfer or delays in clock disable do not help */ mmc1_data.slots[1].name = "internal"; mmc1_data.slots[1].ban_openended = 1; } err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch"); if (err) return; gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0); if (machine_is_nokia_n810()) { err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf"); if (err) { gpio_free(N8X0_SLOT_SWITCH_GPIO); return; } gpio_direction_output(N810_EMMC_VSD_GPIO, 0); err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd"); if (err) { gpio_free(N8X0_SLOT_SWITCH_GPIO); gpio_free(N810_EMMC_VSD_GPIO); return; } gpio_direction_output(N810_EMMC_VIO_GPIO, 0); } mmc_data[0] = &mmc1_data; omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC); }
void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); int i; u32 reg; if (!cpu_is_omap44xx()) { if (cpu_is_omap2430()) { control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; } else { control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; } } else { control_pbias_offset = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE; control_mmc1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1; reg = omap4_ctrl_pad_readl(control_mmc1); reg |= (OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK | OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK); reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK | OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK); reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK| OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK | OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK); omap4_ctrl_pad_writel(reg, control_mmc1); } for (c = controllers; c->mmc; c++) { struct hsmmc_controller *hc = hsmmc + c->mmc - 1; struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) { pr_debug("MMC%d: no such controller\n", c->mmc); continue; } if (mmc) { pr_debug("MMC%d: already configured\n", c->mmc); continue; } mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc) { pr_err("Cannot allocate memory for mmc device!\n"); goto done; } if (cpu_is_ti816x()) mmc->version = MMC_CTRL_VERSION_2; if (c->name) strncpy(hc->name, c->name, HSMMC_NAME_LEN); else snprintf(hc->name, ARRAY_SIZE(hc->name), "mmc%islot%i", c->mmc, 1); mmc->slots[0].name = hc->name; mmc->nr_slots = 1; mmc->slots[0].caps = c->caps; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; if (cpu_is_omap44xx()) mmc->reg_offset = OMAP4_MMC_REG_OFFSET; else mmc->reg_offset = 0; mmc->get_context_loss_count = hsmmc_get_context_loss; mmc->slots[0].switch_pin = c->gpio_cd; mmc->slots[0].gpio_wp = c->gpio_wp; mmc->slots[0].remux = c->remux; mmc->slots[0].init_card = c->init_card; if (c->cover_only) mmc->slots[0].cover = 1; if (c->nonremovable) mmc->slots[0].nonremovable = 1; if (c->power_saving) mmc->slots[0].power_saving = 1; if (c->no_off) mmc->slots[0].no_off = 1; if (c->vcc_aux_disable_is_sleep) mmc->slots[0].vcc_aux_disable_is_sleep = 1; /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. * * temporary HACK: ocr_mask instead of fixed supply */ if (cpu_is_omap3505() || cpu_is_omap3517()) 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; else mmc->slots[0].ocr_mask = c->ocr_mask; if (cpu_is_omap3517() || cpu_is_omap3505() || cpu_is_ti81xx()) mmc->slots[0].set_power = nop_mmc_set_power; else mmc->slots[0].features |= HSMMC_HAS_PBIAS; if ((cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) || cpu_is_ti814x()) mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET; switch (c->mmc) { case 1: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* on-chip level shifting via PBIAS0/PBIAS1 */ if (cpu_is_omap44xx()) { mmc->slots[0].before_set_reg = omap4_hsmmc1_before_set_reg; mmc->slots[0].after_set_reg = omap4_hsmmc1_after_set_reg; } else { mmc->slots[0].before_set_reg = omap_hsmmc1_before_set_reg; mmc->slots[0].after_set_reg = omap_hsmmc1_after_set_reg; } } /* Omap3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; mmc->slots[0].caps = c->caps; } break; case 2: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } /* FALLTHROUGH */ case 3: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* off-chip level shifting, or none */ mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; mmc->slots[0].after_set_reg = NULL; } break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); continue; } hsmmc_data[c->mmc - 1] = mmc; } if (!cpu_is_ti81xx()) omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); else omap2_init_mmc(hsmmc_data, TI81XX_NR_MMC); /* pass the device nodes back to board setup code */ for (c = controllers; c->mmc; c++) { struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) continue; c->dev = mmc->dev; } done: for (i = 0; i < nr_hsmmc; i++) kfree(hsmmc_data[i]); }
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) { struct twl4030_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); u32 reg; if (!cpu_is_omap44xx()) { if (cpu_is_omap2430()) { control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; nr_hsmmc = 2; } else { control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; } } else { control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE; control_mmc1 = OMAP44XX_CONTROL_MMC1; reg = omap_ctrl_readl(control_mmc1); reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 | OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1); reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 | OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3); reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL | OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL | OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL); omap_ctrl_writel(reg, control_mmc1); } for (c = controllers; c->mmc; c++) { struct twl_mmc_controller *twl = hsmmc + c->mmc - 1; struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) { pr_debug("MMC%d: no such controller\n", c->mmc); continue; } if (mmc) { pr_debug("MMC%d: already configured\n", c->mmc); continue; } mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc) { pr_err("Cannot allocate memory for mmc device!\n"); return; } if (c->name) strncpy(twl->name, c->name, HSMMC_NAME_LEN); else snprintf(twl->name, ARRAY_SIZE(twl->name), "mmc%islot%i", c->mmc, 1); #ifdef CONFIG_MMC_EMBEDDED_SDIO if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) { mmc->slots[0].embedded_sdio = &omap_wifi_emb_data; mmc->slots[0].register_status_notify = &omap_wifi_status_register; mmc->slots[0].card_detect = &omap_wifi_status; } #elif defined(CONFIG_TIWLAN_SDIO) if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) mmc->name = "TIWLAN_SDIO"; #endif mmc->slots[0].name = twl->name; mmc->nr_slots = 1; mmc->slots[0].wires = c->wires; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; mmc->init = twl_mmc_late_init; /* note: twl4030 card detect GPIOs can disable VMMCx ... */ if (!cpu_is_omap44xx()) { if (gpio_is_valid(c->gpio_cd)) { mmc->cleanup = twl_mmc_cleanup; mmc->suspend = twl_mmc_suspend; mmc->resume = twl_mmc_resume; mmc->slots[0].switch_pin = c->gpio_cd; mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); if (c->cover_only) mmc->slots[0].get_cover_state = twl_mmc_get_cover_state; else mmc->slots[0].card_detect = twl_mmc_card_detect; } else mmc->slots[0].switch_pin = -EINVAL; } else { /* HardCoding Phoenix number for only MMC1 of OMAP4 */ if (c->mmc == 1) mmc->slots[0].card_detect_irq = 384; else mmc->slots[0].card_detect_irq = 0; if (c->cover_only) mmc->slots[0].get_cover_state = twl_mmc_get_cover_state; else mmc->slots[0].card_detect = twl_mmc_card_detect; } mmc->get_context_loss_count = twl4030_mmc_get_context_loss; if (!cpu_is_omap44xx()) { /* write protect normally uses an OMAP gpio */ if (gpio_is_valid(c->gpio_wp)) { gpio_request(c->gpio_wp, "mmc_wp"); gpio_direction_input(c->gpio_wp); mmc->slots[0].gpio_wp = c->gpio_wp; mmc->slots[0].get_ro = twl_mmc_get_ro; } else mmc->slots[0].gpio_wp = -EINVAL; } if (c->nonremovable) mmc->slots[0].nonremovable = 1; if (c->power_saving) mmc->slots[0].power_saving = 1; /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. * * temporary HACK: ocr_mask instead of fixed supply */ mmc->slots[0].ocr_mask = c->ocr_mask; switch (c->mmc) { case 1: /* on-chip level shifting via PBIAS0/PBIAS1 */ mmc->slots[0].set_power = twl_mmc1_set_power; mmc->slots[0].set_sleep = twl_mmc1_set_sleep; /* Omap3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && c->wires > 4) { c->wires = 4; mmc->slots[0].wires = c->wires; } break; case 2: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && c->wires > 4) c->wires = 4; // TI Added to support Samsung Customisation mmc->slots[0].set_power = twl_iNand_set_power; if(gpio_request(OMAP_GPIO_MOVI_EN, "iNand_Power_source")< 0) { printk(KERN_ERR "Failed to get OMAP_GPIO_MOVI_EN pin \n"); return; } gpio_direction_output(OMAP_GPIO_MOVI_EN, 1); //mmc->slots[0].set_sleep = twl_mmc23_set_sleep; // TI Added to support Samsung Customisation break; /* FALLTHROUGH */ case 3: case 4: case 5: /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc23_set_power; mmc->slots[0].set_sleep = twl_mmc23_set_sleep; #ifdef CONFIG_MMC_EMBEDDED_SDIO mmc->slots[0].ocr_mask = MMC_VDD_165_195; #endif break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); continue; } hsmmc_data[c->mmc - 1] = mmc; } omap2_init_mmc(hsmmc_data, OMAP44XX_NR_MMC); /* pass the device nodes back to board setup code */ for (c = controllers; c->mmc; c++) { struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) continue; c->dev = mmc->dev; } }
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) { struct twl4030_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); if (cpu_is_omap2430()) { control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; nr_hsmmc = 2; } else { control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; } for (c = controllers; c->mmc; c++) { struct twl_mmc_controller *twl = hsmmc + c->mmc - 1; struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) { pr_debug("MMC%d: no such controller\n", c->mmc); continue; } if (mmc) { pr_debug("MMC%d: already configured\n", c->mmc); continue; } mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc) { pr_err("Cannot allocate memory for mmc device!\n"); return; } if (c->name) strncpy(twl->name, c->name, HSMMC_NAME_LEN); else snprintf(twl->name, ARRAY_SIZE(twl->name), "mmc%islot%i", c->mmc, 1); mmc->slots[0].name = twl->name; mmc->nr_slots = 1; mmc->slots[0].wires = c->wires; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; mmc->init = twl_mmc_late_init; /* note: twl4030 card detect GPIOs can disable VMMCx ... */ if (gpio_is_valid(c->gpio_cd)) { mmc->cleanup = twl_mmc_cleanup; mmc->suspend = twl_mmc_suspend; mmc->resume = twl_mmc_resume; mmc->slots[0].switch_pin = c->gpio_cd; mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); if (c->cover_only) mmc->slots[0].get_cover_state = twl_mmc_get_cover_state; else mmc->slots[0].card_detect = twl_mmc_card_detect; } else mmc->slots[0].switch_pin = -EINVAL; mmc->get_context_loss_count = twl4030_mmc_get_context_loss; /* write protect normally uses an OMAP gpio */ if (gpio_is_valid(c->gpio_wp)) { gpio_request(c->gpio_wp, "mmc_wp"); gpio_direction_input(c->gpio_wp); mmc->slots[0].gpio_wp = c->gpio_wp; mmc->slots[0].get_ro = twl_mmc_get_ro; } else mmc->slots[0].gpio_wp = -EINVAL; if (c->nonremovable) mmc->slots[0].nonremovable = 1; if (c->power_saving) mmc->slots[0].power_saving = 1; /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. * * temporary HACK: ocr_mask instead of fixed supply */ mmc->slots[0].ocr_mask = c->ocr_mask; switch (c->mmc) { case 1: /* on-chip level shifting via PBIAS0/PBIAS1 */ mmc->slots[0].set_power = twl_mmc1_set_power; mmc->slots[0].set_sleep = twl_mmc1_set_sleep; break; case 2: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && c->wires > 4) c->wires = 4; /* FALLTHROUGH */ case 3: /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc23_set_power; mmc->slots[0].set_sleep = twl_mmc23_set_sleep; break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); continue; } hsmmc_data[c->mmc - 1] = mmc; } omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); /* pass the device nodes back to board setup code */ for (c = controllers; c->mmc; c++) { struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; if (!c->mmc || c->mmc > nr_hsmmc) continue; c->dev = mmc->dev; } }
void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); int i; u32 reg; int controller_cnt = 0; printk(">>> omap2_hsmmc_init\n"); if (!cpu_is_omap44xx()) { if (cpu_is_omap2430()) { control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; } else { control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; } } else { control_pbias_offset = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE; control_mmc1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1; reg = omap4_ctrl_pad_readl(control_mmc1); reg |= (OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK | OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK); reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK | OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK); reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK| OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK | OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK); omap4_ctrl_pad_writel(reg, control_mmc1); } for (c = controllers; c->mmc; c++) { struct hsmmc_controller *hc = hsmmc + controller_cnt; struct omap_mmc_platform_data *mmc = hsmmc_data[controller_cnt]; if (!c->mmc || c->mmc > nr_hsmmc) { printk("MMC%d: no such controller\n", c->mmc); continue; } if (mmc) { printk("MMC%d: already configured\n", c->mmc); continue; } mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc) { pr_err("Cannot allocate memory for mmc device!\n"); goto done; } if (c->name) strncpy(hc->name, c->name, HSMMC_NAME_LEN); else snprintf(hc->name, ARRAY_SIZE(hc->name), "mmc%islot%i", c->mmc, 1); #ifdef CONFIG_TIWLAN_SDIO if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) { mmc->slots[0].embedded_sdio = &omap_wifi_emb_data; mmc->slots[0].register_status_notify = &omap_wifi_status_register; mmc->slots[0].card_detect = &omap_wifi_status; } #endif mmc->slots[0].name = hc->name; mmc->nr_slots = 1; mmc->slots[0].caps = c->caps; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; /* Register offset Mapping */ if (cpu_is_omap44xx()) mmc->regs_map = (u16 *) omap4_mmc_reg_map; else mmc->regs_map = (u16 *) omap3_mmc_reg_map; if (!cpu_is_omap44xx()) mmc->get_context_loss_count = hsmmc_get_context_loss; //&*&*&*SJ1_20110607, Add SIM card detection. #if defined (CONFIG_SIM_CARD_DETECTION) && defined (CONFIG_CHANGE_INAND_MMC_SCAN_INDEX) mmc->slots[0].sim_switch_pin = c->gpio_sim_cd; #endif //&*&*&*SJ2_20110607, Add SIM card detection. mmc->slots[0].switch_pin = c->gpio_cd; mmc->slots[0].cd_active_high = c->cd_active_high; mmc->slots[0].gpio_wp = c->gpio_wp; mmc->slots[0].remux = c->remux; if (c->cover_only) mmc->slots[0].cover = 1; if (c->nonremovable) mmc->slots[0].nonremovable = 1; if (c->power_saving) mmc->slots[0].power_saving = 1; if (c->no_off) mmc->slots[0].no_off = 1; if (c->vcc_aux_disable_is_sleep) mmc->slots[0].vcc_aux_disable_is_sleep = 1; /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. * * temporary HACK: ocr_mask instead of fixed supply */ mmc->slots[0].ocr_mask = c->ocr_mask; if (cpu_is_omap3517() || cpu_is_omap3505()) mmc->slots[0].set_power = nop_mmc_set_power; else mmc->slots[0].features |= HSMMC_HAS_PBIAS; if (cpu_is_omap44xx()) { if (omap_rev() > OMAP4430_REV_ES1_0) mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET; mmc->slots[0].features |= HSMMC_DVFS_24MHZ_CONST; if (c->mmc >= 3 && c->mmc <= 5) { mmc->slots[0].features |= HSMMC_HAS_48MHZ_MASTER_CLK; mmc->get_context_loss_count = hsmmc_get_context_loss; } } switch (c->mmc) { case 1: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* on-chip level shifting via PBIAS0/PBIAS1 */ if (cpu_is_omap44xx()) { mmc->slots[0].before_set_reg = omap4_hsmmc1_before_set_reg; mmc->slots[0].after_set_reg = omap4_hsmmc1_after_set_reg; } else { mmc->slots[0].before_set_reg = omap_hsmmc1_before_set_reg; mmc->slots[0].after_set_reg = omap_hsmmc1_after_set_reg; } } /* Omap3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; mmc->slots[0].caps = c->caps; } break; case 2: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } /* FALLTHROUGH */ case 3: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* off-chip level shifting, or none */ mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; mmc->slots[0].after_set_reg = NULL; } #ifdef CONFIG_TIWLAN_SDIO mmc->slots[0].ocr_mask = MMC_VDD_165_195; #endif break; case 4: case 5: /* TODO Update required */ mmc->slots[0].before_set_reg = NULL; mmc->slots[0].after_set_reg = NULL; #ifdef CONFIG_TIWLAN_SDIO mmc->slots[0].ocr_mask = MMC_VDD_165_195; #endif break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); continue; } hsmmc_data[controller_cnt] = mmc; omap2_init_mmc(hsmmc_data[controller_cnt], c->mmc); controller_cnt++; } /* pass the device nodes back to board setup code */ controller_cnt = 0; for (c = controllers; c->mmc; c++) { struct omap_mmc_platform_data *mmc = hsmmc_data[controller_cnt]; if (!c->mmc || c->mmc > nr_hsmmc) continue; c->dev = mmc->dev; controller_cnt++; } done: for (i = 0; i < controller_cnt; i++) kfree(hsmmc_data[i]); printk("<<< omap2_hsmmc_init\n"); }
// [email protected] Upgraded this function by referring to omap2_hsmmc_init() in hsmmc.c [START] void __init twl4030_mmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); int i; u32 reg; int controller_cnt = 0; control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; omap_mux_init_gpio(126, OMAP_PIN_INPUT | OMAP_PIN_OFF_WAKEUPENABLE); gpio_request(138, "MICROSD_LDO_EN"); for (c = controllers; c->mmc; c++) { struct twl_mmc_controller *hc = hsmmc + controller_cnt; struct omap_mmc_platform_data *mmc = hsmmc_data[controller_cnt]; if (!c->mmc || c->mmc > nr_hsmmc) { pr_debug("MMC%d: no such controller\n", c->mmc); continue; } if (mmc) { pr_debug("MMC%d: already configured\n", c->mmc); continue; } mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc) { pr_err("Cannot allocate memory for mmc device!\n"); goto done; } if (c->name) strncpy(hc->name, c->name, HSMMC_NAME_LEN); else snprintf(hc->name, ARRAY_SIZE(hc->name), "mmc%islot%i", c->mmc, 1); #ifdef CONFIG_MMC_EMBEDDED_SDIO if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) { mmc->slots[0].embedded_sdio = &omap_wifi_emb_data; mmc->slots[0].register_status_notify = &omap_wifi_status_register; mmc->slots[0].card_detect = &omap_wifi_status; } #elif defined(CONFIG_TIWLAN_SDIO) //--[[ LGE_UBIQUIX_MODIFIED_START : [[email protected]] #if 0 //!defined (LGE_HUB_DEVICE) if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) mmc->name = "TIWLAN_SDIO"; #endif //--]] LGE_UBIQUIX_MODIFIED_END : [[email protected]] #endif mmc->slots[0].name = hc->name; mmc->nr_slots = 1; mmc->slots[0].caps = c->caps; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; mmc->init = twl_mmc_late_init; /* Register offset Mapping */ if (cpu_is_omap44xx()) mmc->regs_map = (u16 *) omap4_mmc_reg_map; else mmc->regs_map = (u16 *) omap3_mmc_reg_map; if (!cpu_is_omap44xx()) mmc->get_context_loss_count = twl4030_mmc_get_context_loss; /* note: twl4030 card detect GPIOs can disable VMMCx ... */ if (gpio_is_valid(c->gpio_cd)) { mmc->cleanup = twl_mmc_cleanup; mmc->suspend = twl_mmc_suspend; mmc->resume = twl_mmc_resume; mmc->slots[0].switch_pin = c->gpio_cd; mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); if (c->cover_only) mmc->slots[0].get_cover_state = twl_mmc_get_cover_state; else mmc->slots[0].card_detect = twl_mmc_card_detect; } else mmc->slots[0].switch_pin = -EINVAL; mmc->slots[0].remux = c->remux; /* write protect normally uses an OMAP gpio */ if (gpio_is_valid(c->gpio_wp)) { gpio_request(c->gpio_wp, "mmc_wp"); gpio_direction_input(c->gpio_wp); mmc->slots[0].gpio_wp = c->gpio_wp; mmc->slots[0].get_ro = twl_mmc_get_ro; } else mmc->slots[0].gpio_wp = -EINVAL; if (c->cover_only) mmc->slots[0].cover = 1; if (c->nonremovable) mmc->slots[0].nonremovable = 1; if (c->power_saving) mmc->slots[0].power_saving = 1; if (c->no_off) mmc->slots[0].no_off = 1; if (c->vcc_aux_disable_is_sleep) mmc->slots[0].vcc_aux_disable_is_sleep = 1; /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. * * temporary HACK: ocr_mask instead of fixed supply */ mmc->slots[0].ocr_mask = c->ocr_mask; switch (c->mmc) { case 1: /* on-chip level shifting via PBIAS0/PBIAS1 */ mmc->slots[0].set_power = twl_mmc1_set_power; mmc->slots[0].set_sleep = twl_mmc1_set_sleep; /* Omap3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; mmc->slots[0].caps = c->caps; } break; case 2: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc2_set_power; mmc->slots[0].set_sleep = twl_mmc2_set_sleep; #ifdef CONFIG_MMC_EMBEDDED_SDIO mmc->slots[0].ocr_mask = MMC_VDD_165_195; #endif break; case 3: if (c->ext_clock) c->transceiver = 1; if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { c->caps &= ~MMC_CAP_8_BIT_DATA; c->caps |= MMC_CAP_4_BIT_DATA; } /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc3_set_power; mmc->slots[0].set_sleep = twl_mmc3_set_sleep; #ifdef CONFIG_MMC_EMBEDDED_SDIO mmc->slots[0].ocr_mask = MMC_VDD_165_195; #endif break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); continue; } hsmmc_data[controller_cnt] = mmc; omap2_init_mmc(hsmmc_data[controller_cnt], c->mmc); controller_cnt++; } /* pass the device nodes back to board setup code */ controller_cnt = 0; for (c = controllers; c->mmc; c++) { struct omap_mmc_platform_data *mmc = hsmmc_data[controller_cnt]; if (!c->mmc || c->mmc > nr_hsmmc) continue; c->dev = mmc->dev; } done: for (i = 0; i < controller_cnt; i++) kfree(hsmmc_data[i]); }
void __init apollon_mmc_init(void) { mmc_data[0] = &mmc1_data; omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC); }