Optimize the powe up and down of wifi and SDcard module
authorxbw <xbw@rock-chips.com>
Sat, 22 Oct 2011 03:19:06 +0000 (11:19 +0800)
committerxbw <xbw@rock-chips.com>
Sat, 22 Oct 2011 03:19:06 +0000 (11:19 +0800)
arch/arm/mach-rk29/board-rk29-ddr3sdk.c
arch/arm/mach-rk29/include/mach/board.h
drivers/mmc/core/core.c
drivers/mmc/core/sdio.c [changed mode: 0644->0755]
drivers/mmc/host/Kconfig
drivers/mmc/host/rk29_sdmmc.c
include/linux/mmc/host.h

index 8499e1e44caa055a63eb86aa719838aee04dc465..b4a4239912a6a6b58e52fe36a973f9a12c4dbd62 100755 (executable)
@@ -1835,23 +1835,256 @@ static struct platform_device rk29_device_pwm_regulator = {
 /*****************************************************************************************
  * SDMMC devices
 *****************************************************************************************/
+#if !defined(CONFIG_SDMMC_RK29_OLD)    
+static void rk29_sdmmc_gpio_open(int device_id, int on)
+{
+    switch(device_id)
+    {
+        case 0://mmc0
+        {
+            #ifdef CONFIG_SDMMC0_RK29
+            if(on)
+            {
+                gpio_direction_output(RK29_PIN1_PD0,GPIO_HIGH);//set mmc0-clk to high
+                gpio_direction_output(RK29_PIN1_PD1,GPIO_HIGH);//set mmc0-cmd to high.
+                gpio_direction_output(RK29_PIN1_PD2,GPIO_HIGH);//set mmc0-data0 to high.
+                gpio_direction_output(RK29_PIN1_PD3,GPIO_HIGH);//set mmc0-data1 to high.
+                gpio_direction_output(RK29_PIN1_PD4,GPIO_HIGH);//set mmc0-data2 to high.
+                gpio_direction_output(RK29_PIN1_PD5,GPIO_HIGH);//set mmc0-data3 to high.
+
+                mdelay(30);
+            }
+            else
+            {
+                rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_GPIO1_D0);
+                gpio_request(RK29_PIN1_PD0, "mmc0-clk");
+                gpio_direction_output(RK29_PIN1_PD0,GPIO_LOW);//set mmc0-clk to low.
+
+                rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_GPIO1_D1);
+                gpio_request(RK29_PIN1_PD1, "mmc0-cmd");
+                gpio_direction_output(RK29_PIN1_PD1,GPIO_LOW);//set mmc0-cmd to low.
+
+                rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_GPIO1D2);
+                gpio_request(RK29_PIN1_PD2, "mmc0-data0");
+                gpio_direction_output(RK29_PIN1_PD2,GPIO_LOW);//set mmc0-data0 to low.
+
+                rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_GPIO1D3);
+                gpio_request(RK29_PIN1_PD3, "mmc0-data1");
+                gpio_direction_output(RK29_PIN1_PD3,GPIO_LOW);//set mmc0-data1 to low.
+
+                rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_GPIO1D4);
+                gpio_request(RK29_PIN1_PD4, "mmc0-data2");
+                gpio_direction_output(RK29_PIN1_PD4,GPIO_LOW);//set mmc0-data2 to low.
+
+                rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_GPIO1D5);
+                gpio_request(RK29_PIN1_PD5, "mmc0-data3");
+                gpio_direction_output(RK29_PIN1_PD5,GPIO_LOW);//set mmc0-data3 to low.
+
+                mdelay(30);
+            }
+            #endif
+        }
+        break;
+        
+        case 1://mmc1
+        {
+            #ifdef CONFIG_SDMMC1_RK29
+            if(on)
+            {
+                gpio_direction_output(RK29_PIN1_PC7,GPIO_HIGH);//set mmc1-clk to high
+                gpio_direction_output(RK29_PIN1_PC2,GPIO_HIGH);//set mmc1-cmd to high.
+                gpio_direction_output(RK29_PIN1_PC3,GPIO_HIGH);//set mmc1-data0 to high.
+                gpio_direction_output(RK29_PIN1_PC4,GPIO_HIGH);//set mmc1-data1 to high.
+                gpio_direction_output(RK29_PIN1_PC5,GPIO_HIGH);//set mmc1-data2 to high.
+                gpio_direction_output(RK29_PIN1_PC6,GPIO_HIGH);//set mmc1-data3 to high.
+                mdelay(100);
+            }
+            else
+            {
+                rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_GPIO1C7);
+                gpio_request(RK29_PIN1_PC7, "mmc1-clk");
+                gpio_direction_output(RK29_PIN1_PC7,GPIO_LOW);//set mmc1-clk to low.
+
+                rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_GPIO1C2);
+                gpio_request(RK29_PIN1_PC2, "mmc1-cmd");
+                gpio_direction_output(RK29_PIN1_PC2,GPIO_LOW);//set mmc1-cmd to low.
+
+                rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_GPIO1C3);
+                gpio_request(RK29_PIN1_PC3, "mmc1-data0");
+                gpio_direction_output(RK29_PIN1_PC3,GPIO_LOW);//set mmc1-data0 to low.
+
+                mdelay(100);
+            }
+            #endif
+        }
+        break; 
+        
+        case 2: //mmc2
+        break;
+        
+        default:
+        break;
+    }
+}
+
+static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width)
+{
+    switch (bus_width)
+    {
+        
+       case 1://SDMMC_CTYPE_4BIT:
+       {
+               rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
+               rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
+               rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
+       }
+       break;
+
+       case 0x10000://SDMMC_CTYPE_8BIT:
+           break;
+       case 0xFFFF: //gpio_reset
+       {
+            rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   
+            gpio_request(RK29_PIN5_PD5,"sdmmc-power");
+            gpio_direction_output(RK29_PIN5_PD5,GPIO_HIGH); //power-off
+
+            rk29_sdmmc_gpio_open(0, 0);
+
+            gpio_direction_output(RK29_PIN5_PD5,GPIO_LOW); //power-on
+
+            rk29_sdmmc_gpio_open(0, 1);
+       }
+       break;
+
+       default: //case 0://SDMMC_CTYPE_1BIT:
+        {
+               rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
+               rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT);
+               rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0);
+
+               rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_GPIO1D3);
+               gpio_request(RK29_PIN1_PD3, "mmc0-data1");
+               gpio_direction_output(RK29_PIN1_PD3,GPIO_HIGH);
+
+               rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_GPIO1D4);
+               gpio_request(RK29_PIN1_PD4, "mmc0-data2");
+               gpio_direction_output(RK29_PIN1_PD4,GPIO_HIGH);
+               
+            rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_GPIO1D5);
+            gpio_request(RK29_PIN1_PD5, "mmc0-data3");
+               gpio_direction_output(RK29_PIN1_PD5,GPIO_HIGH);
+       }
+       break;
+       }
+}
+
+static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width)
+{
+#if 0
+    switch (bus_width)
+    {
+        
+       case 1://SDMMC_CTYPE_4BIT:
+       {
+            rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
+            rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
+            rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
+            rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_SDMMC1_DATA1);
+            rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2);
+            rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
+       }
+       break;
+
+       case 0x10000://SDMMC_CTYPE_8BIT:
+           break;
+       case 0xFFFF:
+       {
+          rk29_sdmmc_gpio_open(1, 0); 
+          rk29_sdmmc_gpio_open(1, 1);
+       }
+       break;
+
+       default: //case 0://SDMMC_CTYPE_1BIT:
+        {
+            rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
+               rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
+               rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
+
+            rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_GPIO1C4);
+            gpio_request(RK29_PIN1_PC4, "mmc1-data1");
+               gpio_direction_output(RK29_PIN1_PC4,GPIO_HIGH);
+               
+            rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_GPIO1C5);
+            gpio_request(RK29_PIN1_PC5, "mmc1-data2");
+               gpio_direction_output(RK29_PIN1_PC5,GPIO_HIGH);
+
+            rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_GPIO1C6);
+            gpio_request(RK29_PIN1_PC6, "mmc1-data3");
+               gpio_direction_output(RK29_PIN1_PC6,GPIO_HIGH);
+
+       }
+       break;
+       }
+#else
+    rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
+    rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
+    rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
+    rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_SDMMC1_DATA1);
+    rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2);
+    rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
+
+#endif
+}
+
+static void rk29_sdmmc_set_iomux_mmc2(unsigned int bus_width)
+{
+    ;//
+}
+
+
+static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
+{
+    switch(device_id)
+    {
+        case 0:
+            #ifdef CONFIG_SDMMC0_RK29
+            rk29_sdmmc_set_iomux_mmc0(bus_width);
+            #endif
+            break;
+        case 1:
+            #ifdef CONFIG_SDMMC1_RK29
+            rk29_sdmmc_set_iomux_mmc1(bus_width);
+            #endif
+            break;
+        case 2:
+            rk29_sdmmc_set_iomux_mmc2(bus_width);
+            break;
+        default:
+            break;
+    }    
+}
+
+#endif
+
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+static int rk29sdk_wifi_status(struct device *dev);
+static int rk29sdk_wifi_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id);
+#endif
+
 #ifdef CONFIG_SDMMC0_RK29
 static int rk29_sdmmc0_cfg_gpio(void)
 {
-       rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
+#ifdef CONFIG_SDMMC_RK29_OLD   
+    rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
        rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT);
        rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0);
        rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
        rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
        rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
