rk30_mux_api_set(GPIO3C1_SDMMC1DATA0_NAME, GPIO3C_GPIO3C1);
gpio_request(RK30_PIN3_PC1, "mmc1-data0");
gpio_direction_output(RK30_PIN3_PC1,GPIO_LOW);//set mmc1-data0 to low.
-
+ #if defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC)
+ rk29_mux_api_set(GPIO3C2_SDMMC1DATA1_NAME, GPIO3C_GPIO3C2);
+ gpio_request(RK30_PIN3_PC2, "mmc1-data1");
+ gpio_direction_output(RK30_PIN3_PC2,GPIO_LOW);//set mmc1-data1 to low.
+
+ rk29_mux_api_set(GPIO3C3_SDMMC1DATA2_NAME, GPIO3C_GPIO3C3);
+ gpio_request(RK30_PIN3_PC3, "mmc1-data2");
+ gpio_direction_output(RK30_PIN3_PC3,GPIO_LOW);//set mmc1-data2 to low.
+
+ rk29_mux_api_set(GPIO3C4_SDMMC1DATA3_NAME, GPIO3C_GPIO3C4);
+ gpio_request(RK30_PIN3_PC4, "mmc1-data3");
+ gpio_direction_output(RK30_PIN3_PC4,GPIO_LOW);//set mmc1-data3 to low.
+ #endif
mdelay(100);
}
#endif
#endif
+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);
+
+#if defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC)
+static int rk29sdk_wifi_mmc0_status(struct device *dev);
+static int rk29sdk_wifi_mmc0_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id);
+static int rk29sdk_wifi_mmc0_cd = 0; /* wifi virtual 'card detect' status */
+static void (*wifi_mmc0_status_cb)(int card_present, void *dev_id);
+static void *wifi_mmc0_status_cb_devid;
+
+int rk29sdk_wifi_power_state = 0;
+int rk29sdk_bt_power_state = 0;
+#endif
-//int rk29sdk_wifi_power_state = 0;
-//int rk29sdk_bt_power_state = 0;
+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;
#ifdef CONFIG_WIFI_CONTROL_FUNC
//#define RK29SDK_WIFI_BT_GPIO_POWER_N RK30_PIN3_PD0
return -ENOMEM;
}
-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;
-
static int rk29sdk_wifi_status(struct device *dev)
{
return rk29sdk_wifi_cd;
},
};
+
+///////////////////////////////////////////////////////////////////////////////////
+#elif defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC)
+
+ #if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ #define USE_SDMMC_CONTROLLER_FOR_WIFI 0
+ #define RK29SDK_WIFI_COMBO_GPIO_POWER_N RK30_PIN4_PD2
+ #define RK29SDK_WIFI_COMBO_GPIO_RESET_N RK30_PIN4_PD1
+ #define RK29SDK_WIFI_COMBO_GPIO_VDDIO RK30_PIN1_PA6
+ #define RK29SDK_WIFI_COMBO_GPIO_BGF_INT_B RK30_PIN1_PA7
+ #define RK29SDK_WIFI_COMBO_GPS_SYNC RK30_PIN3_PC7
+
+ #else
+ #define USE_SDMMC_CONTROLLER_FOR_WIFI 1
+ #define RK29SDK_WIFI_COMBO_GPIO_POWER_N RK30_PIN3_PD0
+ #define RK29SDK_WIFI_COMBO_GPIO_RESET_N RK30_PIN3_PD1
+ #define RK29SDK_WIFI_COMBO_GPIO_WIFI_INT_B RK30_PIN3_PD2
+
+ #define RK29SDK_WIFI_COMBO_GPIO_VDDIO RK30_PIN6_PB4
+ #define RK29SDK_WIFI_COMBO_GPIO_BGF_INT_B RK30_PIN3_PC6
+ #define RK29SDK_WIFI_COMBO_GPS_SYNC RK30_PIN3_PC7
+ #endif
+
+
+#define debug_combo_system 0
+
+int rk29sdk_wifi_combo_get_BGFgpio(void)
+{
+ return RK29SDK_WIFI_COMBO_GPIO_BGF_INT_B;
+}
+EXPORT_SYMBOL(rk29sdk_wifi_combo_get_BGFgpio);
+
+
+int rk29sdk_wifi_combo_get_GPS_SYNC_gpio(void)
+{
+ return RK29SDK_WIFI_COMBO_GPS_SYNC;
+}
+EXPORT_SYMBOL(rk29sdk_wifi_combo_get_GPS_SYNC_gpio);
+
+
+static int rk29sdk_wifi_combo_module_gpio_init(void)
+{
+ if (gpio_request(RK29SDK_WIFI_COMBO_GPIO_RESET_N, "combo-RST"))
+ {
+ pr_info("%s:request combo-RST failed\n", __func__);
+ return -1;
+ }
+ gpio_direction_output(RK29SDK_WIFI_COMBO_GPIO_RESET_N, GPIO_LOW);
+
+ if (gpio_request(RK29SDK_WIFI_COMBO_GPIO_POWER_N, "combo-PMUEN"))
+ {
+ pr_info("%s:request combo-PMUEN failed\n", __func__);
+ return -1;
+ }
+
+ //gpio_pull_updown(RK29SDK_WIFI_COMBO_GPIO_POWER_N,0);
+ //gpio_direction_input(RK29SDK_WIFI_COMBO_GPIO_POWER_N);
+ gpio_direction_output(RK29SDK_WIFI_COMBO_GPIO_POWER_N, GPIO_LOW);
+ return 0;
+}
+
+
+int rk29sdk_wifi_combo_module_power(int on)
+{
+ if(on)
+ {
+ //gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_VDDIO, GPIO_HIGH);
+ //mdelay(10);
+ gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_POWER_N, GPIO_HIGH);
+ mdelay(10);
+ pr_info("combo-module turn on power\n");
+ }
+ else
+ {
+ gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_POWER_N, GPIO_LOW);
+ mdelay(10);
+ //gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_VDDIO, GPIO_LOW);
+ pr_info("combo-module turn off power\n");
+ }
+ return 0;
+
+}
+EXPORT_SYMBOL(rk29sdk_wifi_combo_module_power);
+
+
+int rk29sdk_wifi_combo_module_reset(int on)
+{
+ if(on)
+ {
+ gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_RESET_N, GPIO_HIGH);
+ pr_info("combo-module reset out 1\n");
+ }
+ else
+ {
+ gpio_set_value(RK29SDK_WIFI_COMBO_GPIO_RESET_N, GPIO_LOW);
+ pr_info("combo-module reset out 0\n");
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(rk29sdk_wifi_combo_module_reset);
+
+
+static int rk29sdk_wifi_mmc0_status(struct device *dev)
+{
+ return rk29sdk_wifi_mmc0_cd;
+}
+
+static int rk29sdk_wifi_mmc0_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id)
+{
+ if(wifi_mmc0_status_cb)
+ return -EAGAIN;
+ wifi_mmc0_status_cb = callback;
+ wifi_mmc0_status_cb_devid = dev_id;
+ return 0;
+}
+
+
+static int rk29sdk_wifi_status(struct device *dev)
+{
+ return rk29sdk_wifi_cd;
+}
+
+static int rk29sdk_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id)
+{
+ if(wifi_status_cb)
+ return -EAGAIN;
+ wifi_status_cb = callback;
+ wifi_status_cb_devid = dev_id;
+ return 0;
+}
+extern unsigned int sdio_irq_global;
+
+int rk29sdk_wifi_power(int on)
+{
+ pr_info("%s: %d\n", __func__, on);
+ if (on){
+
+ #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+
+ #if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ rk29_sdmmc_gpio_open(0, 1);
+ #else
+ rk29_sdmmc_gpio_open(1, 0);
+ mdelay(10);
+ rk29_sdmmc_gpio_open(1, 1);
+ #endif
+ #endif
+
+ mdelay(100);
+ pr_info("wifi turn on power\n");
+ }
+ else
+ {
+#if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+ #if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ rk29_sdmmc_gpio_open(0, 0);
+ #else
+ rk29_sdmmc_gpio_open(1, 0);
+ #endif
+#endif
+ mdelay(100);
+ pr_info("wifi shut off power\n");
+
+ }
+
+ rk29sdk_wifi_power_state = on;
+ return 0;
+
+}
+EXPORT_SYMBOL(rk29sdk_wifi_power);
+
+
+int rk29sdk_wifi_reset(int on)
+{
+ return 0;
+}
+EXPORT_SYMBOL(rk29sdk_wifi_reset);
+
+
+#if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+int rk29sdk_wifi_set_carddetect(int val)
+{
+ pr_info("%s:%d\n", __func__, val);
+ rk29sdk_wifi_mmc0_cd = val;
+ if (wifi_mmc0_status_cb){
+ wifi_mmc0_status_cb(val, wifi_mmc0_status_cb_devid);
+ }else {
+ pr_warning("%s,in mmc0 nobody to notify\n", __func__);
+ }
+ return 0;
+}
+
+#else
+int rk29sdk_wifi_set_carddetect(int val)
+{
+ pr_info("%s:%d\n", __func__, val);
+ rk29sdk_wifi_cd = val;
+ if (wifi_status_cb){
+ wifi_status_cb(val, wifi_status_cb_devid);
+ }else {
+ pr_warning("%s,in mmc1 nobody to notify\n", __func__);
+ }
+ return 0;
+}
+#endif
+
+EXPORT_SYMBOL(rk29sdk_wifi_set_carddetect);
+
+#endif /// #endif ---#elif defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC)
+
+
+
+#if 1//defined(CONFIG_WIFI_CONTROL_FUNC)
static struct wifi_platform_data rk29sdk_wifi_control = {
.set_power = rk29sdk_wifi_power,
.set_reset = rk29sdk_wifi_reset,
.platform_data = &rk29sdk_wifi_control,
},
};
+
+#elif defined(CONFIG_WIFI_COMBO_MODULE_CONTROL_FUNC)
+
+ #if debug_combo_system
+ static struct combo_module_platform_data rk29sdk_combo_module_control = {
+ .set_power = rk29sdk_wifi_combo_module_power,
+ .set_reset = rk29sdk_wifi_combo_module_reset,
+ };
+
+ static struct platform_device rk29sdk_combo_module_device = {
+ .name = "combo-system",
+ .id = 1,
+ .dev = {
+ .platform_data = &rk29sdk_combo_module_control,
+ },
+ };
+ #endif
+
+static struct wifi_platform_data rk29sdk_wifi_control = {
+ .set_power = rk29sdk_wifi_power,
+ .set_reset = rk29sdk_wifi_reset,
+ .set_carddetect = rk29sdk_wifi_set_carddetect,
+};
+
+static struct platform_device rk29sdk_wifi_device = {
+ .name = "combo-wifi",
+ .id = 1,
+ .dev = {
+ .platform_data = &rk29sdk_wifi_control,
+ },
+};
+
#endif
#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.3.07 The last modify date is 2012-04-23"
+#define RK29_SDMMC_VERSION "Ver.4.01 The last modify date is 2012-08-09"
#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
#define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC
//#define RK29_SDMMC_LIST_QUEUE /* use list-queue for multi-card*/
#define RK29_SDMMC_DEFAULT_SDIO_FREQ 0 // 1--run in default frequency(50Mhz); 0---run in 25Mhz,
-#define RK29_MAX_SDIO_FREQ 25000000 //set max-sdio-frequency 25Mhz at the present time¡£
+#define RK29_MAX_SDIO_FREQ 45000000 //set max-sdio-frequency 25Mhz at the present time
enum {
EVENT_CMD_COMPLETE = 0,
int gpio_det;
#endif
+#ifdef CONFIG_RK29_SDIO_IRQ_FROM_GPIO
+ unsigned int sdio_INT_gpio;
+ unsigned int sdio_irq;
+#endif
+
#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
int write_protect;
#endif
static void send_stop_cmd(struct rk29_sdmmc *host)
{
int ret;
+ int timeout = 250;
+ unsigned int value;
+
if(host->mrq->cmd->error)
{
__FUNCTION__, __LINE__, host->dma_name);
}
}
-
- mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+1500));
+
+ 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)
+ {
+ printk(KERN_ERR "%d... cmd=%d(arg=0x%x),blksz=%d,blocks=%d,errorStep=0x%x, host->state=%x [%s]\n",\
+ __LINE__,host->cmd->opcode, host->cmd->arg, host->cmd->data->blksz, host->cmd->data->blocks,host->errorstep,host->state,host->dma_name);
+
+ //stop DMA
+ if(host->dodma)
+ {
+ rk29_sdmmc_stop_dma(host);
+ rk29_sdmmc_control_host_dma(host, FALSE);
+
+ host->dodma = 0;
+ }
+
+ ret= rk29_sdmmc_clear_fifo(host);
+ if(SDM_SUCCESS != ret)
+ {
+ xbwprintk(3, "%s..%d.. clear fifo error before call CMD_STOP [%s]\n", \
+ __FUNCTION__, __LINE__, host->dma_name);
+ }
+ }
+
+ host->errorstep = 0xe1;
+ mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+2500));
host->stopcmd.opcode = MMC_STOP_TRANSMISSION;
host->stopcmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;;
{
rk29_sdmmc_start_error(host);
- host->state = STATE_IDLE;
+ //host->state = STATE_IDLE;
host->complete_done = 4;
}
+ host->errorstep = 0xe2;
}
}
if (data->blksz & 3)
+ {
+ printk(KERN_WARNING "%s..%d... data_len not aligned to 4bytes. [%s]\n", __FUNCTION__, __LINE__, host->dma_name);
return -EINVAL;
+ }
+
for_each_sg(data->sg, sg, data->sg_len, i)
{
if (sg->offset & 3 || sg->length & 3)
break;
}
+#if defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
+ return 1;
+#endif
return cdetect;
}
if(0== host->pdev->id)
{
#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
+ #else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+ #endif
#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)
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
+ #else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+ #endif
#else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
#endif
}
else
{
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
+ #else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA | SDMMC_INT_SDIO);
+ #endif
}
}
}
if(0== host->pdev->id)
{
#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO);
+ #else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+ #endif
#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)
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO);
+ #else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+ #endif
#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);
+ #if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO);
+ #else
+ rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEIO | SDMMC_INT_SDIO);
+ #endif
}
}
}
host->cmd->data->error = -EILSEQ;
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_DTO); // clear interrupt
rk29_sdmmc_set_pending(host, EVENT_DATA_COMPLETE);
+#if SDMMC_USE_INT_UNBUSY
+ rk29_sdmmc_set_pending(host, EVENT_DATA_UNBUSY);
+#endif
tasklet_schedule(&host->tasklet);
break;
#if SDMMC_USE_INT_UNBUSY
{
struct rk29_sdmmc *host = (struct rk29_sdmmc *) host_data;
- //spin_lock(&host->lock);
+ rk29_sdmmc_enable_irq(host, false);
if(STATE_SENDING_CMD == host->state)
{
if(0==host->cmd->retries)
{
- printk(KERN_WARNING "%s..%d... cmd=%d, INT_CMD_DONE timeout, errorStep=0x%x, host->state=%x [%s]\n",\
- __FUNCTION__, __LINE__,host->cmd->opcode, host->errorstep,host->state,host->dma_name);
+ printk(KERN_WARNING "%d... cmd=%d, INT_CMD_DONE timeout, errorStep=0x%x, host->state=%x [%s]\n",\
+ __LINE__,host->cmd->opcode, host->errorstep,host->state,host->dma_name);
}
-
+
rk29_sdmmc_dealwith_timeout(host);
}
- //spin_unlock(&host->lock);
+ rk29_sdmmc_enable_irq(host, true);
}
{
struct rk29_sdmmc *host = (struct rk29_sdmmc *) host_data;
- //spin_lock(&host->lock);
+ rk29_sdmmc_enable_irq(host, false);
#if SDMMC_USE_INT_UNBUSY
if( (host->cmdr & SDMMC_CMD_DAT_EXP) &&((STATE_DATA_BUSY == host->state)||(STATE_DATA_UNBUSY == host->state) ))
rk29_sdmmc_dealwith_timeout(host);
}
- //spin_unlock(&host->lock);
-
+ rk29_sdmmc_enable_irq(host, true);
}
}
+#if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+static irqreturn_t rk29_sdmmc_sdio_irq_cb(int irq, void *dev_id)
+{
+ struct rk29_sdmmc *host = dev_id;
+ //printk("%d..%s: sdio_gpio_int callback. ====[%s]==\n", __LINE__, __FUNCTION__, host->dma_name);
+
+ //rk28_send_wakeup_key(); //wake up backlight
+
+ if(host && host->mmc)
+ mmc_signal_sdio_irq(host->mmc);
+
+ return IRQ_HANDLED;
+}
+#endif
+
static void rk29_sdmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
- u32 intmask;
+#if !defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ u32 intmask;
unsigned long flags;
+#endif
struct rk29_sdmmc *host = mmc_priv(mmc);
-
+
+#if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ if(enable)
+ enable_irq(host->sdio_irq);
+ //enable_irq_wake(host->sdio_irq);
+ else
+ disable_irq_nosync(host->sdio_irq);
+
+#else
spin_lock_irqsave(&host->lock, flags);
-
- intmask = rk29_sdmmc_read(host->regs, SDMMC_INTMASK);
-
+
+ intmask = rk29_sdmmc_read(host->regs, SDMMC_INTMASK);
if(enable)
rk29_sdmmc_write(host->regs, SDMMC_INTMASK, intmask | SDMMC_INT_SDIO);
else
rk29_sdmmc_write(host->regs, SDMMC_INTMASK, intmask & ~SDMMC_INT_SDIO);
- spin_unlock_irqrestore(&host->lock, flags);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+#endif
+
}
struct mmc_data *data = host->cmd->data;
enum rk29_sdmmc_state state = host->state;
int pending_flag, stopflag;
- unsigned long iflags;
rk29_sdmmc_enable_irq(host, false);
spin_lock(&host->lock);//spin_lock_irqsave(&host->lock, iflags);
{
xbwprintk(7, "%s..%d.. prev_state= STATE_SENDING_CMD, pendingEvernt=0x%lu [%s]\n",\
__FUNCTION__, __LINE__,host->completed_events, host->dma_name);
-
+ if(host->cmd->error)
+ {
+ del_timer_sync(&host->request_timer);
+ }
+
if (!rk29_sdmmc_test_and_clear_pending(host, EVENT_CMD_COMPLETE))
break;
host->errorstep = 0xfb;
** use DTO_timer for waiting for INT_UNBUSY.
** max 250ms in specification, but adapt 500 for the compatibility of all kinds of sick sdcard.
*/
- mod_timer(&host->DTO_timer, jiffies + msecs_to_jiffies(500));
+ mod_timer(&host->DTO_timer, jiffies + msecs_to_jiffies(2000));
}
else
{
xbwprintk(3,"%d: call send_stop_cmd== %d, completedone=%d, doneflag=%d, hoststate=%x, statusReg=0x%x \n", \
__LINE__,stopflag, host->complete_done, host->mmc->doneflag, state, rk29_sdmmc_read(host->regs, SDMMC_STATUS));
+ host->errorstep = 0xe0;
state = STATE_SENDING_CMD;
send_stop_cmd(host); //Moidfyed by xbw at 2011-09-08
}
if(0==host->complete_done)
{
host->errorstep = 0xf2;
+
+ if(12==host->cmd->opcode)
+ {
+ printk(KERN_ERR "%d... cmd=%d(arg=0x%x),blksz=%d,blocks=%d,errorStep=0x%x,\n host->state=%x, statusReg=0x%x [%s]\n",\
+ __LINE__,host->mrq->cmd->opcode, host->mrq->cmd->arg, host->mrq->cmd->data->blksz, host->mrq->cmd->data->blocks,\
+ host->errorstep,host->state,rk29_sdmmc_read(host->regs, SDMMC_STATUS),host->dma_name);
+ }
spin_unlock(&host->lock);//spin_unlock_irqrestore(&host->lock, iflags);
rk29_sdmmc_enable_irq(host, true);
goto Exit_INT;
}
+#if !defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
if(pending & SDMMC_INT_SDIO)
{
xbwprintk(7, "%s..%d.. INT_SDIO INT=0x%x [%s]\n", \
goto Exit_INT;
}
-
+#endif
if(pending & SDMMC_INT_RTO)
{
//int irq;
int ret = 0;
+#if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ unsigned long trigger_flags;
+#endif
+
/* must have platform data */
pdata = pdev->dev.platform_data;
if (!pdata) {
host->retryfunc = 0;
host->mrq = NULL;
host->new_mrq = NULL;
+ host->irq_state = true;
#ifdef CONFIG_PM
host->gpio_det = pdata->detect_irq;
#endif
host->set_iomux = pdata->set_iomux;
+#if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ if(RK29_CTRL_SDIO1_ID == host->pdev->id)
+ {
+ host->sdio_INT_gpio = pdata->sdio_INT_gpio;
+ }
+#endif
+
if(pdata->io_init)
pdata->io_init();
ret = rk29_dma_config(host->dma_info.chn, 4, 16);
}
else
- {
- ret = rk29_dma_config(host->dma_info.chn, 4, 1);
+ {
+ #if defined(CONFIG_ARCH_RK30)
+ ret = rk29_dma_config(host->dma_info.chn, 4, 16); // a unified set the burst value to 16 in RK30,noted at 2012-07-16
+ #else
+ ret = rk29_dma_config(host->dma_info.chn, 4, 1); // to maintain set this value to 1 in RK29,noted at 2012-07-16
+ #endif
}
#endif
if(ret < 0)
host->write_protect = pdata->write_prt;
#endif
- rk29_sdmmc_hw_init(host);
+
+ if(RK29_CTRL_SDMMC_ID != host->pdev->id)
+ {
+ rk29_sdmmc_hw_init(host);
+ }
ret = request_irq(host->irq, rk29_sdmmc_interrupt, 0, dev_name(&pdev->dev), host);
if (ret)
host->errorstep = 0x8C;
goto err_dmaunmap;
}
-
- host->irq_state = true;
+
+#if defined(CONFIG_RK29_SDIO_IRQ_FROM_GPIO)
+ if(RK29_CTRL_SDIO1_ID == host->pdev->id)
+ {
+ gpio_request(host->sdio_INT_gpio, "sdio_interrupt");
+
+ // intput + pull_Up,
+ gpio_direction_input(host->sdio_INT_gpio);
+ //gpio_direction_output(host->sdio_INT_gpio, GPIO_HIGH);
+ gpio_pull_updown(host->sdio_INT_gpio, 0); //disable default internal pull-down
+
+ host->sdio_irq = gpio_to_irq(host->sdio_INT_gpio);
+ trigger_flags = IRQF_TRIGGER_LOW;
+ //printk("%d..%s sdio interrupt gpio level=%lu ====[%s]====\n", __LINE__, __FUNCTION__, trigger_flags, host->dma_name);
+ ret = request_irq(host->sdio_irq, rk29_sdmmc_sdio_irq_cb,
+ trigger_flags,
+ "sdio_interrupt",
+ host);
+ if (ret)
+ {
+
+ printk("%s..%d.. sdio_request_INT_irq error=%d ====xbw[%s]====\n", \
+ __FUNCTION__, __LINE__, ret, host->dma_name);
+ host->errorstep = 0x8D;
+ goto err_dmaunmap;
+ }
+ disable_irq_nosync(host->sdio_irq);
+ }
+#endif
/* setup sdmmc1 wifi card detect change */
if (pdata->register_status_notify) {