static void * mmc_cim_single_card_acq( struct mmc_dev *dev, int first ) { struct mmc_response_r3 r3; struct mmc_response_r1 r1; struct mmc_slot *slot = dev->slot; /* Must be slot 0 */ int retval; DEBUG(2,"\n"); if ( first ) { mmc_simple_cmd(dev, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE); slot->sd = 0; return NULL; } switch (dev->request.cmd) { case MMC_GO_IDLE_STATE: /* No response to parse */ if ( (dev->sdrive->flags & MMC_SDFLAG_VOLTAGE )) DEBUG(0,": error - current driver doesn't do OCR\n"); mmc_simple_cmd(dev, MMC_APP_CMD, 0, RESPONSE_R1); break; case MMC_APP_CMD: retval = mmc_unpack_r1(&dev->request,&r1,slot->state); if ( retval ) { DEBUG(0, ": unable to MMC_APP_CMD error=%d (%s)\n", retval, mmc_result_to_string(retval)); mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3); } else { mmc_simple_cmd(dev, SD_SEND_OP_COND, 0x00ff8000, RESPONSE_R3); } break; case SD_SEND_OP_COND: retval = mmc_unpack_r3(&dev->request, &r3); if ( retval ) { /* Try MMC card */ mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3); break; } DEBUG(2,": read ocr value = 0x%08x\n", r3.ocr); if (!(r3.ocr & MMC_CARD_BUSY)) { mmc_simple_cmd(dev, MMC_APP_CMD, 0, RESPONSE_R1); } else { /* Set the data bus width to 4 bits */ slot->sd = 1; /* SD Card ready */ slot->state = CARD_STATE_READY; mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); } break; case MMC_SEND_OP_COND: retval = mmc_unpack_r3(&dev->request, &r3); if ( retval ) { DEBUG(0,": failed SEND_OP_COND error=%d (%s)\n", retval, mmc_result_to_string(retval)); return mmc_cim_default_state; } DEBUG(2,": read ocr value = 0x%08x\n", r3.ocr); if (!(r3.ocr & MMC_CARD_BUSY)) { mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3); } else { slot->sd = 0; /* MMC Card ready */ slot->state = CARD_STATE_READY; mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); } break; case MMC_ALL_SEND_CID: retval = mmc_unpack_cid( &dev->request, &slot->cid ); if ( retval ) { DEBUG(0,": unable to ALL_SEND_CID error=%d (%s)\n", retval, mmc_result_to_string(retval)); return mmc_cim_default_state; } slot->state = CARD_STATE_IDENT; if(slot->sd) { mmc_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, 0, RESPONSE_R6); } else { mmc_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, ID_TO_RCA(slot->id) << 16, RESPONSE_R1); } break; case MMC_SET_RELATIVE_ADDR: if (slot->sd) { retval = mmc_unpack_r6(&dev->request, &r1, slot->state, &slot->rca); slot->rca = slot->rca << 16; DEBUG(2, ": Get RCA from SD: 0x%04x Status: %x\n", slot->rca, r1.status); } else { retval = mmc_unpack_r1(&dev->request,&r1,slot->state); slot->rca = ID_TO_RCA(slot->id) << 16; } if ( retval ) { DEBUG(0, ": unable to SET_RELATIVE_ADDR error=%d (%s)\n", retval, mmc_result_to_string(retval)); return mmc_cim_default_state; } slot->state = CARD_STATE_STBY; mmc_simple_cmd(dev, MMC_SEND_CSD, slot->rca, RESPONSE_R2_CSD); break; case MMC_SEND_CSD: retval = mmc_unpack_csd(&dev->request, &slot->csd); if ( retval ) { DEBUG(0, ": unable to SEND_CSD error=%d (%s)\n", retval, mmc_result_to_string(retval)); return mmc_cim_default_state; } if ( slot->csd.dsr_imp ) { DEBUG(0, ": driver doesn't support setting DSR\n"); // mmc_simple_cmd(dev, MMC_SET_DSR, 0, RESPONSE_NONE); } mmc_configure_card( dev, 0 ); return mmc_cim_default_state; default: DEBUG(0, ": error! Illegal last cmd %d\n", dev->request.cmd); return mmc_cim_default_state; } return NULL; }
static int mmc_init_card_state(struct mmc_request *request) { struct mmc_response_r1 r1; struct mmc_response_r3 r3; int retval; int ocr = 0x40300000; DEBUG(2, "mmc_init_card_state\n"); switch (request->cmd) { case MMC_GO_IDLE_STATE: /* No response to parse */ if (mmcinfo.sd) mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1); else mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); break; case 8: retval = mmc_unpack_r1(request, &r1, mmcinfo.state); mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1); break; case MMC_APP_CMD: retval = mmc_unpack_r1(request, &r1, mmcinfo.state); if (retval & (limit_41 < 100)) { DEBUG(0, "mmc_init_card_state: unable to MMC_APP_CMD error=%d (%s)\n", retval, mmc_result_to_string(retval)); limit_41++; mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3); } else if (limit_41 < 100) { limit_41++; mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3); } else { /* reset the card to idle */ mmc_simple_cmd(request, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE); mmcinfo.sd = 0; } break; case SD_SEND_OP_COND: retval = mmc_unpack_r3(request, &r3); if (retval) { /* Try MMC card */ mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); break; } DEBUG(2, "mmc_init_card_state: read ocr value = 0x%08x\n", r3.ocr); if (!(r3.ocr & MMC_CARD_BUSY || ocr == 0)) { mdelay(10); mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1); } else { /* Set the data bus width to 4 bits */ mmcinfo.sd = 1; /* SD Card ready */ mmcinfo.state = CARD_STATE_READY; mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); } break; case MMC_SEND_OP_COND: retval = mmc_unpack_r3(request, &r3); if (retval) { DEBUG(0, "mmc_init_card_state: failed SEND_OP_COND error=%d (%s)\n", retval, mmc_result_to_string(retval)); return MMC_INIT_FAILED; } DEBUG(2, "mmc_init_card_state: read ocr value = 0x%08x\n", r3.ocr); if (!(r3.ocr & MMC_CARD_BUSY)) { mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); } else { mmcinfo.sd = 0; /* MMC Card ready */ mmcinfo.state = CARD_STATE_READY; mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID); } break; case MMC_ALL_SEND_CID: retval = mmc_unpack_cid(request, &mmcinfo.cid); /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ if (retval && (retval != MMC_ERROR_CRC)) { DEBUG(0, "mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n", retval, mmc_result_to_string(retval)); return MMC_INIT_FAILED; } mmcinfo.state = CARD_STATE_IDENT; if (mmcinfo.sd) mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, 0, RESPONSE_R6); else mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1); break; case MMC_SET_RELATIVE_ADDR: if (mmcinfo.sd) { retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca); mmcinfo.rca = mmcinfo.rca << 16; DEBUG(2, "mmc_init_card_state: Get RCA from SD: 0x%04x Status: %x\n", mmcinfo.rca, r1.status); } else { retval = mmc_unpack_r1(request, &r1, mmcinfo.state); mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16; } if (retval) { DEBUG(0, "mmc_init_card_state: unable to SET_RELATIVE_ADDR error=%d (%s)\n", retval, mmc_result_to_string(retval)); return MMC_INIT_FAILED; } mmcinfo.state = CARD_STATE_STBY; mmc_simple_cmd(request, MMC_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD); break; case MMC_SEND_CSD: retval = mmc_unpack_csd(request, &mmcinfo.csd); /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ if (retval && (retval != MMC_ERROR_CRC)) { DEBUG(0, "mmc_init_card_state: unable to SEND_CSD error=%d (%s)\n", retval, mmc_result_to_string(retval)); return MMC_INIT_FAILED; } if (mmcinfo.csd.dsr_imp) { DEBUG(0, "mmc_init_card_state: driver doesn't support setting DSR\n"); } mmc_configure_card(); return MMC_INIT_PASSED; break; default: DEBUG(0, "mmc_init_card_state: error! Illegal last cmd %d\n", request->cmd); return MMC_INIT_FAILED; } return MMC_INIT_DOING; }