-
-#ifdef CONFIG_SDMMC_RK29_OLD   
+       
        rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2);
-#else
-       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
-#endif
 
-       rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   ///GPIO5H_SDMMC0_PWR_EN);  ///GPIO5H_GPIO5D5);
+    rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   ///GPIO5H_SDMMC0_PWR_EN);  ///GPIO5H_GPIO5D5);
        gpio_request(RK29_PIN5_PD5,"sdmmc");
 #if 0
        gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH);
@@ -1861,9 +2094,16 @@ static int rk29_sdmmc0_cfg_gpio(void)
        gpio_direction_output(RK29_PIN5_PD5,GPIO_LOW);
 #endif
 
-#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+#else
+    rk29_sdmmc_set_iomux(0, 0xFFFF);
+    
+       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
+
+       #if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
     gpio_request(SDMMC0_WRITE_PROTECT_PIN,"sdmmc-wp");
     gpio_direction_input(SDMMC0_WRITE_PROTECT_PIN);        
+    #endif
+
 #endif
 
        return 0;
@@ -1876,6 +2116,11 @@ struct rk29_sdmmc_platform_data default_sdmmc0_data = {
                                           MMC_VDD_33_34|MMC_VDD_34_35| MMC_VDD_35_36),
        .host_caps      = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
        .io_init = rk29_sdmmc0_cfg_gpio,
