From: lbt Date: Tue, 14 Dec 2010 06:22:47 +0000 (+0800) Subject: wifi: add wifi virtual card detect support X-Git-Tag: firefly_0821_release~10939 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fcd62b7dd9792b879c3075f92260fed39d88d315;p=firefly-linux-kernel-4.4.55.git wifi: add wifi virtual card detect support --- diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 22862eafeab5..ac5969ed337f 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -840,7 +840,9 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = { .status = rk29sdk_wifi_status, .register_status_notify = rk29sdk_wifi_status_register, #endif +#if 0 .detect_irq = RK29SDK_WIFI_SDIO_CARD_DETECT_N, +#endif }; #endif diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index 8c60ffb12a6f..09ee6933d246 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -111,6 +111,7 @@ struct rk29_sdmmc { int id; int irq; struct timer_list detect_timer; + unsigned int oldstatus; }; #define rk29_sdmmc_test_and_clear_pending(host, event) \ @@ -450,8 +451,10 @@ static int rk29_sdmmc_submit_data_dma(struct rk29_sdmmc *host, struct mmc_data * * non-word-aligned buffers or lengths. Also, we don't bother * with all the DMA setup overhead for short transfers. */ +#if 0 if (data->blocks * data->blksz < RK29_SDMMC_DMA_THRESHOLD) return -EINVAL; +#endif if (data->blksz & 3) return -EINVAL; for_each_sg(data->sg, sg, data->sg_len, i) { @@ -1099,6 +1102,7 @@ static void rk29_sdmmc_cmd_interrupt(struct rk29_sdmmc *host, u32 status) tasklet_schedule(&host->tasklet); } +#if 0 static int rk29_sdmmc1_card_get_cd(struct mmc_host *mmc) { struct rk29_sdmmc *host = mmc_priv(mmc); @@ -1134,6 +1138,7 @@ static irqreturn_t rk29_sdmmc1_card_detect_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +#endif static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id) { @@ -1288,6 +1293,37 @@ static void rk29_sdmmc_detect_change(unsigned long data) mmc_detect_change(host->mmc, 0); } +static void rk29_sdmmc1_check_status(unsigned long data) +{ + struct rk29_sdmmc *host = (struct rk29_sdmmc *)data; + struct rk29_sdmmc_platform_data *pdata = host->pdev->dev.platform_data; + unsigned int status; + + status = pdata->status(mmc_dev(host->mmc)); + + if (status ^ host->oldstatus) + { + pr_info("%s: slot status change detected(%d-%d)\n",mmc_hostname(host->mmc), host->oldstatus, status); + if (status) { + set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(200)); + } + else { + clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + rk29_sdmmc_detect_change((unsigned long)host); + } + } + + host->oldstatus = status; +} + +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); + rk29_sdmmc1_check_status((unsigned long)host); +} + static int rk29_sdmmc_probe(struct platform_device *pdev) { struct mmc_host *mmc; @@ -1365,22 +1401,45 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) ret = request_irq(irq, rk29_sdmmc_interrupt, 0, dev_name(&pdev->dev), host); if (ret) goto err_dmaunmap; - + +#if 0 /* register sdmmc1 card detect interrupt route */ - if ((pdev->id == 1) && (pdata->detect_irq != 0)) { - irq = gpio_to_irq(pdata->detect_irq); - if (irq < 0) { - printk("%s: request gpio irq failed\n", __FUNCTION__); - goto err_dmaunmap; - } + if ((pdev->id == 1) && (pdata->detect_irq != 0)) { + irq = gpio_to_irq(pdata->detect_irq); + if (irq < 0) { + printk("%s: request gpio irq failed\n", __FUNCTION__); + goto err_dmaunmap; + } - ret = request_irq(irq, rk29_sdmmc1_card_detect_interrupt, IRQF_TRIGGER_RISING, dev_name(&pdev->dev), host); - if (ret) { - printk("%s: sdmmc1 request detect interrupt failed\n", __FUNCTION__); - goto err_dmaunmap; - } + ret = request_irq(irq, rk29_sdmmc1_card_detect_interrupt, IRQF_TRIGGER_RISING, dev_name(&pdev->dev), host); + if (ret) { + printk("%s: sdmmc1 request detect interrupt failed\n", __FUNCTION__); + goto err_dmaunmap; + } - } + } +#endif + /* setup sdmmc1 wifi card detect change */ + if (pdata->register_status_notify) { + pdata->register_status_notify(rk29_sdmmc1_status_notify_cb, host); + } + + /* Assume card is present initially */ + if(rk29_sdmmc_get_cd(host->mmc)) + set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + else + clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + + /* sdmmc1 wifi card slot status initially */ + if (pdata->status) { + host->oldstatus = pdata->status(mmc_dev(host->mmc)); + if (host->oldstatus) { + set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + }else { + clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); + } + } + platform_set_drvdata(pdev, host); mmc->ops = &rk29_sdmmc_ops[pdev->id]; mmc->f_min = host->bus_hz/510; @@ -1393,11 +1452,6 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) mmc->max_blk_count = 65535; ///512; mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; - /* Assume card is present initially */ - if(rk29_sdmmc_get_cd(host->mmc)) - set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); - else - clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags); mmc_add_host(mmc); #if defined (CONFIG_DEBUG_FS)