diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2012-02-24 11:29:27 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:03:01 +0200 |
commit | d7d57e67456f336f10f7e9fcb4b39ac34d3e7f2a (patch) | |
tree | 991298be1075e93b24c82db8b361f4a69216e84c /arch/arm | |
parent | be2ec17ae364a4e1e6595ad5d620062df149a9ca (diff) |
ARM: u8500: board-sdi: ios_handler handles voltage switch
The ios_handler, which is used for SD-cards, is now able to
switch voltage level between 3V and 1.8V. This is needed to
support UHS-I card which supports 1.8V I/O.
Change-Id: I3f2d467a384c6b672064ec1d993c6d8b1acba7e5
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/50398
Reviewed-by: QABUILD
Reviewed-by: Per FORLIN <per.forlin@stericsson.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 9fb8cae0dbc..19dbf5ca68a 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -38,8 +38,37 @@ static int sdi0_vsel = -1; static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) { - static int power_mode = -1; + static unsigned char power_mode = MMC_POWER_ON; + static unsigned char signal_voltage = MMC_SIGNAL_VOLTAGE_330; + if (signal_voltage == ios->signal_voltage) + goto do_power; + + /* + * We need to re-init the levelshifter when switching I/O voltage level. + * Max discharge time according to ST6G3244ME spec is 1 ms. + */ + if (power_mode == MMC_POWER_ON) { + power_mode = MMC_POWER_OFF; + gpio_direction_output(sdi0_en, 0); + msleep(1); + } + + switch (ios->signal_voltage) { + case MMC_SIGNAL_VOLTAGE_330: + gpio_direction_output(sdi0_vsel, 0); + break; + case MMC_SIGNAL_VOLTAGE_180: + gpio_direction_output(sdi0_vsel, 1); + break; + default: + pr_warning("Non supported signal voltage for levelshifter.\n"); + break; + } + + signal_voltage = ios->signal_voltage; + +do_power: if (power_mode == ios->power_mode) return 0; @@ -47,25 +76,17 @@ static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) case MMC_POWER_UP: break; case MMC_POWER_ON: - /* - * Level shifter voltage should depend on vdd to when deciding - * on either 1.8V or 2.9V. Once the decision has been made the - * level shifter must be disabled and re-enabled with a changed - * select signal in order to switch the voltage. Since there is - * no framework support yet for indicating 1.8V in vdd, use the - * default 2.9V. - */ - gpio_direction_output(sdi0_vsel, 0); gpio_direction_output(sdi0_en, 1); + /* Max settling time according to ST6G3244ME spec is 100 us. */ udelay(100); break; case MMC_POWER_OFF: - gpio_direction_output(sdi0_vsel, 0); gpio_direction_output(sdi0_en, 0); break; } power_mode = ios->power_mode; + return 0; } |