+       
+#if !defined(CONFIG_SDMMC_RK29_OLD)            
+       .set_iomux = rk29_sdmmc_set_iomux,
+#endif
+
        .dma_name = "sd_mmc",
 #ifdef CONFIG_SDMMC0_USE_DMA
        .use_dma  = 1,
@@ -1896,6 +2141,7 @@ struct rk29_sdmmc_platform_data default_sdmmc0_data = {
 #define CONFIG_SDMMC1_USE_DMA
 static int rk29_sdmmc1_cfg_gpio(void)
 {
+#if defined(CONFIG_SDMMC_RK29_OLD)
        rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
        rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
        rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
@@ -1904,17 +2150,19 @@ static int rk29_sdmmc1_cfg_gpio(void)
        rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
        //rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_SDMMC1_DETECT_N);
 
+#else
+
 #if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
     gpio_request(SDMMC1_WRITE_PROTECT_PIN,"sdio-wp");
     gpio_direction_input(SDMMC1_WRITE_PROTECT_PIN);        
 #endif
+
+#endif
+
        return 0;
 }
 
-#ifdef CONFIG_WIFI_CONTROL_FUNC
-static int rk29sdk_wifi_status(struct device *dev);
-static int rk29sdk_wifi_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id);
-#endif
+
 
 #define RK29SDK_WIFI_SDIO_CARD_DETECT_N    RK29_PIN1_PD6
 
@@ -1922,15 +2170,28 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
        .host_ocr_avail = (MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|
                                           MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32|
                                           MMC_VDD_32_33|MMC_VDD_33_34),
+
+#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)                                    
        .host_caps      = (MMC_CAP_4_BIT_DATA|MMC_CAP_SDIO_IRQ|
                                   MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
+#else
+    .host_caps         = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
+#endif
+
        .io_init = rk29_sdmmc1_cfg_gpio,
+       
+#if !defined(CONFIG_SDMMC_RK29_OLD)            
+       .set_iomux = rk29_sdmmc_set_iomux,
+#endif 
+
        .dma_name = "sdio",
 #ifdef CONFIG_SDMMC1_USE_DMA
        .use_dma  = 1,
 #else
        .use_dma = 0,
 #endif
+
+#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
 #ifdef CONFIG_WIFI_CONTROL_FUNC
         .status = rk29sdk_wifi_status,
         .register_status_notify = rk29sdk_wifi_status_register,
@@ -1943,11 +2204,21 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
     .write_prt = SDMMC1_WRITE_PROTECT_PIN,
 #else
     .write_prt = INVALID_GPIO, 
-#endif    
+#endif  
 
-};
+#else
+//for wifi develop board
+    .detect_irq = INVALID_GPIO,
+    .enable_sd_wakeup = 0,
 #endif
 
+};
+#endif ////endif--#ifdef CONFIG_SDMMC1_RK29
+
+
+int rk29sdk_wifi_power_state = 0;
+int rk29sdk_bt_power_state = 0;
+
 #ifdef CONFIG_WIFI_CONTROL_FUNC
 #define RK29SDK_WIFI_BT_GPIO_POWER_N       RK29_PIN5_PD6
 #define RK29SDK_WIFI_GPIO_RESET_N          RK29_PIN6_PC0
@@ -1956,8 +2227,6 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
 static int rk29sdk_wifi_cd = 0;   /* wifi virtual 'card detect' status */
 static void (*wifi_status_cb)(int card_present, void *dev_id);
 static void *wifi_status_cb_devid;
-int rk29sdk_wifi_power_state = 0;
-int rk29sdk_bt_power_state = 0;
 
 static int rk29sdk_wifi_status(struct device *dev)
 {
@@ -1996,6 +2265,22 @@ static int rk29sdk_wifi_bt_gpio_control_init(void)
     gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N,    GPIO_LOW);
     gpio_direction_output(RK29SDK_BT_GPIO_RESET_N,      GPIO_LOW);
 
+    #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+    
+    rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_GPIO1C4);
+    gpio_request(RK29_PIN1_PC4, "mmc1-data1");
+    gpio_direction_output(RK29_PIN1_PC4,GPIO_LOW);//set mmc1-data1 to low.
+
+    rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_GPIO1C5);
+    gpio_request(RK29_PIN1_PC5, "mmc1-data2");
+    gpio_direction_output(RK29_PIN1_PC5,GPIO_LOW);//set mmc1-data2 to low.
+
+    rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_GPIO1C6);
+    gpio_request(RK29_PIN1_PC6, "mmc1-data3");
+    gpio_direction_output(RK29_PIN1_PC6,GPIO_LOW);//set mmc1-data3 to low.
+    
+    rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
+    #endif    
     pr_info("%s: init finished\n",__func__);
 
     return 0;
@@ -2006,12 +2291,22 @@ static int rk29sdk_wifi_power(int on)
         pr_info("%s: %d\n", __func__, on);
         if (on){
                 gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH);
