summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2012-02-24 11:29:27 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:01 +0200
commitd7d57e67456f336f10f7e9fcb4b39ac34d3e7f2a (patch)
tree991298be1075e93b24c82db8b361f4a69216e84c
parentbe2ec17ae364a4e1e6595ad5d620062df149a9ca (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>
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c43
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;
}