Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
	}
}
Пример #5
0
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;
	}
}
Пример #6
0
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");
}
Пример #7
0
// [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);
}