+
+                #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)     
+                rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13
+                #endif
+
                 gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH);
                 mdelay(100);
                 pr_info("wifi turn on power\n");
         }else{
                 if (!rk29sdk_bt_power_state){
                         gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
+
+                        #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)     
+                        rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
+                        #endif
+                        
                         mdelay(100);
                         pr_info("wifi shut off power\n");
                 }else
index 039cc173cb9b300e2f3eee610479a29c29ea7eef..7cec44db21f5fab5052a14becd312d9dd91637d4 100755 (executable)
@@ -139,6 +139,7 @@ struct rk29_sdmmc_platform_data {
        char dma_name[8];
        int (*io_init)(void);
        int (*io_deinit)(void);
+       void (*set_iomux)(int device_id, unsigned int bus_width);//added by xbw at 2011-10-13
        int (*status)(struct device *);
        int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
         int detect_irq;
index 314b4ae171a4c0cc05484e8088fa36a04c3b3acc..20f9b82b0d53fe9ca81a783a11a7e7a37add203b 100755 (executable)
@@ -208,7 +208,8 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
 #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
     if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ) 
     {
-        waittime = wait_for_completion_timeout(&complete,HZ*2); //sdio; for cmd dead. Modifyed by xbw at 2011-06-02
+        multi = (mrq->cmd->retries>0)?mrq->cmd->retries:1;
+        waittime = wait_for_completion_timeout(&complete,HZ*7*multi); //sdio; for cmd dead. Modifyed by xbw at 2011-06-02
     }
     else
     {   
@@ -221,7 +222,7 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
             multi += (datasize%unit)?1:0;
             multi = (multi>0) ? multi : 1;
             multi += (mrq->cmd->retries>0)?1:0;
-            waittime = wait_for_completion_timeout(&complete,HZ*5*multi); //It should be longer than bottom driver's time,due to the sum of two cmd time.
+            waittime = wait_for_completion_timeout(&complete,HZ*7*multi); //It should be longer than bottom driver's time,due to the sum of two cmd time.
                                                                           //modifyed by xbw at 2011-10-08
                                                                           //
                                                                           //example:
@@ -230,7 +231,8 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
         }
         else
         {
-            waittime = wait_for_completion_timeout(&complete,HZ*2);
+            multi = (mrq->cmd->retries>0)?mrq->cmd->retries:1;
+            waittime = wait_for_completion_timeout(&complete,HZ*7*multi);
         }
     }
     
@@ -1164,8 +1166,9 @@ void mmc_rescan(struct work_struct *work)
     */
 
     //mmc_send_if_cond(host, host->ocr_avail); //deleted by xbw@2011-04-09
-
+#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) 
      if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ){
+#endif     
        /*
         * First we search for SDIO...
         */
@@ -1187,8 +1190,9 @@ void mmc_rescan(struct work_struct *work)
                extend_wakelock = 1;
                goto out;
        }
+#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)         
     }
-
+#endif
 
     /*
      * ...then normal SD...
old mode 100644 (file)
new mode 100755 (executable)
index 7280140..5e98695
@@ -647,6 +647,10 @@ int sdio_reset_comm(struct mmc_card *card)
 
        printk("%s():\n", __func__);
        mmc_claim_host(host);
+       
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+       host->sdmmc_host_hw_init(mmc_priv(host));  //added by xbw , at 2011-10-18
+#endif
 
        mmc_go_idle(host);
 
index 85df780a5e0a5148bf18f644a3e69fd48e07471d..f7e229dd632d58ef9b6ea70d297d11434cb83c08 100755 (executable)
@@ -27,16 +27,21 @@ if SDMMC_RK29
                        
        config SDMMC0_RK29_WRITE_PROTECT
                bool "Write-protect for SDMMC0"
+               default n
                depends on SDMMC0_RK29
                help
                         You will add the feature of write-protect for sdmmc-card if you say Yes.
                         Please note that this feature requires hardware support.
-#      config EMMC_RK29
-#              tristate "RK29 EMMC controller support(sdmmc)"
-#              default y
-#              depends on SDMMC0_RK29
+       
+#      config USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD
+#          depends on SDMMC0_RK29
+#              bool "Switch the driver SDMMC0 for the debug of wifi_develop_board."
+#              default n
 #              help
-#                      This supports the use of the EMMC controller on Rk29 processors.
+#                      In order to debug the Wifi development board using SD interface,
+#                      we can switch the driver SDMMC0.
+
+
        config SDMMC1_RK29
                tristate "RK29 SDMMC1 controller support(sdio)"
                default y
@@ -45,10 +50,20 @@ if SDMMC_RK29
                        This supports the use of the SDMMC1 controller on Rk29 processors.
        config SDMMC1_RK29_WRITE_PROTECT
                bool "Write-protect for SDMMC1"
+               default n
                depends on SDMMC1_RK29
                help
                         You will add the feature of write-protect for sdio-card if you say Yes.
                         Please note that this feature requires hardware support.
+                       
+#      config USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD
+#        depends on SDMMC1_RK29
+#              bool "Switch the driver SDMMC1 for the debug of wifi_develop_board."
+#              default n
+#              help
+#                      In order to debug the Wifi development board using SD interface,
+#                      we can switch the driver SDMMC1.
+
 endif
 
 config MMC_ARMMMCI
index 216353d21309ce1856d89f8e7a57956a824b4d37..107c5dfe3dcf314c58c2c5fc1d4efdb508201495 100755 (executable)
@@ -52,7 +52,7 @@
 #define RK29_SDMMC_xbw_Debug 0
 
 #if RK29_SDMMC_xbw_Debug 
-int debug_level = 4;
+int debug_level = 5;
 #define xbwprintk(n, format, arg...) \
        if (n <= debug_level) {  \
                printk(format,##arg); \
@@ -67,16 +67,22 @@ int debug_level = 4;
 #define RK29_SDMMC_INTMASK_USEIO    (SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS | SDMMC_INT_CD| SDMMC_INT_TXDR | SDMMC_INT_RXDR )
 
 
-#define RK29_SDMMC_SEND_START_TIMEOUT   1000  //The time interval from the time SEND_CMD to START_CMD_BIT cleared.
+#define RK29_SDMMC_SEND_START_TIMEOUT   3000  //The time interval from the time SEND_CMD to START_CMD_BIT cleared.
 #define RK29_ERROR_PRINTK_INTERVAL      200   //The time interval between the two printk for the same error. 
-#define RK29_SDMMC_WAIT_DTO_INTERNVAL   1000  //The time interval from the CMD_DONE_INT to DTO_INT
-#define RK29_SDMMC_REMOVAL_DELAY        1000  //The time interval from the CD_INT to detect_timer react.
+#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.2.11 The last modify date is 2011-10-08,modifyed by XBW." 
+#define RK29_SDMMC_VERSION "Ver.2.13 The last modify date is 2011-10-19,modifyed by XBW." 
 
+#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) 
 #define RK29_CTRL_SDMMC_ID   0  //mainly used by SDMMC
 #define RK29_CTRL_SDIO1_ID   1  //mainly used by sdio-wifi
 #define RK29_CTRL_SDIO2_ID   2  //mainly used by sdio-card
+#else
+#define RK29_CTRL_SDMMC_ID   5  
+#define RK29_CTRL_SDIO1_ID   1  
+#define RK29_CTRL_SDIO2_ID   2  
+#endif
 
 #define RK29_SDMMC_NOTIFY_REMOVE_INSERTION /* use sysfs to notify the removal or insertion of sd-card*/
 //#define RK29_SDMMC_LIST_QUEUE            /* use list-queue for multi-card*/
