Ejemplo n.º 1
0
/* set host timing config */
static void mshci_hi_update_timing(struct mshci_host *ms_host, int bsuspend)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	unsigned int config_val;

	if ( get_chipid() == DI_CHIP_ID ) {
		if (bsuspend) {
			config_val = hi_host->suspend_timing_config;
		} else {
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "current signal voltage = %d",
							hi_host->old_sig_voltage);
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "current timing = %d",
							hi_host->old_timing);
			config_val = hi_host->timing_config[hi_host->old_timing + \
							hi_host->old_sig_voltage * (MMC_TIMING_UHS_DDR50 + 1)];
		}

		hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "current timing config = 0x%x",
						config_val);

		if (-1 == config_val) {
			himci_error("invalid config_val");
		}

		writel(0xF << (hi_host->pdev->id * 4),
					IO_ADDRESS(REG_BASE_SCTRL) + REG_SCPERDIS4);
		writel(config_val << (hi_host->pdev->id * 4),
					IO_ADDRESS(REG_BASE_SCTRL) + REG_SCPEREN4);

		hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "new reg val 0x%x",
					readl(IO_ADDRESS(REG_BASE_SCTRL) + REG_SCPERSTAT4));
	}
}
Ejemplo n.º 2
0
static irqreturn_t mshci_hi_card_detect_gpio(int irq, void *data)
{
	struct mshci_host *ms_host = (struct mshci_host *)data;
	struct himci_host *hi_host = (struct himci_host *)(ms_host->private);

#ifdef SD_FPGA_GPIO
	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "g00175134: CD Interrupt 0x%x\n",
					GPIO_CD_RIS(hi_host->gpioaddr));
	GPIO_CD_IC(hi_host->gpioaddr) = 0x1;
#endif
	hi_host->ocp_flag = 0;

	tasklet_schedule(&ms_host->card_tasklet);
	return IRQ_HANDLED;
};
Ejemplo n.º 3
0
unsigned int mshci_hi_get_present_status(struct mshci_host *ms_host)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	unsigned int status;
	if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) {
		if (ms_host->flags & MSHCI_DEVICE_DEAD)
			return 1;
		else
			return 0;
	} else if (ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION) {
#ifdef SD_FPGA_GPIO
		status = GPIO_CD_DATA(hi_host->gpioaddr);
		hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "g00175134: gpio status = %d \n",
						status);
#else
		/* GPIO High mean SD Card insert; GPIO Low means no SD card */
		status = !gpio_get_value(hi_host->plat->cd_gpio);
#endif
		status |= hi_host->ocp_flag;
		return status;
	} else {
		return 0;
	}
}
Ejemplo n.º 4
0
/*			-1 -- Tuning failed. Maybe slow down the clock and call this function again */
static int mshci_hi_tuning_find_condition(struct mshci_host *ms_host)
{
	struct himci_host *hi_host;
	int sample_min, sample_max;
	/*int begin, end;*/
	int i, j;
	int ret = 0;
	int mask,mask_lenth;

	hi_host = mshci_priv(ms_host);

	if (hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM] ==
		hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) {
		hi_host->tuning_init_sample =
			(hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM] +
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) / 2;
		mshci_hi_set_timing(hi_host, hi_host->tuning_init_sample, -1, -1);
		hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
			"no need tuning: timing is %d, tuning sample = %d",
			ms_host->mmc->ios.timing, hi_host->tuning_init_sample);
		return 0;
	}
	if (-1 == hi_host->tuning_current_sample) {

		mshci_hi_tuning_clear_flags(hi_host);

		/* set the first sam del as the min_sam_del */
		hi_host->tuning_current_sample =
			hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];
		/* a trick for next "++" */
		hi_host->tuning_current_sample--;
	}

	if (hi_host->tuning_current_sample >=
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) {
		/* tuning finish, select the best sam_del */

		/* set sam del to -1, for next tuning */
		hi_host->tuning_current_sample = -1;

		sample_min =
			hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];
		sample_max =
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];

