Ejemplo n.º 1
0
int ReinitSDIO(struct hif_device *device)
{
    s32 err;
    struct mmc_host *host;
    struct mmc_card *card;
	struct sdio_func *func;
    u8 cmd52_resp;
    u32 clock;

    func = device->func;
    card = func->card;
    host = card->host;
   
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
    sdio_claim_host(func);

    do {
        if (!device->is_suspend) {
            u32 resp;
            u16 rca;
            u32 i;
            int bit = fls(host->ocr_avail) - 1;
            /* emulate the mmc_power_up(...) */
            host->ios.vdd = bit;
            host->ios.chip_select = MMC_CS_DONTCARE;
            host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
            host->ios.power_mode = MMC_POWER_UP;
            host->ios.bus_width = MMC_BUS_WIDTH_1;
            host->ios.timing = MMC_TIMING_LEGACY;
            host->ops->set_ios(host, &host->ios);
            /*
             * This delay should be sufficient to allow the power supply
             * to reach the minimum voltage.
             */
            msleep(2);

            host->ios.clock = host->f_min;
            host->ios.power_mode = MMC_POWER_ON;
            host->ops->set_ios(host, &host->ios);

            /*
             * This delay must be at least 74 clock sizes, or 1 ms, or the
             * time required to reach a stable voltage.
             */
            msleep(2);

            /* Issue CMD0. Goto idle state */
	        host->ios.chip_select = MMC_CS_HIGH;
            host->ops->set_ios(host, &host->ios);
	        msleep(1);
            err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
            host->ios.chip_select = MMC_CS_DONTCARE;
            host->ops->set_ios(host, &host->ios);
	        msleep(1);
            host->use_spi_crc = 0;

            if (err) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));    
                break;
            }        

            if (!host->ocr) {
                /* Issue CMD5, arg = 0 */
                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
                if (err) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
                    break;
                }
                host->ocr = resp;
            }

            /* Issue CMD5, arg = ocr. Wait till card is ready  */
            for (i=0;i<100;i++) {
                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
                if (err) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
                    break;
                }
                if (resp & MMC_CARD_BUSY) {
                    break;
                }
                msleep(10);
            }

            if ((i == 100) || (err)) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));    
                break;
            }

            /* Issue CMD3, get RCA */
            err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
            if (err) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));    
                break;
            }
            rca = resp >> 16;
            host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
            host->ops->set_ios(host, &host->ios);

            /* Issue CMD7, select card  */
            err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
            if (err) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));    
                break;
            }
        }
        
        /* Enable high speed */
        if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));    
            err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
            if (err) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed  : %d \n",err));    
                card->state &= ~MMC_STATE_HIGHSPEED;
                /* no need to break */
            } else {
                err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
                if (err) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed  : %d \n",err));    
                    break;
                }
                mmc_card_set_highspeed(card);
                host->ios.timing = MMC_TIMING_SD_HS;
                host->ops->set_ios(host, &host->ios);
            }
        }

        /* Set clock */
        if (mmc_card_highspeed(card)) {
            clock = 50000000;
        } else {
            clock = card->cis.max_dtr;
        }
        
        if (clock > host->f_max) {
            clock = host->f_max;
        }
        host->ios.clock = clock;
        host->ops->set_ios(host, &host->ios);
        

        if (card->host->caps & MMC_CAP_4_BIT_DATA) {
            /* CMD52: Set bus width & disable card detect resistor */
            err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
            if (err) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));    
                break;
            }
            host->ios.bus_width = MMC_BUS_WIDTH_4;
            host->ops->set_ios(host, &host->ios);
        }
    } while (0);
Ejemplo n.º 2
0
static A_STATUS ReinitSDIO(HIF_DEVICE *device)
{
    A_STATUS            status = A_OK;
    SD_COMMAND_RESPONSE response;
    A_UINT32            ocr;
    int                 cardReadyRetry = 10;
    A_UINT16            rca;
    A_UINT8             cmd52Data;

    do {

        if (!IssueSDCommand(device->handle,0,0,NoResponse,NULL)) {
            break;
        }

        AR_DEBUG_PRINTF(DBG_TRACE,("Issuing first CMD5 ... \n"));

            /* issue CMD5, ARG=0 */
        if (!IssueSDCommand(device->handle,5,0,ResponseR4,&response)) {
            AR_DEBUG_PRINTF(DBG_TRACE,("CMD5 FAILED, NO card detected \n"));
            break;
        }

        ocr = SD_SDIO_R4_GET_OCR(response.ResponseBuffer);

        AR_DEBUG_PRINTF(DBG_TRACE,("CMD5 success, OCR = 0x%X \n",ocr));

            /* issue CMD5, ARG=0x00100000 repeatedly until card is ready */
        while (cardReadyRetry) {
            if (!IssueSDCommand(device->handle,
                                5,
                                0x00100000, /* use 3.0 volts, although this really is a don't care */
                                ResponseR4,
                                &response)) {
                AR_DEBUG_PRINTF(DBG_ERR,("CMD5 Failed \n"));
                cardReadyRetry = 0;
                break;
            }

            if (SD_SDIO_R4_IS_CARD_READY(response.ResponseBuffer)) {
                AR_DEBUG_PRINTF(DBG_TRACE,("SDIO Card is Ready! \n"));
                break;
            }
            cardReadyRetry--;
            Sleep(10);
        }

        if (cardReadyRetry == 0) {
            AR_DEBUG_PRINTF(DBG_ERR,("CMD5 Ready polling Expired \r\n"));
            break;
        }

        AR_DEBUG_PRINTF(DBG_TRACE,("Issuing CMD3 ... \n"));

             /* issue CMD3 */
        if (!IssueSDCommand(device->handle,3,0,ResponseR6,&response)) {
            AR_DEBUG_PRINTF(DBG_ERR,("CMD3 FAILED \n"));
            break;
        }

        rca = SD_SDIO_R6_GET_RCA(response.ResponseBuffer);

        AR_DEBUG_PRINTF(DBG_TRACE,("Card RCA : 0x%X \n",rca));

        AR_DEBUG_PRINTF(DBG_TRACE,("Issuing CMD7 ... \n"));

              /* issue CMD7 to select card */
        if (!IssueSDCommand(device->handle, 7,(((A_UINT32)rca) << 16),ResponseR1b,&response)) {
            AR_DEBUG_PRINTF(DBG_ERR,("CMD7 FAILED \n"));
            break;
        }

        AR_DEBUG_PRINTF(DBG_TRACE,("Card is now selected! \n"));

            /* disable card detect resistor and restore operational bus width */
        cmd52Data = CARD_DETECT_DISABLE;
        if (device->CardInterface.InterfaceMode == SD_INTERFACE_SD_4BIT) {
                /* enable 4-bit mode */
            cmd52Data |= 0x2;
        }

        if (!IssueCMD52(device->handle,
                        SDIO_BUS_IF_REG,
                        0,
                        TRUE,
                        &cmd52Data)) {
            AR_DEBUG_PRINTF(DBG_ERR,("Failed to set bus mode register \r\n"));
            break;
        }

            /* complete interface setup */
        if (!SetupSDIOInterface(device)) {
            status = A_ERROR;
        }

    } while (FALSE);


    return status;
}