@@ -206,6 +212,8 @@ struct rk29_sdmmc {
     int write_protect;
 #endif
 
+    void (*set_iomux)(int device_id, unsigned int bus_width);
+
 };
 
 
@@ -225,6 +233,7 @@ static struct rk29_sdmmc    *globalSDhost[3];
 
 static void rk29_sdmmc_start_error(struct rk29_sdmmc *host);
 static int rk29_sdmmc_clear_fifo(struct rk29_sdmmc *host);
+int rk29_sdmmc_hw_init(void *data);
 
 static void rk29_sdmmc_write(unsigned char  __iomem    *regbase, unsigned int regOff,unsigned int val)
 {
@@ -287,7 +296,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
     //envalue the address of host base on input-parameter.
     if( !strncmp(buf,"sd-" , strlen("sd-")) )
     {
-        host = (struct rk29_sdmmc      *)globalSDhost[RK29_CTRL_SDMMC_ID];
+        host = (struct rk29_sdmmc      *)globalSDhost[0];
         if(!host)
         {
             printk("%s..%d.. fail to call progress_store because the host is null. ==xbw==\n",__FUNCTION__,__LINE__);
@@ -329,6 +338,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
      *  insert card state-change:  No-Media ==> Pending ==> Idle-Unmounted ==> Checking ==>Mounted
      *  remove card state-change:  Unmounting ==> Idle-Unmounted ==> No-Media
     */
+    #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
     if(RK29_CTRL_SDMMC_ID == host->pdev->id)
     {
         if(!strncmp(buf, "sd-Unmounting", strlen("sd-Unmounting")))
@@ -366,6 +376,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
         else if( !strncmp(buf,"sd-reset" , strlen("sd-reset")) ) 
         {
             printk(".%d.. Now manual reset for SDMMC0. ====xbw[%s]====\n",__LINE__, host->dma_name);
+            rk29_sdmmc_hw_init(host);
             mmc_detect_change(host->mmc, 0);           
         }
         else if( !strncmp(buf, "sd-regs", strlen("sd-regs")))
@@ -375,6 +386,22 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
         }
 
     }
+    #else
+    if(0 == host->pdev->id)
+    {
+        if( !strncmp(buf,"sd-reset" , strlen("sd-reset")) ) 
+        {
+            printk(".%d.. Now manual reset for SDMMC0. ====xbw[%s]====\n",__LINE__, host->dma_name);
+            rk29_sdmmc_hw_init(host);
+            mmc_detect_change(host->mmc, 0);           
+        }
+        else if( !strncmp(buf, "sd-regs", strlen("sd-regs")))
+        {
+            printk(".%d.. Now printk the register of SDMMC0. ====xbw[%s]====\n",__LINE__, host->dma_name); 
+            rk29_sdmmc_regs_printk(host);
+        }
+    }
+    #endif
     else if(RK29_CTRL_SDIO1_ID == host->pdev->id)
     {
         if( !strncmp(buf, "sdio1-regs", strlen("sdio1-regs")))
@@ -385,6 +412,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
         else if( !strncmp(buf,"sdio1-reset" , strlen("sdio1-reset")) ) 
         {
             printk(".%d.. Now manual reset for SDMMC1. ====xbw[%s]====\n",__LINE__, host->dma_name);
+            rk29_sdmmc_hw_init(host);
             mmc_detect_change(host->mmc, 0);           
         }
     }
@@ -398,6 +426,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
         else if( !strncmp(buf,"sdio2-reset" , strlen("sdio2-reset")) ) 
         {
             printk(".%d.. Now manual reset for SDMMC2. ====xbw[%s]====\n",__LINE__, host->dma_name);
+            rk29_sdmmc_hw_init(host);
             mmc_detect_change(host->mmc, 0);           
         }
     }
@@ -414,7 +443,7 @@ struct kobj_attribute mmc_reset_attrs =
 {
         .attr = {
                 .name = "rescan",
-                .mode = 0777},
+                .mode = 0766},
         .show = NULL,
         .store = rk29_sdmmc_progress_store,
 };
