mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Optimize the powe up and down of wifi and SDcard module
This commit is contained in:
@@ -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,10 +2204,20 @@ 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 ////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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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...
|
||||
|
||||
4
drivers/mmc/core/sdio.c
Normal file → Executable file
4
drivers/mmc/core/sdio.c
Normal file → Executable file
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
return (cdetect & SDMMC_CARD_DETECT_N)?0:1;
|
||||
cdetect = (cdetect & SDMMC_CARD_DETECT_N)?0:1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user