summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-05-05 13:56:17 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:15:00 +0200
commitf890cdd6930624fb2ff8041128c80ae5fe406dd7 (patch)
treecb91466c474535a436288094bf94b8be8f7334a4
parent88f4814d93373a0f7686ce624f0ccbe6abd22303 (diff)
mach-ux500: Add SDIO VDD handler for GPIO config
It seems as PL18X does not drive all pins in a correct way when the block is powered but not initialized. Since CW1200 is sensitive to this (it samples the DAT2 signal level on bootup to choose between SPI and SDIO mode), it must be assured that the pins are in a correct state at all times. This is done by adding a VDD handler for SDI1 which reconfigures all the pins to GPIO pins with pullups when PL18X is not in an initialized state. ST-Ericsson ID: 327586 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ic3bbe24f13c32203ad1f5fd3fef22ef25996568e Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18619 Reviewed-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com> Reviewed-by: Linus WALLEIJ <linus.walleij@stericsson.com> Conflicts: arch/arm/mach-ux500/board-mop500-sdi.c
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 3935e054b14..cd2eedd2fb1 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <asm/mach-types.h>
+#include <plat/pincfg.h>
#include <plat/ste_dma40.h>
#include <mach/devices.h>
#include <mach/hardware.h>
@@ -124,10 +125,60 @@ static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
#endif
/*
+ * Reconfigures a GPIO pin with a given number to either ALT_A or
+ * GPIO input pin with pull ups.
+ */
+static void sdio_config_gpio(struct device *dev,
+ bool cfg_for_mmc,
+ int gpio_pin_nbr)
+{
+ int err;
+ pin_cfg_t p = gpio_pin_nbr;
+
+ if (cfg_for_mmc)
+ p |= PIN_ALT_A | PIN_INPUT_PULLUP;
+ else
+ p |= PIN_GPIO | PIN_INPUT_PULLUP;
+
+ err = nmk_config_pin(p, false);
+ if (err)
+ dev_err(dev,
+ "error %i while reconfiguring pin %i to %s mode!\n",
+ err, gpio_pin_nbr, cfg_for_mmc ? "ALT_A" : "GPIO");
+}
+
+/*
+ * Reconfigure all SDI1 pins to GPIO when SDI1 is not used since PL18X seems
+ * to drive some of them incorrectly when powered but not initialized.
+ */
+static u32 sdi1_vdd_handler(struct device *dev, unsigned int vdd,
+ unsigned char power_mode)
+{
+ switch (power_mode) {
+ case MMC_POWER_ON:
+ sdio_config_gpio(dev, true, 210);
+ sdio_config_gpio(dev, true, 211);
+ sdio_config_gpio(dev, true, 212);
+ sdio_config_gpio(dev, true, 213);
+ sdio_config_gpio(dev, true, 214);
+ break;
+ case MMC_POWER_OFF:
+ sdio_config_gpio(dev, false, 210);
+ sdio_config_gpio(dev, false, 211);
+ sdio_config_gpio(dev, false, 212);
+ sdio_config_gpio(dev, false, 213);
+ sdio_config_gpio(dev, false, 214);
+ break;
+ }
+ return 0;
+}
+
+/*
* TODO 1: SDIO power management not fully supported.
* TODO 2: SDIO with DMA not yet supported.
*/
static struct mmci_platform_data mop500_sdi1_data = {
+ .vdd_handler = sdi1_vdd_handler,
.ocr_mask = MMC_VDD_29_30,
.f_max = 15000000,
.capabilities = MMC_CAP_4_BIT_DATA |