@@ -702,7 +731,7 @@ void  rk29_sdmmc_set_frq(struct rk29_sdmmc *host)
 
 static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command *cmd, u32 cmd_flags)
 {
-       int tmo = RK29_SDMMC_SEND_START_TIMEOUT*3;
+       int tmo = RK29_SDMMC_SEND_START_TIMEOUT*10;//wait 60ms cycle.
        
        host->cmd = cmd;
        host->old_cmd = cmd->opcode;
@@ -1292,10 +1321,10 @@ static void rk29_sdmmc_submit_data(struct rk29_sdmmc *host, struct mmc_data *dat
 
 static int sdmmc_send_cmd_start(struct rk29_sdmmc *host, unsigned int cmd)
 {
-       int tmo = RK29_SDMMC_SEND_START_TIMEOUT*3;;
+       int tmo = RK29_SDMMC_SEND_START_TIMEOUT*10;//wait 60ms cycle.
        
        rk29_sdmmc_write(host->regs, SDMMC_CMD, SDMMC_CMD_START | cmd);         
-       while (--tmo && readl(host->regs + SDMMC_CMD) & SDMMC_CMD_START)
+       while (--tmo && (rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START))
        {
            udelay(2);
        }
@@ -1315,16 +1344,41 @@ static int sdmmc_send_cmd_start(struct rk29_sdmmc *host, unsigned int cmd)
 static int rk29_sdmmc_get_cd(struct mmc_host *mmc)
 {
        struct rk29_sdmmc *host = mmc_priv(mmc);
-       u32 cdetect;
+       u32 cdetect=1;
 
-#ifdef CONFIG_PM
-       if(host->gpio_det == INVALID_GPIO)
-               return 1;
-#endif
+    switch(host->pdev->id)
+    {
+        case 0:
+        {
+            #ifdef CONFIG_PM
+               if(host->gpio_det == INVALID_GPIO)
+                       return 1;
+            #endif
 
-       cdetect = rk29_sdmmc_read(host->regs, SDMMC_CDETECT);
+               cdetect = rk29_sdmmc_read(host->regs, SDMMC_CDETECT);
+
+            cdetect = (cdetect & SDMMC_CARD_DETECT_N)?0:1;
+
+            break;
+        }        
 
-       return (cdetect & SDMMC_CARD_DETECT_N)?0:1;
+        case 1:
+        {
+            #if defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
+            cdetect = 1;
+            #else
+            cdetect = test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags)?1:0;
+            #endif
+            break;
+        }
+        
+        default:
+            cdetect = 1;
+            break;
+    
+       }
+
+        return cdetect;
 }
 
 
@@ -1400,7 +1454,26 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host)
                }
                else
                {
-                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+                   if(0== host->pdev->id)
+                   {
+                   #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+                   #else
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
+                   #endif
+                   }
+                   else if(1== host->pdev->id)
+                   {
+                      #if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+                  #else
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
+                  #endif 
+                   }
+                   else
+                   {
+                       rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+                   }
                }
        }
        else
@@ -1411,7 +1484,26 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host)
                }
                else
                {
-                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+                   if(0== host->pdev->id)
+                   {
+                   #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+                   #else
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO);
+                   #endif
+                   }
+                   else if(1== host->pdev->id)
+                   {
+                       #if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+                   #else
+                   rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO);
+                   #endif
+                   }
+                   else
+                   {
+                       rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+                   }
                }               
     }
 
@@ -1436,7 +1528,7 @@ static int rk29_sdmmc_control_clock(struct rk29_sdmmc *host, bool enable)
     tmo = 1000;
        while (--tmo && (rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START))
        {
-               cpu_relax();
+               udelay(1);//cpu_relax();
        }
        if(!tmo)
        {
@@ -1482,7 +1574,7 @@ static int rk29_sdmmc_control_clock(struct rk29_sdmmc *host, bool enable)
     return SDM_SUCCESS;
 
 Error_exit:
-    printk("\n%s....%d..  control clock fail!!! Enable=%d, ret=%d ===xbw[%s]====\n",\
+    printk("\n%s....%d..  control clock fail!!! Enable=%d, ret=0x%x ===xbw[%s]====\n",\
                        __FILE__,__LINE__,enable,ret, host->dma_name);
 
     return ret;
@@ -1543,7 +1635,7 @@ int rk29_sdmmc_change_clk_div(struct rk29_sdmmc *host, u32 freqHz)
     tmo = 1000;
        while (--tmo && (rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START))
        {
-               cpu_relax();
+               udelay(1);//cpu_relax();
        }
        if(!tmo)
        {
@@ -1580,19 +1672,24 @@ int rk29_sdmmc_change_clk_div(struct rk29_sdmmc *host, u32 freqHz)
     
 SetFreq_error:
 
-    printk("%s..%s..%d..  change division fail, ret=%d  !!! ====xbw[%s]====\n",\
-        __FILE__, __FUNCTION__,__LINE__,ret, host->dma_name);
+    printk("%s..%d..  change division fail, errorStep=0x%x,ret=%d  !!! ====xbw[%s]====\n",\
+        __FILE__, __LINE__,host->errorstep,ret, host->dma_name);
         
     return ret;
     
 }
 
-
-
-static int rk29_sdmmc_hw_init(struct rk29_sdmmc *host)
+int rk29_sdmmc_hw_init(void *data)
 {
+    struct rk29_sdmmc *host = (struct rk29_sdmmc *)data;
+
+    //set the iomux
+    host->ctype = SDMMC_CTYPE_1BIT;
+    host->set_iomux(host->pdev->id, host->ctype);
+    
     /* reset controller */
     rk29_sdmmc_reset_controller(host);
+
     rk29_sdmmc_change_clk_div(host, FOD_FREQ);
     
     return SDM_SUCCESS;    
@@ -1600,23 +1697,6 @@ static int rk29_sdmmc_hw_init(struct rk29_sdmmc *host)
 
 
 
-int rk29_sdmmc_set_iomux(struct rk29_sdmmc *host)
-{
-    #if 0
-    switch (host->busWidth)
-    {
-        case 
-       rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
-       rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT);
-       rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0);
-       rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
-       rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
-       }
-    #endif
-    
-       return 0;
-}
-
 int rk29_sdmmc_set_buswidth(struct rk29_sdmmc *host)
 {
     //int ret;
@@ -1630,7 +1710,8 @@ int rk29_sdmmc_set_buswidth(struct rk29_sdmmc *host)
         default:
             return SDM_PARAM_ERROR;
     }
-    rk29_sdmmc_set_iomux(host);
+
+    host->set_iomux(host->pdev->id, host->ctype);
 
     /* Set the current  bus width */
        rk29_sdmmc_write(host->regs, SDMMC_CTYPE, host->ctype);
@@ -1891,6 +1972,7 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                                __FUNCTION__, __LINE__, host->dma_name, host->dma_name);
 
         host->state = STATE_IDLE;
