Skip to content

Commit

Permalink
ARM: OMAP: mmc-twl4030: add regulator sleep / wake function
Browse files Browse the repository at this point in the history
Add the ability for the driver to put the card power regulators to sleep
and wake them up again.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Matt Fleming <matt@console-pimps.org>
Cc: Ian Molton <ian@mnementh.co.uk>
Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com>
Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Cc: Denis Karpov <ext-denis.2.karpov@nokia.com>
Cc: Pierre Ossman <pierre@ossman.eu>
Cc: Philip Langdale <philipl@overt.org>
Cc: "Madhusudhan" <madhu.cr@ti.com>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Adrian Hunter authored and Linus Torvalds committed Sep 23, 2009
1 parent dd498ef commit 9b7c18e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
57 changes: 57 additions & 0 deletions arch/arm/mach-omap2/mmc-twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v
return ret;
}

static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
int cardsleep)
{
struct twl_mmc_controller *c = &hsmmc[0];
int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;

return regulator_set_mode(c->vcc, mode);
}

static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd,
int cardsleep)
{
struct twl_mmc_controller *c = NULL;
struct omap_mmc_platform_data *mmc = dev->platform_data;
int i, err, mode;

for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
if (mmc == hsmmc[i].mmc) {
c = &hsmmc[i];
break;
}
}

if (c == NULL)
return -ENODEV;

/*
* If we don't see a Vcc regulator, assume it's a fixed
* voltage always-on regulator.
*/
if (!c->vcc)
return 0;

mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;

if (!c->vcc_aux)
return regulator_set_mode(c->vcc, mode);

if (cardsleep) {
/* VCC can be turned off if card is asleep */
struct regulator *vcc_aux = c->vcc_aux;

c->vcc_aux = NULL;
if (sleep)
err = twl_mmc23_set_power(dev, slot, 0, 0);
else
err = twl_mmc23_set_power(dev, slot, 1, vdd);
c->vcc_aux = vcc_aux;
} else
err = regulator_set_mode(c->vcc, mode);
if (err)
return err;
return regulator_set_mode(c->vcc_aux, mode);
}

static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;

void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
Expand Down Expand Up @@ -433,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
case 1:
/* on-chip level shifting via PBIAS0/PBIAS1 */
mmc->slots[0].set_power = twl_mmc1_set_power;
mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
break;
case 2:
if (c->ext_clock)
Expand All @@ -443,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
case 3:
/* off-chip level shifting, or none */
mmc->slots[0].set_power = twl_mmc23_set_power;
mmc->slots[0].set_sleep = twl_mmc23_set_sleep;
break;
default:
pr_err("MMC%d configuration not supported!\n", c->mmc);
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/plat-omap/include/mach/mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ struct omap_mmc_platform_data {
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
int (* get_ro)(struct device *dev, int slot);
int (*set_sleep)(struct device *dev, int slot, int sleep,
int vdd, int cardsleep);

/* return MMC cover switch state, can be NULL if not supported.
*
Expand Down

0 comments on commit 9b7c18e

Please sign in to comment.