#if 0
		begin = -1;
		end = -1;
		for (i = sample_min; i <= sample_max; i++) {
			if (-1 == begin) {
				/* no begin, find begin */
				if (mshci_hi_tuning_get_flags(hi_host, i)) {
					begin = i;
				} else {
					continue;
				}
			} else if (-1 == end) {
				/* no end, find end */
				if (mshci_hi_tuning_get_flags(hi_host, i)) {
					if (i == sample_max) {
						end = sample_max;
					} else {
						continue;
					}
				} else {
					end = i - 1;
				}
			} else {
				/* has begin & end, break */
				break;
			}
		}

		if (-1 == begin) {
			hi_host->tuning_init_sample = (sample_min + sample_max) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
				"tuning err: no good sam_del, timing is %d, tuning_flag = 0x%x",
				ms_host->mmc->ios.timing, hi_host->tuning_sample_flag);
			ret = -1;
		} else if (-1 == end) {
			hi_host->tuning_init_sample = (begin + sample_max) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
					"tuning err: no end! arithmetic error, timing is %d, begin = %d; tuning_flag = 0x%x",
					ms_host->mmc->ios.timing, begin, hi_host->tuning_sample_flag);
			ret = -1;
		} else {
			hi_host->tuning_init_sample = (begin + end) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
				"tuning OK: timing is %d, tuning sample = %d, tuning_flag = 0x%x",
				ms_host->mmc->ios.timing, hi_host->tuning_init_sample, hi_host->tuning_sample_flag);
			ret = 0;
		}
#else
		hi_host->tuning_init_sample = -1;
		for (mask_lenth = (((sample_max - sample_min) >> 1) << 1) + 1;
			mask_lenth >= 1; mask_lenth -= 2) {

				mask = (1 << mask_lenth) - 1;
				for (i = (sample_min + sample_max - mask_lenth + 1) / 2, j = 1;
					(i <= sample_max - mask_lenth + 1) && (i >= sample_min);
					i = ((sample_min + sample_max - mask_lenth + 1) / 2) + ((j % 2) ? -1 : 1) * (j / 2)) {
					if ((hi_host->tuning_sample_flag & (mask << i)) == (mask << i)) {
						hi_host->tuning_init_sample = i + mask_lenth / 2 ;
						break;
					}

					j++;
				}

				if (hi_host->tuning_init_sample != -1) {
					hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
						"tuning OK: timing is %d, tuning sample = %d, tuning_flag = 0x%x",
						ms_host->mmc->ios.timing, hi_host->tuning_init_sample, hi_host->tuning_sample_flag);
					ret = 0;
					break;
				}
		}

		if (-1 == hi_host->tuning_init_sample) {
			hi_host->tuning_init_sample = (sample_min + sample_max) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
				"tuning err: no good sam_del, timing is %d, tuning_flag = 0x%x",
				ms_host->mmc->ios.timing, hi_host->tuning_sample_flag);
			ret = -1;
		}
