From 20a22cc9d4f7da1aec4e26d710f385078d78c2b9 Mon Sep 17 00:00:00 2001 From: xbw Date: Sun, 12 Aug 2012 13:20:07 +0800 Subject: [PATCH] SDMMC: add the power-off after closing of removing the card --- arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c | 2 + drivers/mmc/host/rk29_sdmmc.c | 101 +++++++++++----------- 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c b/arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c index 817269750485..d57ef3c84572 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c +++ b/arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c @@ -140,11 +140,13 @@ static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width) gpio_request(RK30_PIN3_PA7,"sdmmc-power"); gpio_direction_output(RK30_PIN3_PA7,GPIO_HIGH); //power-off + #if 0 //replace the power control into rk29_sdmmc_set_ios(); modifyed by xbw at 2012-08-12 rk29_sdmmc_gpio_open(0, 0); gpio_direction_output(RK30_PIN3_PA7,GPIO_LOW); //power-on rk29_sdmmc_gpio_open(0, 1); + #endif } break; diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index d2d600ab7e53..95e52dfda300 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -69,6 +69,16 @@ int debug_level = 5; #define SDMMC_USE_INT_UNBUSY 1 #endif +#if defined(CONFIG_ARCH_RK29) +#define RK29_SDMMC0DETECTN_GPIO RK29_PIN2_PA2 +#define RK29_SDMMC0PWREN_GPIO RK29_PIN5_PD5 + +#elif defined(CONFIG_ARCH_RK30) +#define RK29_SDMMC0DETECTN_GPIO RK30_PIN3_PB6 +#define RK29_SDMMC0PWREN_GPIO RK30_PIN3_PA7 + +#endif + #define RK29_SDMMC_ERROR_FLAGS (SDMMC_INT_FRUN | SDMMC_INT_HLE ) #if SDMMC_USE_INT_UNBUSY @@ -84,7 +94,7 @@ int debug_level = 5; #define RK29_SDMMC_WAIT_DTO_INTERNVAL 4500 //The time interval from the CMD_DONE_INT to DTO_INT #define RK29_SDMMC_REMOVAL_DELAY 2000 //The time interval from the CD_INT to detect_timer react. -#define RK29_SDMMC_VERSION "Ver.4.01 The last modify date is 2012-08-09" +#define RK29_SDMMC_VERSION "Ver.4.02 The last modify date is 2012-08-12" #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) #define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC @@ -1438,7 +1448,7 @@ static int sdmmc_send_cmd_start(struct rk29_sdmmc *host, unsigned int cmd) udelay(2); } - if(!tmo) + if(!tmo && test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags)) { printk(KERN_WARNING "%s.. %d set cmd(value=0x%x) register timeout error ! [%s]\n",\ __FUNCTION__,__LINE__, cmd, host->dma_name); @@ -2288,13 +2298,22 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { case MMC_POWER_UP: rk29_sdmmc_write(host->regs, SDMMC_PWREN, POWER_ENABLE); - + //reset the controller if it is SDMMC0 if(RK29_CTRL_SDMMC_ID == host->pdev->id) { xbwprintk(7, "%s..%d..POWER_UP, call reset_controller, initialized_flags=%d [%s]\n",\ __FUNCTION__, __LINE__, host->mmc->re_initialized_flags,host->dma_name); + #if defined(CONFIG_ARCH_RK29) + //power-on; (#define RK29_SDMMC0PWREN_GPIO RK29_PIN5_PD5 in RK2918 platform) + gpio_direction_output(RK29_SDMMC0PWREN_GPIO,GPIO_LOW); + #elif defined(CONFIG_ARCH_RK30) + //power-on; (#define RK29_SDMMC0PWREN_GPIO RK30_PIN3_PA7 in RK3066 platform) + gpio_direction_output(RK29_SDMMC0PWREN_GPIO,GPIO_LOW); + #endif + //printk("##########vcc_sd power on##########\n"); + mdelay(5); rk29_sdmmc_hw_init(host); @@ -2307,7 +2326,7 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { rk29_sdmmc_control_clock(host, FALSE); rk29_sdmmc_write(host->regs, SDMMC_PWREN, POWER_DISABLE); - + if(5 == host->bus_mode) { mdelay(5); @@ -2316,6 +2335,16 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) rk29_sdmmc_reset_controller(host); } + + #if defined(CONFIG_ARCH_RK29) + //power-off + gpio_direction_output(RK29_SDMMC0PWREN_GPIO,GPIO_HIGH); + + #elif defined(CONFIG_ARCH_RK30) + //power-off + gpio_direction_output(RK29_SDMMC0PWREN_GPIO,GPIO_HIGH); + #endif + //printk("##########vcc_sd power off##########\n"); } @@ -3558,11 +3587,12 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) host->write_protect = pdata->write_prt; #endif - - if(RK29_CTRL_SDMMC_ID != host->pdev->id) +#if 0 + if(RK29_CTRL_SDMMC_ID == host->pdev->id) { rk29_sdmmc_hw_init(host); } +#endif ret = request_irq(host->irq, rk29_sdmmc_interrupt, 0, dev_name(&pdev->dev), host); if (ret) @@ -3731,12 +3761,11 @@ static int __exit rk29_sdmmc_remove(struct platform_device *pdev) #ifdef CONFIG_PM -#if defined(CONFIG_ARCH_RK29) static irqreturn_t det_keys_isr(int irq, void *dev_id) { struct rk29_sdmmc *host = dev_id; dev_info(&host->pdev->dev, "sd det_gpio changed(%s), send wakeup key!\n", - gpio_get_value(RK29_PIN2_PA2)?"removed":"insert"); + gpio_get_value(RK29_SDMMC0DETECTN_GPIO)?"removed":"insert"); rk29_sdmmc_detect_change((unsigned long)dev_id); return IRQ_HANDLED; @@ -3745,49 +3774,19 @@ static irqreturn_t det_keys_isr(int irq, void *dev_id) static int rk29_sdmmc_sdcard_suspend(struct rk29_sdmmc *host) { int ret = 0; - rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2); - gpio_request(RK29_PIN2_PA2, "sd_detect"); - gpio_direction_input(RK29_PIN2_PA2); - - host->gpio_irq = gpio_to_irq(RK29_PIN2_PA2); - ret = request_irq(host->gpio_irq, det_keys_isr, - (gpio_get_value(RK29_PIN2_PA2))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, - "sd_detect", - host); - enable_irq_wake(host->gpio_irq); - - return ret; -} -static void rk29_sdmmc_sdcard_resume(struct rk29_sdmmc *host) -{ - disable_irq_wake(host->gpio_irq); - free_irq(host->gpio_irq,host); - gpio_free(RK29_PIN2_PA2); - rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N); -} - +#if defined(CONFIG_ARCH_RK29) + rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2); #elif defined(CONFIG_ARCH_RK30) -static irqreturn_t det_keys_isr(int irq, void *dev_id) -{ - struct rk29_sdmmc *host = dev_id; - dev_info(&host->pdev->dev, "sd det_gpio changed(%s), send wakeup key!\n", - gpio_get_value(RK30_PIN3_PB6)?"removed":"insert"); - rk29_sdmmc_detect_change((unsigned long)dev_id); - - return IRQ_HANDLED; -} - -static int rk29_sdmmc_sdcard_suspend(struct rk29_sdmmc *host) -{ - int ret = 0; rk29_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME, GPIO3B_GPIO3B6); - gpio_request(RK30_PIN3_PB6, "sd_detect"); - gpio_direction_input(RK30_PIN3_PB6); +#endif + + gpio_request(RK29_SDMMC0DETECTN_GPIO, "sd_detect"); + gpio_direction_input(RK29_SDMMC0DETECTN_GPIO); - host->gpio_irq = gpio_to_irq(RK30_PIN3_PB6); + host->gpio_irq = gpio_to_irq(RK29_SDMMC0DETECTN_GPIO); ret = request_irq(host->gpio_irq, det_keys_isr, - (gpio_get_value(RK30_PIN3_PB6))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, + (gpio_get_value(RK29_SDMMC0DETECTN_GPIO))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, "sd_detect", host); @@ -3799,13 +3798,15 @@ static void rk29_sdmmc_sdcard_resume(struct rk29_sdmmc *host) { disable_irq_wake(host->gpio_irq); free_irq(host->gpio_irq,host); - gpio_free(RK30_PIN3_PB6); + gpio_free(RK29_SDMMC0DETECTN_GPIO); + +#if defined(CONFIG_ARCH_RK29) + rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N); +#elif defined(CONFIG_ARCH_RK30) rk29_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME, GPIO3B_SDMMC0_DETECT_N); +#endif } -#endif - - static int rk29_sdmmc_suspend(struct platform_device *pdev, pm_message_t state) { struct mmc_host *mmc = platform_get_drvdata(pdev); -- 2.34.1