+        rk29_sdmmc_write(host->regs, SDMMC_RINTSTS, 0xFFFFFFFF);
         spin_unlock_irqrestore(&host->lock, iflags);
            mmc_request_done(mmc, mrq);
                return;
@@ -1949,27 +2031,26 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                {       
                        host->old_cmd = mrq->cmd->opcode;
                                host->error_times = 0;
-                       }
+                       }                       
        }
        }
        else
        {
         host->old_cmd = mrq->cmd->opcode;
         host->error_times = 0;
+
+        if(!test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags))
+               {
+                   host->state = STATE_IDLE;
+                   mrq->cmd->error = -ENOMEDIUM;
+            spin_unlock_irqrestore(&host->lock, iflags);
+               mmc_request_done(mmc, mrq);
+               return;
+               }
+
        }
        
-       #if 1
-    if(0 == host->mmc->doneflag)
-    {
-        host->state = STATE_IDLE;
-    }
-    
-       if(host->state != STATE_IDLE)
-       {
-            printk("%s..%d..state Error! ,old_state=%d, OldCMD=%d ,NewCMD%2d,arg=0x%x ===xbw[%s]===\n", \
-                               __FUNCTION__, __LINE__, host->state, host->cmd->opcode,mrq->cmd->opcode,mrq->cmd->arg, host->dma_name);
-       }
-           
+       #if 1  
     host->new_mrq = mrq;        
 
        spin_unlock_irqrestore(&host->lock, iflags);
@@ -2021,25 +2102,28 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
     spin_lock_irqsave(&host->lock, iflags);
 
-    /*
-     * Waiting SDIO controller to be IDLE.
-    */
-    while (timeout-- > 0)
-       {
-               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
-               if ((value & SDMMC_STAUTS_DATA_BUSY) == 0 &&(value & SDMMC_CMD_FSM_MASK) == SDMMC_CMD_FSM_IDLE)
-               {
-                       break;
-               }
-               
-               mdelay(1);
-       }
-       if (timeout <= 0)
-       {
-               printk("%s..%d...Waiting for SDMMC%d controller to be IDLE timeout.==xbw[%s]===\n", \
-                               __FUNCTION__, __LINE__, host->pdev->id, host->dma_name);
+    if(test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags) || (RK29_CTRL_SDMMC_ID == host->pdev->id))
+    {
+        /*
+         * Waiting SDIO controller to be IDLE.
+        */
+        while (timeout-- > 0)
+       {
+               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
+               if ((value & SDMMC_STAUTS_DATA_BUSY) == 0 &&(value & SDMMC_CMD_FSM_MASK) == SDMMC_CMD_FSM_IDLE)
+               {
+                       break;
+               }
+               
+               mdelay(1);
+       }
+       if (timeout <= 0)
+       {
+               printk("%s..%d...Waiting for SDMMC%d controller to be IDLE timeout.==xbw[%s]===\n", \
+                               __FUNCTION__, __LINE__, host->pdev->id, host->dma_name);
 
-               goto out;
+               goto out;
+       }
        }
 
     //if(host->bus_mode != ios->power_mode)
@@ -2088,7 +2172,9 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        
        }
 
