aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorBalaji Rao <balajirrao@openmoko.org>2009-01-28 19:30:42 +0000
committerAndy Green <agreen@octopus.localdomain>2009-01-28 19:30:42 +0000
commit9d1fd9e7b19d66a35ee4e760b30a3b9a168c20a2 (patch)
tree48f4ebb86706de06434d8ba582f58b5a7c9ecb51 /drivers/mmc/host
parent11afa2f75c68eb2c984ea43a92b8e453b8b70e49 (diff)
Subject: pcf50606_rebase_changes,patch
X-Git-Url: http://git.openmoko.org/?p=kernel.git;a=commitdiff_plain;h=938eddf17625cce0307f7612a3ea2560384e2384 pcf50606_rebase_changes,patch This patch brings into andy-tracking all changes related to pcf50606 from old balaji-tracking.
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/s3cmci.c53
-rw-r--r--drivers/mmc/host/s3cmci.h3
2 files changed, 50 insertions, 6 deletions
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 45c5192869b..a014b669fe4 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1109,18 +1109,42 @@ static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios)
host->real_rate = 0;
}
+static int s3cmci_get_mv(int vdd)
+{
+ int mv = 1700; /* 1.7V for MMC_VDD_165_195 */
+ int bit;
+
+ for (bit = 0; bit != 24; bit++)
+ if (vdd == (1 << bit))
+ mv += 100 * (bit - 4);
+
+ return mv;
+}
+
static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct s3cmci_host *host = mmc_priv(mmc);
u32 mci_con;
+ struct regulator *regulator;
+ int mv;
/* Set the power state */
mci_con = readl(host->base + S3C2410_SDICON);
+ regulator = host->regulator;
+
switch (ios->power_mode) {
- case MMC_POWER_ON:
case MMC_POWER_UP:
+ if (regulator) {
+ mv = s3cmci_get_mv(ios->vdd);
+ regulator_set_voltage(regulator, mv * 1000, mv * 1000);
+ regulator_enable(regulator);
+ } else if (host->pdata->set_power) {
+ host->pdata->set_power(ios->power_mode, ios->vdd);
+ } else
+ dev_err(&host->pdev->dev, "Can't MMC_POWERUP\n");
+ case MMC_POWER_ON:
s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
@@ -1128,26 +1152,37 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
- if (host->pdata->set_power)
+ if (regulator) {
+ mv = s3cmci_get_mv(ios->vdd);
+ regulator_set_voltage(regulator, mv * 1000, mv * 1000);
+ } else if (host->pdata->set_power) {
host->pdata->set_power(ios->power_mode, ios->vdd);
-
+ } else
+ dev_err(&host->pdev->dev, "Can't MMC_POWERON\n");
+
if (!host->is2440)
mci_con |= S3C2410_SDICON_FIFORESET;
break;
case MMC_POWER_OFF:
- default:
s3c2410_gpio_setpin(S3C2410_GPE5, 0);
s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
if (host->is2440)
mci_con |= S3C2440_SDICON_SDRESET;
- if (host->pdata->set_power)
+ if (regulator) {
+ if (regulator_is_enabled(regulator))
+ regulator_disable(regulator);
+ } else if (host->pdata->set_power) {
host->pdata->set_power(ios->power_mode, ios->vdd);
-
+ } else
+ dev_err(&host->pdev->dev, "Can't MMC_POWEROFF\n");
+
break;
+ default:
+ printk(KERN_ERR "No such power mode %d\n", ios->power_mode);
}
s3cmci_set_clk(host, ios);
@@ -1429,6 +1464,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
goto free_dmabuf;
}
+ host->regulator = regulator_get(&pdev->dev, "SD_3V3");
+ if (IS_ERR(host->regulator)) {
+ dev_err(&pdev->dev, "Regulator for SD_3V3 unavilable \n");
+ host->regulator = NULL;
+ }
+
ret = mmc_add_host(mmc);
if (ret) {
dev_err(&pdev->dev, "failed to add mmc host.\n");
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index c2b65b3488b..7f80047ee8c 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -10,6 +10,7 @@
#include <mach/regs-sdi.h>
+#include <linux/regulator/consumer.h>
/* FIXME: DMA Resource management ?! */
#define S3CMCI_DMA 0
@@ -81,4 +82,6 @@ struct s3cmci_host {
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
#endif
+
+ struct regulator *regulator;
};