Example #1
0
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;
}
Example #2
0
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;
}