#endif

		mshci_hi_set_timing(hi_host, hi_host->tuning_init_sample, -1, -1);
		return ret;
	} else {
Ejemplo n.º 5
0
static int mshci_hi_start_signal_voltage_switch(struct mshci_host *ms_host,
				struct mmc_ios *ios)
{
	struct himci_host *hi_host = (struct himci_host *)(ms_host->private);
	int ret =0;
	struct iomux_pin *pin_temp = NULL;

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "old_sig_voltage = %d ",
					hi_host->old_sig_voltage);
	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "new_sig_voltage = %d ",
					ios->signal_voltage);
	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "allow_switch_signal_voltage = %d ",
					hi_host->allow_switch_signal_voltage);

	if (hi_host->allow_switch_signal_voltage &&
		(hi_host->old_sig_voltage != ios->signal_voltage)) {
		switch (ios->signal_voltage) {
		case MMC_SIGNAL_VOLTAGE_330:
			/* alter driver 6mA */
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "alter driver 6mA");
			pin_temp = iomux_get_pin(SD_CLK_PIN);
			if (pin_temp) {
				ret = pinmux_setdrivestrength(pin_temp, LEVEL2);
				if (ret < 0)
					himci_error("pinmux_setdrivestrength error");
			} else {
				himci_error("failed to get iomux pin");
			}

			hi_host->old_sig_voltage = ios->signal_voltage;
			/* if there is signal vcc, set vcc to signal voltage */
		    if (hi_host->signal_vcc) {
				ret = regulator_set_voltage(hi_host->signal_vcc, 2600000, 2600000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}
				ret = regulator_enable(hi_host->signal_vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
		    }

			/* update time config*/
			mshci_hi_update_timing(ms_host, 0);
			break;
		case MMC_SIGNAL_VOLTAGE_180:
			/* alter driver 8mA */
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "alter driver 8mA");
			pin_temp = iomux_get_pin(SD_CLK_PIN);
			if (pin_temp) {
				ret = pinmux_setdrivestrength(pin_temp, LEVEL3);
				if (ret < 0)
					himci_error("pinmux_setdrivestrength error");
			} else {
				himci_error("failed to get iomux pin");
			}

			hi_host->old_sig_voltage = ios->signal_voltage;
			/* if there is signal vcc, set vcc to signal voltage */
		    if (hi_host->signal_vcc) {
				ret = regulator_set_voltage(hi_host->signal_vcc, 1800000, 1800000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}
				ret = regulator_enable(hi_host->signal_vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
		    }
			/* update time config*/
			mshci_hi_update_timing(ms_host, 0);
			break;

		case MMC_SIGNAL_VOLTAGE_120:
			/* FIXME */
			/* 1.20v is not support */
			himci_error("1.20V is not supported");
			break;
		default:
			himci_error("unknown signal voltage");
			break;
		}
	}

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "--");

	return 0;
}
Ejemplo n.º 6
0
void mshci_hi_set_ios(struct mshci_host *ms_host, struct mmc_ios *ios)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	int ret = -1;

	hi_host_trace(HIMCI_TRACE_GEN_API, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->power_mode = %d ", ios->power_mode);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->clock = %d ", ios->clock);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->bus_width = %d ", ios->bus_width);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->timing = %d ", ios->timing);

	/* process power */
	if (hi_host->old_power_mode != ios->power_mode) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
		    hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to lowpower");
		    if (hi_host->vcc) {
				regulator_disable(hi_host->vcc);
		    }
			if (hi_host->signal_vcc) {
				regulator_disable(hi_host->signal_vcc);
				regulator_set_mode(hi_host->signal_vcc, REGULATOR_MODE_IDLE);
		    }

		    ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		    if (ret) {
				himci_error("failed to blockmux_set");
		    }

			break;
		case MMC_POWER_UP:
		    hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to normal");

		    ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		    if (ret) {
				himci_error("failed to blockmux_set");
		    }

		    if (hi_host->vcc) {
				ret = regulator_set_voltage(hi_host->vcc, 2850000, 2850000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}

				ret = regulator_enable(hi_host->vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
		    }
			if (hi_host->signal_vcc) {
				ret = regulator_set_voltage(hi_host->signal_vcc, 2600000, 2600000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}
				regulator_set_mode(hi_host->signal_vcc, REGULATOR_MODE_NORMAL);
				ret = regulator_enable(hi_host->signal_vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}

		    }
			break;
		case MMC_POWER_ON:
			break;
		default:
			himci_error("unknown power supply mode");
			break;
		}
		hi_host->old_power_mode = ios->power_mode;
	}

	/* process timing */
	if (hi_host->old_timing != ios->timing) {

		hi_host->old_timing = ios->timing;

		if ( get_chipid() == DI_CHIP_ID ) {
			mshci_hi_update_timing(ms_host, 0);

			switch (ios->timing) {
			case MMC_TIMING_LEGACY:
				if (hi_host->pdev->id == 1) {
					/* 2 division, 40M */
					writel((0x1<<6) | (0x7<<22),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 40*1000*1000;
					ms_host->clock++;
				} else if (hi_host->pdev->id == 0) {
					/* 2 division, 40M */
					writel((0x0<<5) | (0x1<<21),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 40*1000*1000;
					ms_host->clock++;
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_LEGACY");
				break;
			case MMC_TIMING_UHS_DDR50:
				if (hi_host->pdev->id == 1) {
					/* 1 division, 80M */
					writel((0x0<<6) | (0x7<<22),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 80*1000*1000;
					ms_host->clock++;
				} else {
#if 0
					/*
					 * m53980:
					 * debug purpose.
					 * change clock via sctrl configuration
					 */
					printk("clk div a:0x%x\n", readl(IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2));
					writel((0x7)|(0xF<<16), IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					printk("clk div b:0x%x\n", readl(IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2));
#endif
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_UHS_DDR50");
				break;
			case MMC_TIMING_UHS_SDR50:
				if (hi_host->pdev->id == 0) {
					writel((0x1<<5) | (0x1<<21),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 80*1000*1000;
					ms_host->clock++;
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_UHS_SDR50");
				break;
			default:
				break;
			}
		} else {
			ret = clk_set_rate(hi_host->pclk,hi_host->init_tuning_config[0 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]);
			if (ret) {
				himci_error("failed to clk_set_rate");
			}
			hi_host->tuning_init_sample =
					(hi_host->init_tuning_config[3 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM] +
					hi_host->init_tuning_config[4 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]) / 2;
			mshci_hi_set_timing(hi_host,
				hi_host->tuning_init_sample,
				hi_host->init_tuning_config[2 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM],
				hi_host->init_tuning_config[1 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]);

			ms_host->max_clk = hi_host->init_tuning_config[5 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM];

			ms_host->clock++;
		}
	}

	hi_host_trace(HIMCI_TRACE_GEN_API, "--");
}
Ejemplo n.º 7
0
/*			-1 -- Tuning failed. Maybe slow down the clock and call this function again */
static int mshci_hi_tuning_find_condition(struct mshci_host *ms_host)
{
	struct himci_host *hi_host;
	struct mmc_host *mmc;
	int sample_min, sample_max;
	/*int begin, end;*/
	int i, j;
	int ret;
	int mask,mask_lenth;

	hi_host = mshci_priv(ms_host);
	mmc = ms_host->mmc;

	if (hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM] ==
		hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) {
		hi_host->tuning_init_sample =
			(hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM] +
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) / 2;
		mshci_hi_set_timing(hi_host, hi_host->tuning_init_sample, -1, -1);
		hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
			"no need tuning: timing is %d, tuning sample = %d",
			ms_host->mmc->ios.timing, hi_host->tuning_init_sample);
		return 0;
	}
	if (-1 == hi_host->tuning_current_sample) {

		mshci_hi_tuning_clear_flags(hi_host);

		/* set the first sam del as the min_sam_del */
		hi_host->tuning_current_sample =
			hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];
		/* a trick for next "++" */
		hi_host->tuning_current_sample--;
	}

	if (hi_host->tuning_current_sample >=
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM]) {
		/* tuning finish, select the best sam_del */

		/* set sam del to -1, for next tuning */
		hi_host->tuning_current_sample = -1;

		sample_min =
			hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];
		sample_max =
			hi_host->init_tuning_config[3 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM];

#if 0
		begin = -1;
		end = -1;
		for (i = sample_min; i <= sample_max; i++) {
			if (-1 == begin) {
				/* no begin, find begin */
				if (mshci_hi_tuning_get_flags(hi_host, i)) {
					begin = i;
				} else {
					continue;
				}
			} else if (-1 == end) {
				/* no end, find end */
				if (mshci_hi_tuning_get_flags(hi_host, i)) {
					if (i == sample_max) {
						end = sample_max;
					} else {
						continue;
					}
				} else {
					end = i - 1;
				}
			} else {
				/* has begin & end, break */
				break;
			}
		}

		if (-1 == begin) {
			hi_host->tuning_init_sample = (sample_min + sample_max) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
				"tuning err: no good sam_del, timing is %d, tuning_flag = 0x%x",
				ms_host->mmc->ios.timing, hi_host->tuning_sample_flag);
			ret = -1;
		} else if (-1 == end) {
			hi_host->tuning_init_sample = (begin + sample_max) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
					"tuning err: no end! arithmetic error, timing is %d, begin = %d; tuning_flag = 0x%x",
					ms_host->mmc->ios.timing, begin, hi_host->tuning_sample_flag);
			ret = -1;
		} else {
			hi_host->tuning_init_sample = (begin + end) / 2;
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT,
				"tuning OK: timing is %d, tuning sample = %d, tuning_flag = 0x%x",
				ms_host->mmc->ios.timing, hi_host->tuning_init_sample, hi_host->tuning_sample_flag);
			ret = 0;
		}
