1266 static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, 1267 unsigned short vdd) 1268 { 1269 struct mmc_host *mmc = host->mmc; 1270 u8 pwr = 0; 1271 1272 if (!IS_ERR(mmc->supply.vmmc)) { 1273 spin_unlock_irq(&host->lock); 1274 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 1275 spin_lock_irq(&host->lock); 1276 1277 if (mode != MMC_POWER_OFF) 1278 sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); 1279 else 1280 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1281 1282 return; 1283 } 1284 1285 if (mode != MMC_POWER_OFF) { 1286 switch (1 << vdd) { 1287 case MMC_VDD_165_195: 1288 pwr = SDHCI_POWER_180; 1289 break; 1290 case MMC_VDD_29_30: 1291 case MMC_VDD_30_31: 1292 pwr = SDHCI_POWER_300; 1293 break; 1294 case MMC_VDD_32_33: 1295 case MMC_VDD_33_34: 1296 pwr = SDHCI_POWER_330; 1297 break; 1298 default: 1299 BUG(); 1300 } 1301 } 1302 1303 if (host->pwr == pwr) 1304 return; 1305 1306 host->pwr = pwr; 1307 1308 if (pwr == 0) { 1309 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1310 if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 1311 sdhci_runtime_pm_bus_off(host); 1312 vdd = 0; 1313 } else { 1314 /* 1315 * Spec says that we should clear the power reg before setting 1316 * a new value. Some controllers don't seem to like this though. 1317 */ 1318 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 1319 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1320 1321 /* 1322 * At least the Marvell CaFe chip gets confused if we set the 1323 * voltage and set turn on power at the same time, so set the 1324 * voltage first. 1325 */ 1326 if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) 1327 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1328 1329 pwr |= SDHCI_POWER_ON; 1330 1331 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1332 1333 if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 1334 sdhci_runtime_pm_bus_on(host); 1335 1336 /* 1337 * Some controllers need an extra 10ms delay of 10ms before 1338 * they can apply clock after applying power 1339 */ 1340 if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) 1341 mdelay(10); 1342 } 1343 } 1344