-    
+    if(!(test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags) || (RK29_CTRL_SDIO1_ID != host->pdev->id)))
+        goto out; //exit the set_ios directly if the SDIO is not present. 
+        
        if(host->ctype != ios->bus_width)
        {
        switch (ios->bus_width) 
@@ -2128,25 +2214,41 @@ out:
 static int rk29_sdmmc_get_ro(struct mmc_host *mmc)
 {
     struct rk29_sdmmc *host = mmc_priv(mmc);
-    
-#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
-    int ret;
-    
-       if(INVALID_GPIO == host->write_protect)
-           ret = 0;//no write-protect
-       else
-        ret = gpio_get_value(host->write_protect)?1:0;
-   
-    xbwprintk(7,"%s..%d.. write_prt_pin=%d, get_ro=%d ===xbw[%s]===\n",\
-        __FUNCTION__, __LINE__,host->write_protect, ret, host->dma_name);
+    int ret=0;
+
+    switch(host->pdev->id)
+    {
+        case 0:
+        {
+            #if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)            
+               if(INVALID_GPIO == host->write_protect)
+                   ret = 0;//no write-protect
+               else
+                ret = gpio_get_value(host->write_protect)?1:0;
+           
+            xbwprintk(7,"%s..%d.. write_prt_pin=%d, get_ro=%d ===xbw[%s]===\n",\
+                __FUNCTION__, __LINE__,host->write_protect, ret, host->dma_name);
+                            
+            #else
+               u32 wrtprt = rk29_sdmmc_read(host->regs, SDMMC_WRTPRT);
+               
+               ret = (wrtprt & SDMMC_WRITE_PROTECT)?1:0;
+            #endif
+
+            break;
+        }
         
+        case 1:
+            ret = 0;//no write-protect
+            break;
+        
+        default:
+            ret = 0;
+        break;   
+    }
+
     return ret;
-    
-#else
-       u32 wrtprt = rk29_sdmmc_read(host->regs, SDMMC_WRTPRT);
-       
-       return (wrtprt & SDMMC_WRITE_PROTECT)?1:0;
-#endif 
+
 }
 
 
@@ -2231,6 +2333,8 @@ static const struct mmc_host_ops rk29_sdmmc_ops[] = {
        {
                .request        = rk29_sdmmc_request,
                .set_ios        = rk29_sdmmc_set_ios,
+               .get_ro         = rk29_sdmmc_get_ro,
+               .get_cd         = rk29_sdmmc_get_cd,
                .enable_sdio_irq = rk29_sdmmc_enable_sdio_irq,
                .init_card       = rk29_sdmmc_init_card,
        },
@@ -2719,7 +2823,7 @@ static inline void rk29_sdmmc_cmd_interrupt(struct rk29_sdmmc *host, u32 status)
         multi += ((rk29_sdmmc_read(host->regs, SDMMC_BYTCNT)%unit) ? 1 :0 );
         multi = (multi>0) ? multi : 1;
         multi += (host->cmd->retries>2)?2:host->cmd->retries;
-           mod_timer(&host->DTO_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_WAIT_DTO_INTERNVAL*multi));
+           mod_timer(&host->DTO_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_WAIT_DTO_INTERNVAL*multi));//max wait 8s larger  
        }
        
        smp_wmb();
@@ -2927,12 +3031,14 @@ static void rk29_sdmmc1_check_status(unsigned long data)
         unsigned int status;
 
     status = pdata->status(mmc_dev(host->mmc));
-
+    
+    pr_info("%s: slot status change detected(%d-%d)\n",mmc_hostname(host->mmc), host->oldstatus, status);
+    
     if (status ^ host->oldstatus)
-    {
-        pr_info("%s: slot status change detected(%d-%d)\n",mmc_hostname(host->mmc), host->oldstatus, status);
+    {        
         if (status) 
         {
+            rk29_sdmmc_hw_init(host);
             set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
             mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(200));
         }
@@ -2949,7 +3055,7 @@ static void rk29_sdmmc1_check_status(unsigned long data)
 static void rk29_sdmmc1_status_notify_cb(int card_present, void *dev_id)
 {
         struct rk29_sdmmc *host = dev_id;
-        printk(KERN_INFO "%s, card_present %d\n", mmc_hostname(host->mmc), card_present);
+        //printk(KERN_INFO "%s, card_present %d\n", mmc_hostname(host->mmc), card_present);
         rk29_sdmmc1_check_status((unsigned long)host);
 }
 
@@ -3007,6 +3113,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM
     host->gpio_det = pdata->detect_irq;
 #endif
+    host->set_iomux = pdata->set_iomux;
 
        if(pdata->io_init)
                pdata->io_init();
@@ -3062,6 +3169,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
        mmc->caps = pdata->host_caps;
        mmc->re_initialized_flags = 1;
        mmc->doneflag = 1;
+       mmc->sdmmc_host_hw_init = rk29_sdmmc_hw_init;
 
     /*
         * We can do SGIO
@@ -3186,6 +3294,22 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
             clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
         }
     }
+    else
+    {
+        #if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+        if(0== host->pdev->id)
+        {
+            set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
+        }
+        #endif
+
+        #if defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
+        if(1== host->pdev->id)
+        {
+            set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
+        }
+        #endif
+    }
 
 
     /* sdmmc1 wifi card slot status initially */
@@ -3206,7 +3330,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
 #ifdef RK29_SDMMC_NOTIFY_REMOVE_INSERTION
     
     globalSDhost[pdev->id] = (struct rk29_sdmmc        *)host;
-    if(RK29_CTRL_SDMMC_ID== host->pdev->id)
+    if(0== host->pdev->id)
     {
         rk29_sdmmc_progress_add_attr(pdev);
     }
index 4125ef55faee8393f631a827fa3eca37eb778aba..2b3d83ba6a9cab0a4876bc0d4fb4208e9e46d393 100755 (executable)
@@ -203,8 +203,11 @@ struct mmc_host {
 #define MMC_BUSRESUME_MANUAL_RESUME    (1 << 0)
 #define MMC_BUSRESUME_NEEDS_RESUME     (1 << 1)
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
     unsigned int               re_initialized_flags; //in order to begin the rescan ;  added by xbw@2011-04-07
     unsigned int        doneflag;//added by xbw at 2011-08-27
+    int (*sdmmc_host_hw_init)(void *data);
+#endif    
 
        unsigned int            sdio_irqs;
        struct task_struct      *sdio_irq_thread;