#else
#define SD_DDR50_TUNNING_WIDTH		8
		/* begin: different delay sel for SD card in DDR50 */
		if ((MMC_TYPE_SD == mmc->card->type) &&
			(MMC_TIMING_UHS_DDR50 == mmc->ios.timing) &&
			(hi_host->init_tuning_config[4 + (ms_host->mmc->ios.timing + 1) * TUNING_INIT_CONFIG_NUM] > 8)) {
			sample_min = sample_min - SD_DDR50_TUNNING_WIDTH;
			hi_host->tuning_sample_flag |= hi_host->tuning_sample_flag >> SD_DDR50_TUNNING_WIDTH;
		}
Ejemplo n.º 8
0
static int mshci_hi_start_signal_voltage_switch(struct mshci_host *ms_host,
				struct mmc_ios *ios)
{
#if 1
	struct himci_host *hi_host = (struct himci_host *)(ms_host->private);




if (ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION) {

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "old_sig_voltage = %d ",
					hi_host->old_sig_voltage);
	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "new_sig_voltage = %d ",
					ios->signal_voltage);
	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "allow_switch_signal_voltage = %d ",
					hi_host->allow_switch_signal_voltage);

	if (hi_host->allow_switch_signal_voltage &&
		(hi_host->old_sig_voltage != ios->signal_voltage)) {
		switch (ios->signal_voltage) {
		case MMC_SIGNAL_VOLTAGE_330:
#ifdef CONFIG_MACH_HI6620OEM

		printk("yuandan 330 \n");

		hi_host->old_sig_voltage = ios->signal_voltage;

		/*
		3.3V IO 设置
 		LDO7   2.85V
 		LDO22  1.425V
 		*/
		if(ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION){
			pmussi_reg_write(SOC_SMART_LDO7_REG_ADJ_ADDR(0),SDMMC_3V3_IO_LDO7_SSI_VALUE);
			pmussi_reg_write(SOC_SMART_ENABLE4_ADDR(0),BIT(SOC_SMART_ENABLE4_en_ldo22_int_START));
		}
		sd_ldo22_need_control = 0;

#endif
			break;
		case MMC_SIGNAL_VOLTAGE_180:
#ifdef CONFIG_MACH_HI6620OEM
		printk("yuandan 180 \n");

		hi_host->old_sig_voltage = ios->signal_voltage;

		/*
		1.8V IO 设置
 		LDO7   1.8V
 		LDO22  0V
 		*/
 		if(ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION){
 			pmussi_reg_write(SOC_SMART_LDO7_REG_ADJ_ADDR(0),SDMMC_1V8_IO_LDO7_SSI_VALUE);
			udelay(30);
			pmussi_reg_write(SOC_SMART_DR1_ISET_ADDR(0), SDMMC_DR1_ISET_SSI_VALUE);/* DR1 current control */
			pmussi_reg_write(SOC_SMART_DR2_ISET_ADDR(0), SDMMC_DR2_ISET_SSI_VALUE);/* DR2 current control */
			pmussi_reg_write(SOC_SMART_DR_BRE_CTRL_ADDR(0), SDMMC_DR_CONTROL_SSI_VALUE);/* Turn on DR1 DR2 */
			pmussi_reg_write(SOC_SMART_DISABLE4_ADDR(0),BIT(SOC_SMART_DISABLE4_dis_ldo22_int_START));
		}

		sd_ldo22_need_control = 1;
#endif
			break;

		case MMC_SIGNAL_VOLTAGE_120:
			/* FIXME */
			/* 1.20v is not support */
			himci_error("1.20V is not supported");
			break;
		default:
			himci_error("unknown signal voltage");
			break;
		}
	}

	hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "--");

}
#endif

	return 0;
}
Ejemplo n.º 9
0
void mshci_hi_set_ios(struct mshci_host *ms_host, struct mmc_ios *ios)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	int ret = -1;
	int cbp_flag = 0;

	hi_host_trace(HIMCI_TRACE_GEN_API, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->power_mode = %d ", ios->power_mode);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->clock = %d ", ios->clock);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->bus_width = %d ", ios->bus_width);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->timing = %d ", ios->timing);

	ret = get_hw_config_int("modem/viacbp82d", &cbp_flag, NULL);
	if ((!ret) || (0 == cbp_flag)) {
		pr_info("%s has no cbp support\n", __func__);
	}

	pr_info("%s mode %d\n", __func__, ios->power_mode);

	/* process power */
	if (hi_host->old_power_mode != ios->power_mode) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
			if ((!cbp_flag)&&(1 == ms_host->hw_mmc_id)){
				mshci_sd_power_onoff(ms_host, 0);
				break;
			}
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to lowpower");
			if (hi_host->piomux_block && hi_host->pblock_config){
				ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
					if (ret) {
						himci_error("failed to blockmux_set");
					}
			}

			if (hi_host->vcc_lvs){
				ret = regulator_disable(hi_host->vcc_lvs);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}

			if (hi_host->vcc_ldo){
				ret = regulator_disable(hi_host->vcc_ldo);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}
			break;
		case MMC_POWER_UP:

			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to normal");
			if ((!cbp_flag)&&(1 == ms_host->hw_mmc_id)){
				mshci_sd_power_onoff(ms_host, 1);
				break;
			}
			if (hi_host->vcc_ldo){
				ret = regulator_enable(hi_host->vcc_ldo);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}
			if((1 == hi_host->ms_host->hw_mmc_id)&&(cbp_flag)){
				/*cbp need set as fixed 1.8v*/
				himci_error("sdio regulator_set_voltage 1.8 \n");
				if (hi_host->vcc_lvs) {
					ret = regulator_set_voltage(hi_host->vcc_lvs, SDMMC_1V8_IO_LDO7_180, SDMMC_1V8_IO_LDO7_180);
					if (ret != 0) {
						himci_error("failed to LDO7 regulator_set_voltage 1.8 \n");
					}
				}
			}
            if (hi_host->vcc_lvs){
                    ret = regulator_enable(hi_host->vcc_lvs);
                if (ret) {
                    himci_error("failed to regulator_enable");
                }
            }
            

            if (hi_host->piomux_block && hi_host->pblock_config){
                ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
                if (ret) {
                    himci_error("failed to blockmux_set");
                }
            }
			break;
		case MMC_POWER_ON:
			break;
		default:
			himci_error("unknown power supply mode");
			break;
		}
		hi_host->old_power_mode = ios->power_mode;
	}

	hi_host_trace(HIMCI_TRACE_GEN_API, "--");
}