Ejemplo n.º 1
0
/*
 * Handle the detection and initialisation of a card.
 *
 * In the case of a resume, "oldcard" will contain the card
 * we're trying to reinitialise.
 */
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                            struct mmc_card *oldcard)
{
    struct mmc_card *card;
    int err;
    u32 cid[4];
    unsigned int max_dtr;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
    int retries;
#endif
    BUG_ON(!host);
    WARN_ON(!host->claimed);

    /*
     * Since we're changing the OCR value, we seem to
     * need to tell some cards to go back to the idle
     * state.  We wait 1ms to give cards time to
     * respond.
     */
    mmc_go_idle(host);

    /*
     * If SD_SEND_IF_COND indicates an SD 2.0
     * compliant card and we should set bit 30
     * of the ocr to indicate that we can handle
     * block-addressed SDHC cards.
     */
    err = mmc_send_if_cond(host, ocr);
    if (!err)
        ocr |= 1 << 30;

    err = mmc_send_app_op_cond(host, ocr, NULL);
    if (err)
        goto err;

    /*
     * Fetch CID from card.
     */
    if (mmc_host_is_spi(host))
        err = mmc_send_cid(host, cid);
    else
        err = mmc_all_send_cid(host, cid);
    if (err)
        goto err;

    if (oldcard) {
        if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
            err = -ENOENT;
            goto err;
        }

        card = oldcard;
    } else {
        /*
         * Allocate card structure.
         */
        card = mmc_alloc_card(host, &sd_type);
        if (IS_ERR(card)) {
            err = PTR_ERR(card);
            goto err;
        }

        card->type = MMC_TYPE_SD;
        memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
    }

    /*
     * For native busses:  get card RCA and quit open drain mode.
     */
    if (!mmc_host_is_spi(host)) {
        err = mmc_send_relative_addr(host, &card->rca);
        if (err)
            goto free_card;

        mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
    }

    if (!oldcard) {
        /*
         * Fetch CSD from card.
         */
        err = mmc_send_csd(card, card->raw_csd);
        if (err)
            goto free_card;

        err = mmc_decode_csd(card);
        if (err)
            goto free_card;

        mmc_decode_cid(card);
    }

    /*
     * Select card, as all following commands rely on that.
     */
    if (!mmc_host_is_spi(host)) {
        err = mmc_select_card(card);
        if (err)
            goto free_card;
    }

    if (!oldcard) {
        /*
         * Fetch SCR from card.
         */
        err = mmc_app_send_scr(card, card->raw_scr);
        if (err)
            goto free_card;

        err = mmc_decode_scr(card);
        if (err < 0)
            goto free_card;
        /*
         * Fetch switch information from card.
         */
#ifdef CONFIG_MMC_PARANOID_SD_INIT
        for (retries = 1; retries <= 3; retries++) {
            err = mmc_read_switch(card);
            if (!err) {
                if (retries > 1) {
                    printk(KERN_WARNING
                           "%s: recovered\n",
                           mmc_hostname(host));
                }
                break;
            } else {
                printk(KERN_WARNING
                       "%s: read switch failed (attempt %d)\n",
                       mmc_hostname(host), retries);
            }
        }
#else
        err = mmc_read_switch(card);
#endif

        if (err)
            goto free_card;
    }

    /*
     * For SPI, enable CRC as appropriate.
     * This CRC enable is located AFTER the reading of the
     * card registers because some SDHC cards are not able
     * to provide valid CRCs for non-512-byte blocks.
     */
    if (mmc_host_is_spi(host)) {
        err = mmc_spi_set_crc(host, use_spi_crc);
        if (err)
            goto free_card;
    }

    /*
     * Attempt to change to high-speed (if supported)
     */
    err = mmc_switch_hs(card);
    if (err)
        goto free_card;

    /*
     * Compute bus speed.
     */
    max_dtr = (unsigned int)-1;

    if (mmc_card_highspeed(card)) {
        if (max_dtr > card->sw_caps.hs_max_dtr)
            max_dtr = card->sw_caps.hs_max_dtr;
    } else if (max_dtr > card->csd.max_dtr) {
        max_dtr = card->csd.max_dtr;
    }

    mmc_set_clock(host, max_dtr);

    /*
     * Switch to wider bus (if supported).
     */
    if ((host->caps & MMC_CAP_4_BIT_DATA) &&
            (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
        err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
        if (err)
        {
            err = 0;
            printk(KERN_ERR "HiGH-SPEED MODE NOT AVILABLE FOR YOUR CARD!\n");
            mmc_set_timing(card->host,MMC_TIMING_LEGACY);
            err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
            if(err)
            {
                err = 0;
                printk(KERN_ERR "CLOCK TOO HIGH SWITCH TO NORMAL CLOCK!\n");
                max_dtr = card->csd.max_dtr;
                mmc_set_clock(host, max_dtr);
                err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
                if(err)
                {
                    printk("I don't known why!!\n");
                    goto free_card;
                }

            }
        }
        mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
    }

    /*
     * Check if read-only switch is active.
     */
    if (!oldcard) {
        if (!host->ops->get_ro || host->ops->get_ro(host) < 0) {
            printk(KERN_WARNING "%s: host does not "
                   "support reading read-only "
                   "switch. assuming write-enable.\n",
                   mmc_hostname(host));
        } else {
            if (host->ops->get_ro(host) > 0)
                mmc_card_set_readonly(card);
        }
    }

    if (!oldcard)
        host->card = card;

    return 0;

free_card:
    if (!oldcard)
        mmc_remove_card(card);
err:

    return err;
}
Ejemplo n.º 2
0
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
                      bool reinit)
{
    int err;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
    int retries;
#endif

    if (!reinit) {
        /*
         * Fetch SCR from card.
         */
        err = mmc_app_send_scr(card, card->raw_scr);
        if (err)
            return err;

        err = mmc_decode_scr(card);
        if (err)
            return err;

        /*
         * Fetch and process SD Status register.
         */
        err = mmc_read_ssr(card);
        if (err)
            return err;

        /* Erase init depends on CSD and SSR */
        mmc_init_erase(card);

        /*
         * Fetch switch information from card.
         */
#ifdef CONFIG_MMC_PARANOID_SD_INIT
        for (retries = 1; retries <= 3; retries++) {
            err = mmc_read_switch(card);
            if (!err) {
                if (retries > 1) {
                    printk(KERN_WARNING
                           "%s: recovered\n",
                           mmc_hostname(host));
                }
                break;
            } else {
                printk(KERN_WARNING
                       "%s: read switch failed (attempt %d)\n",
                       mmc_hostname(host), retries);
            }
        }
#else
        err = mmc_read_switch(card);
#endif

        if (err)
            return err;
    }

    /*
     * For SPI, enable CRC as appropriate.
     * This CRC enable is located AFTER the reading of the
     * card registers because some SDHC cards are not able
     * to provide valid CRCs for non-512-byte blocks.
     */
    if (mmc_host_is_spi(host)) {
        err = mmc_spi_set_crc(host, use_spi_crc);
        if (err)
            return err;
    }

    /*
     * Check if read-only switch is active.
     */
    if (!reinit) {
        int ro = -1;

        if (host->ops->get_ro)
            ro = host->ops->get_ro(host);

        if (ro < 0) {
            printk(KERN_WARNING "%s: host does not "
                   "support reading read-only "
                   "switch. assuming write-enable.\n",
                   mmc_hostname(host));
        } else if (ro > 0) {
            mmc_card_set_readonly(card);
        }
    }

    return 0;
}