Skip to content

Commit

Permalink
mmc: mxcmmc: Allow binding a regulator to manage the MMC card voltage
Browse files Browse the repository at this point in the history
This implementation is based on the pxamci.c driver and it will
be used to support the mx31_3ds machine.

Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Chris Ball <cjb@laptop.org>
  • Loading branch information
Alberto Panizzo authored and Chris Ball committed Jan 9, 2011
1 parent 930e2fe commit 74b6695
Showing 1 changed file with 42 additions and 6 deletions.
48 changes: 42 additions & 6 deletions drivers/mmc/host/mxcmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>

#include <asm/dma.h>
#include <asm/irq.h>
Expand Down Expand Up @@ -141,10 +142,45 @@ struct mxcmci_host {

struct work_struct datawork;
spinlock_t lock;

struct regulator *vcc;
};

static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);

static inline void mxcmci_init_ocr(struct mxcmci_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_avail)
dev_warn(mmc_dev(host->mmc),
"pdata->ocr_avail will not be used\n");
}
#endif
if (host->vcc == NULL) {
/* fall-back to platform data */
if (host->pdata && host->pdata->ocr_avail)
host->mmc->ocr_avail = host->pdata->ocr_avail;
else
host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
}
}

static inline void mxcmci_set_power(struct mxcmci_host *host, unsigned int vdd)
{
#ifdef CONFIG_REGULATOR
if (host->vcc)
mmc_regulator_set_ocr(host->vcc, vdd);
#endif
if (host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc_dev(host->mmc), vdd);
}

static inline int mxcmci_use_dma(struct mxcmci_host *host)
{
return host->do_dma;
Expand Down Expand Up @@ -680,9 +716,9 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;

if (host->power_mode != ios->power_mode) {
if (host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc_dev(mmc), ios->vdd);
mxcmci_set_power(host, ios->vdd);
host->power_mode = ios->power_mode;

if (ios->power_mode == MMC_POWER_ON)
host->cmdat |= CMD_DAT_CONT_INIT;
}
Expand Down Expand Up @@ -807,10 +843,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host->pdata = pdev->dev.platform_data;
spin_lock_init(&host->lock);

if (host->pdata && host->pdata->ocr_avail)
mmc->ocr_avail = host->pdata->ocr_avail;
else
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mxcmci_init_ocr(host);

if (host->pdata && host->pdata->dat3_card_detect)
host->default_irq_mask =
Expand Down Expand Up @@ -915,6 +948,9 @@ static int mxcmci_remove(struct platform_device *pdev)

mmc_remove_host(mmc);

if (host->vcc)
regulator_put(host->vcc);

if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);

Expand Down

0 comments on commit 74b6695

Please sign in to comment.