1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host = mmc_priv(mmc); struct sdhci_pci_slot *slot = sdhci_priv(host); struct sdhci_pci_chip *chip = slot->chip; u8 scratch8; u16 scratch16; int ret;
sdhci_writeb(host, 0, SDHCI_CLOCK_CONTROL);
scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL); scratch8 &= 0x0F;
if (host->mmc->ios.timing == MMC_TIMING_SD_EXP_1_2V && host->mmc->caps2 & MMC_CAP2_SD_EXP_1_2V) { scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_120; } else { scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_180; } sdhci_writeb(host, scratch8, SDHCI_POWER_CONTROL);
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch8); scratch8 &= 0x7f; pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch8);
ret = read_poll_timeout(sdhci_readb, scratch8, !(scratch8 & BIT(0)), 1, 30000, false, host, O2_SD_EXP_INT_REG);
if (!ret) { scratch16 = sdhci_readw(host, O2_SD_PCIE_SWITCH); scratch16 |= BIT(8); sdhci_writew(host, scratch16, O2_SD_PCIE_SWITCH); } else { scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL); scratch8 &= 0x0F; sdhci_writeb(host, scratch8, SDHCI_POWER_CONTROL);
host->mmc->ios.timing = MMC_TIMING_LEGACY; }
pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch8); scratch8 |= 0x80; pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch8);
return 0; }
|