Skip to content

Commit

Permalink
omap: RX51: Remux to pull eMMC lines down when powering off
Browse files Browse the repository at this point in the history
It has been discovered that, when eMMC is powered off, current
will flow from OMAP eMMC data pull-ups to the eMMC voltage supply.
Configuring pads for OMAP off-mode does not help because eMMC is
powered off independently of OMAP off-mode.  Hence the pads are
now re-configured when eMMC is powered on or off.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
  • Loading branch information
Adrian Hunter authored and Tony Lindgren committed Feb 15, 2010
1 parent e3df0fb commit ce6f001
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
43 changes: 42 additions & 1 deletion arch/arm/mach-omap2/board-rx51-peripherals.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,46 @@ static struct twl4030_madc_platform_data rx51_madc_data = {
.irq_line = 1,
};

/* Enable input logic and pull all lines up when eMMC is on. */
static struct omap_board_mux rx51_mmc2_on_mux[] = {
OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};

/* Disable input logic and pull all lines down when eMMC is off. */
static struct omap_board_mux rx51_mmc2_off_mux[] = {
OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0),
OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};

/*
* Current flows to eMMC when eMMC is off and the data lines are pulled up,
* so pull them down. N.B. we pull 8 lines because we are using 8 lines.
*/
static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
{
if (power_on)
omap_mux_write_array(rx51_mmc2_on_mux);
else
omap_mux_write_array(rx51_mmc2_off_mux);
}

static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "external",
Expand All @@ -222,11 +262,12 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
{
.name = "internal",
.mmc = 2,
.wires = 8,
.wires = 8, /* See also rx51_mmc2_remux */
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.nonremovable = true,
.power_saving = true,
.remux = rx51_mmc2_remux,
},
{} /* Terminator */
};
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/mach-omap2/hsmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ static void hsmmc1_before_set_reg(struct device *dev, int slot,
u32 reg, prog_io;
struct omap_mmc_platform_data *mmc = dev->platform_data;

if (mmc->slots[0].remux)
mmc->slots[0].remux(dev, slot, power_on);

/*
* Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
* card with Vcc regulator (from twl4030 or whatever). OMAP has both
Expand Down Expand Up @@ -121,6 +124,9 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot,
{
struct omap_mmc_platform_data *mmc = dev->platform_data;

if (mmc->slots[0].remux)
mmc->slots[0].remux(dev, slot, power_on);

if (power_on) {
/* Only MMC2 supports a CLKIN */
if (mmc->slots[0].internal_clock) {
Expand Down Expand Up @@ -185,6 +191,8 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
mmc->slots[0].switch_pin = c->gpio_cd;
mmc->slots[0].gpio_wp = c->gpio_wp;

mmc->slots[0].remux = c->remux;

if (c->cover_only)
mmc->slots[0].cover = 1;

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-omap2/hsmmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct omap2_hsmmc_info {
char *name; /* or NULL for default */
struct device *dev; /* returned: pointer to mmc adapter */
int ocr_mask; /* temporary HACK */
/* Remux (pad configuation) when powering on/off */
void (*remux)(struct device *dev, int slot, int power_on);
};

#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
Expand Down
1 change: 1 addition & 0 deletions arch/arm/plat-omap/include/plat/mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ struct omap_mmc_platform_data {
int (*get_ro)(struct device *dev, int slot);
int (*set_sleep)(struct device *dev, int slot, int sleep,
int vdd, int cardsleep);
void (*remux)(struct device *dev, int slot, int power_on);
/* Call back before enabling / disabling regulators */
void (*before_set_reg)(struct device *dev, int slot,
int power_on, int vdd);
Expand Down

0 comments on commit ce6f001

Please sign in to comment.