mmc: msm_sdcc: Handle SD card detection based on polarity
SD card detect GPIO line can be ACTIVE HIGH or ACTIVE LOW based on the way
the board is designed. This change will allow the polarity information to
be used when determining if a card was inserted or removed for a given
board.
CRs-fixed: 318036
Change-Id: I30b96e840a28030af3141fd722383722a24089c8
Signed-off-by: Krishna Konda <kkonda@codeaurora.org>
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index c86fad9..75ec143 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -130,6 +130,8 @@
void (*sdio_lpm_gpio_setup)(struct device *, unsigned int);
unsigned int status_irq;
unsigned int status_gpio;
+ /* Indicates the polarity of the GPIO line when card is inserted */
+ bool is_status_gpio_active_low;
unsigned int sdiowakeup_irq;
unsigned long irq_flags;
unsigned long mmc_bus_width;
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index dfcafd4..8521717 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -247,6 +247,7 @@
.status_gpio = PM8921_GPIO_PM_TO_SYS(26),
.status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ .is_status_gpio_active_low = true,
#endif
.xpc_cap = 1,
.uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index f5bd44d..835a327 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -534,12 +534,12 @@
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
static unsigned int sdc1_sup_clk_rates[] = {
- 400000, 24000000, 48000000
+ 400000, 24000000, 48000000,
};
static struct mmc_platform_data sdc1_data = {
- .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
- .mmc_bus_width = MMC_CAP_4_BIT_DATA,
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .mmc_bus_width = MMC_CAP_4_BIT_DATA,
.sup_clk_table = sdc1_sup_clk_rates,
.sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
.pclk_src_dfab = true,
@@ -552,7 +552,7 @@
#endif
.xpc_cap = 1,
.uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_MAX_CURRENT_400)
+ MMC_CAP_MAX_CURRENT_400),
};
static struct mmc_platform_data *msm9615_sdc1_pdata = &sdc1_data;
#else
@@ -561,7 +561,7 @@
#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
static unsigned int sdc2_sup_clk_rates[] = {
- 400000, 24000000, 48000000
+ 400000, 24000000, 48000000,
};
static struct mmc_platform_data sdc2_data = {
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0410473..0a239da 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2897,7 +2897,7 @@
} else {
status = gpio_direction_input(gpio_no);
if (!status)
- status = !gpio_get_value_cansleep(gpio_no);
+ status = gpio_get_value_cansleep(gpio_no);
gpio_free(gpio_no);
}
return status;
@@ -2910,15 +2910,36 @@
unsigned int status;
if (host->plat->status || host->plat->status_gpio) {
- if (host->plat->status)
+ if (host->plat->status) {
status = host->plat->status(mmc_dev(host->mmc));
- else
+ host->eject = !status;
+ } else {
status = msmsdcc_slot_status(host);
- host->eject = !status;
+ if (host->plat->is_status_gpio_active_low)
+ host->eject = status;
+ else
+ host->eject = !status;
+ }
+
if (status ^ host->oldstat) {
- pr_info("%s: Slot status change detected (%d -> %d)\n",
- mmc_hostname(host->mmc), host->oldstat, status);
+ if (host->plat->status)
+ pr_info("%s: Slot status change detected "
+ "(%d -> %d)\n",
+ mmc_hostname(host->mmc),
+ host->oldstat, status);
+ else if (host->plat->is_status_gpio_active_low)
+ pr_info("%s: Slot status change detected "
+ "(%d -> %d) and the card detect GPIO"
+ " is ACTIVE_LOW\n",
+ mmc_hostname(host->mmc),
+ host->oldstat, status);
+ else
+ pr_info("%s: Slot status change detected "
+ "(%d -> %d) and the card detect GPIO"
+ " is ACTIVE_HIGH\n",
+ mmc_hostname(host->mmc),
+ host->oldstat, status);
mmc_detect_change(host->mmc, 0);
}
host->oldstat = status;
@@ -4049,11 +4070,17 @@
*/
if (plat->status || plat->status_gpio) {
- if (plat->status)
+ if (plat->status) {
host->oldstat = plat->status(mmc_dev(host->mmc));
- else
+ host->eject = !host->oldstat;
+ } else {
host->oldstat = msmsdcc_slot_status(host);
- host->eject = !host->oldstat;
+
+ if (host->plat->is_status_gpio_active_low)
+ host->eject = host->oldstat;
+ else
+ host->eject = !host->oldstat;
+ }
}
if (plat->status_irq) {