1
0
Fork 0

pxamci: add regulator support.

Changes pxamci.c to use the regulator subsystem. Uses the regulator case
CONFIG_REGULATOR is defined and a matching is regulator is provided, or
falls back to pdata->setpower otherwise. A warning is displayed case
both a valid regulator and pdata is set, and the regulator is used.

Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com>
Acked-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
hifive-unleashed-5.1
Daniel Ribeiro 2009-05-21 08:54:18 -03:00 committed by Pierre Ossman
parent 8dfd0374be
commit 8385f9cb7f
1 changed files with 41 additions and 5 deletions

View File

@ -27,6 +27,7 @@
#include <linux/err.h>
#include <linux/mmc/host.h>
#include <linux/io.h>
#include <linux/regulator/consumer.h>
#include <asm/sizes.h>
@ -67,8 +68,42 @@ struct pxamci_host {
unsigned int dma_dir;
unsigned int dma_drcmrrx;
unsigned int dma_drcmrtx;
struct regulator *vcc;
};
static inline void pxamci_init_ocr(struct pxamci_host *host)
{
#ifdef CONFIG_REGULATOR
host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc");
if (IS_ERR(host->vcc))
host->vcc = NULL;
else {
host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc);
if (host->pdata && host->pdata->ocr_mask)
dev_warn(mmc_dev(host->mmc),
"ocr_mask/setpower will not be used\n");
}
#endif
if (host->vcc == NULL) {
/* fall-back to platform data */
host->mmc->ocr_avail = host->pdata ?
host->pdata->ocr_mask :
MMC_VDD_32_33 | MMC_VDD_33_34;
}
}
static inline void pxamci_set_power(struct pxamci_host *host, unsigned int vdd)
{
#ifdef CONFIG_REGULATOR
if (host->vcc)
mmc_regulator_set_ocr(host->vcc, vdd);
#endif
if (!host->vcc && host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc_dev(host->mmc), vdd);
}
static void pxamci_stop_clock(struct pxamci_host *host)
{
if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
@ -438,8 +473,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->power_mode != ios->power_mode) {
host->power_mode = ios->power_mode;
if (host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc_dev(mmc), ios->vdd);
pxamci_set_power(host, ios->vdd);
if (ios->power_mode == MMC_POWER_ON)
host->cmdat |= CMDAT_INIT;
@ -562,9 +596,8 @@ static int pxamci_probe(struct platform_device *pdev)
mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
: host->clkrate;
mmc->ocr_avail = host->pdata ?
host->pdata->ocr_mask :
MMC_VDD_32_33|MMC_VDD_33_34;
pxamci_init_ocr(host);
mmc->caps = 0;
host->cmdat = 0;
if (!cpu_is_pxa25x()) {
@ -661,6 +694,9 @@ static int pxamci_remove(struct platform_device *pdev)
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
if (host->vcc)
regulator_put(host->vcc);
if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);