diff options
author | Philippe Langlais <philippe.langlais@linaro.org> | 2011-05-05 13:56:17 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 15:15:00 +0200 |
commit | f890cdd6930624fb2ff8041128c80ae5fe406dd7 (patch) | |
tree | cb91466c474535a436288094bf94b8be8f7334a4 | |
parent | 88f4814d93373a0f7686ce624f0ccbe6abd22303 (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.c | 51 |
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 | |