/* 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)); } }
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; };
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; } }
/* -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 {
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; }
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, "--"); }
/* -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; }
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; }
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, "--"); }