diff options
author | Balaji T K <balajitk@ti.com> | 2014-02-19 09:56:40 -0500 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-03-04 11:44:50 -0500 |
commit | e99448ff1f738412bbfec595b5e682c1f0a50279 (patch) | |
tree | 5c3572718f045242f4307ea3405a7aa0a9077887 /drivers/mmc | |
parent | 11469e0bb1c5eedd3b489a4b19dbd26c02577674 (diff) |
mmc: omap_hsmmc: adapt hsmmc to use pbias regulator
In DT case, PBAIS registers are programmed via regulator,
use regulator APIs to control PBIAS.
Signed-off-by: Balaji T K <balajitk@ti.com>
Tested-by: Florian Vaussard <florian.vaussard@epfl.ch>
Tested-by: Stefan Roese <sr@denx.de>
Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6f4b6b47c1c0..f46190cfae17 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -126,6 +126,10 @@ | |||
126 | #define OMAP_MMC_MAX_CLOCK 52000000 | 126 | #define OMAP_MMC_MAX_CLOCK 52000000 |
127 | #define DRIVER_NAME "omap_hsmmc" | 127 | #define DRIVER_NAME "omap_hsmmc" |
128 | 128 | ||
129 | #define VDD_1V8 1800000 /* 180000 uV */ | ||
130 | #define VDD_3V0 3000000 /* 300000 uV */ | ||
131 | #define VDD_165_195 (ffs(MMC_VDD_165_195) - 1) | ||
132 | |||
129 | /* | 133 | /* |
130 | * One controller can have multiple slots, like on some omap boards using | 134 | * One controller can have multiple slots, like on some omap boards using |
131 | * omap.c controller driver. Luckily this is not currently done on any known | 135 | * omap.c controller driver. Luckily this is not currently done on any known |
@@ -164,6 +168,8 @@ struct omap_hsmmc_host { | |||
164 | */ | 168 | */ |
165 | struct regulator *vcc; | 169 | struct regulator *vcc; |
166 | struct regulator *vcc_aux; | 170 | struct regulator *vcc_aux; |
171 | struct regulator *pbias; | ||
172 | bool pbias_enabled; | ||
167 | int pbias_disable; | 173 | int pbias_disable; |
168 | void __iomem *base; | 174 | void __iomem *base; |
169 | resource_size_t mapbase; | 175 | resource_size_t mapbase; |
@@ -277,6 +283,15 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
277 | if (mmc_slot(host).before_set_reg) | 283 | if (mmc_slot(host).before_set_reg) |
278 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | 284 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); |
279 | 285 | ||
286 | if (host->pbias) { | ||
287 | if (host->pbias_enabled == 1) { | ||
288 | ret = regulator_disable(host->pbias); | ||
289 | if (!ret) | ||
290 | host->pbias_enabled = 0; | ||
291 | } | ||
292 | regulator_set_voltage(host->pbias, VDD_3V0, VDD_3V0); | ||
293 | } | ||
294 | |||
280 | /* | 295 | /* |
281 | * Assume Vcc regulator is used only to power the card ... OMAP | 296 | * Assume Vcc regulator is used only to power the card ... OMAP |
282 | * VDDS is used to power the pins, optionally with a transceiver to | 297 | * VDDS is used to power the pins, optionally with a transceiver to |
@@ -311,9 +326,27 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
311 | } | 326 | } |
312 | } | 327 | } |
313 | 328 | ||
329 | if (host->pbias) { | ||
330 | if (vdd <= VDD_165_195) | ||
331 | ret = regulator_set_voltage(host->pbias, VDD_1V8, | ||
332 | VDD_1V8); | ||
333 | else | ||
334 | ret = regulator_set_voltage(host->pbias, VDD_3V0, | ||
335 | VDD_3V0); | ||
336 | if (ret < 0) | ||
337 | goto error_set_power; | ||
338 | |||
339 | if (host->pbias_enabled == 0) { | ||
340 | ret = regulator_enable(host->pbias); | ||
341 | if (!ret) | ||
342 | host->pbias_enabled = 1; | ||
343 | } | ||
344 | } | ||
345 | |||
314 | if (mmc_slot(host).after_set_reg) | 346 | if (mmc_slot(host).after_set_reg) |
315 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | 347 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); |
316 | 348 | ||
349 | error_set_power: | ||
317 | return ret; | 350 | return ret; |
318 | } | 351 | } |
319 | 352 | ||
@@ -347,6 +380,9 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
347 | reg = devm_regulator_get_optional(host->dev, "vmmc_aux"); | 380 | reg = devm_regulator_get_optional(host->dev, "vmmc_aux"); |
348 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; | 381 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; |
349 | 382 | ||
383 | reg = devm_regulator_get_optional(host->dev, "pbias"); | ||
384 | host->pbias = IS_ERR(reg) ? NULL : reg; | ||
385 | |||
350 | /* For eMMC do not power off when not in sleep state */ | 386 | /* For eMMC do not power off when not in sleep state */ |
351 | if (mmc_slot(host).no_regulator_off_init) | 387 | if (mmc_slot(host).no_regulator_off_init) |
352 | return 0; | 388 | return 0; |
@@ -1831,6 +1867,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
1831 | host->base = ioremap(host->mapbase, SZ_4K); | 1867 | host->base = ioremap(host->mapbase, SZ_4K); |
1832 | host->power_mode = MMC_POWER_OFF; | 1868 | host->power_mode = MMC_POWER_OFF; |
1833 | host->next_data.cookie = 1; | 1869 | host->next_data.cookie = 1; |
1870 | host->pbias_enabled = 0; | ||
1834 | 1871 | ||
1835 | platform_set_drvdata(pdev, host); | 1872 | platform_set_drvdata(pdev, host); |
1836 | 1873 | ||