SDMMC: add the power-off after closing of removing the card
authorxbw <xbw@rock-chips.com>
Sun, 12 Aug 2012 05:20:07 +0000 (13:20 +0800)
committerxbw <xbw@rock-chips.com>
Sun, 12 Aug 2012 05:31:11 +0000 (13:31 +0800)
arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c
drivers/mmc/host/rk29_sdmmc.c

index 8172697504854f96e93ad95ac673ddc00fed0419..d57ef3c845726084676ba62b4e70fa828a75c241 100755 (executable)
@@ -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;
 
index d2d600ab7e536a786435eca5681acd8a965ab4a9..95e52dfda300bb08865bdc529a07ccd9e9847068 100755 (executable)
@@ -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);