⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_protocol.c

📁 spi driver for sd /mmc card
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	switch (dev->request.cmd) {	case MMC_SELECT_CARD:		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )			goto lock_error;		for ( i = 0 ; i < dev->num_slots ; i++ )			dev->slot[i].state = ( i == t->id ? CARD_STATE_TRAN : CARD_STATE_STBY );                mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );		break;	case MMC_SET_BLOCKLEN:		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )			goto lock_error;		mmc_send_cmd(dev, MMC_LOCK_UNLOCK, 0, 1, t->block_len, RESPONSE_R1B );		break;	case MMC_LOCK_UNLOCK:		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )			goto lock_error;		mmc_simple_cmd(dev, MMC_SEND_STATUS, slot->rca, RESPONSE_R1 );		break;	case MMC_SEND_STATUS:		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state)) ) {			switch (retval) {			case MMC_ERROR_STATE_MISMATCH:				/* poll unitl it's done */				mmc_simple_cmd(dev, MMC_SEND_STATUS, slot->rca, RESPONSE_R1 );				return NULL;			case MMC_ERROR_LOCK_UNLOCK_FAILED:				/* nothing */				break;			default:				goto lock_error;			}		}		if (retval == MMC_ERROR_LOCK_UNLOCK_FAILED) 			slot->flags |= MMC_SLOT_FLAG_LOCK_FAILED;		if (r1.status & R1_CARD_IS_LOCKED) slot->flags |= MMC_SLOT_FLAG_LOCKED;		else slot->flags &= ~MMC_SLOT_FLAG_LOCKED;				mmc_finish_io_request(dev, 1);		return mmc_cim_default_state;	default:		goto lock_error;		break;	}	return NULL;	lock_error:	DEBUG(0,": failure during cmd %d, error %d (%s)\n", 	      dev->request.cmd, retval, mmc_result_to_string(retval));	printk(" failure during cmd %d, error %d (%s)\n", 	      dev->request.cmd, retval, mmc_result_to_string(retval));	slot->flags |= MMC_SLOT_FLAG_LOCK_FAILED;	mmc_finish_io_request(dev, 0);	return mmc_cim_default_state;}/* Update the card's status information in preparation to running a read/write cycle */static void * mmc_cim_get_status( struct mmc_dev *dev, int first ){	struct mmc_slot *slot = dev->slot + dev->io_request->id;	struct mmc_response_r1 r1;	int retval = MMC_NO_ERROR;	DEBUG(2," first=%d\n",first);	if ( first ) {		mmc_simple_cmd(dev, MMC_SEND_STATUS, slot->rca, RESPONSE_R1 );		return NULL;	}	switch (dev->request.cmd) {	case MMC_SEND_STATUS:		retval = mmc_unpack_r1(&dev->request,&r1,slot->state);		if ( retval && (retval != MMC_ERROR_STATE_MISMATCH) ) 			goto err_out;		slot->state = R1_CURRENT_STATE(r1.status);		if (dev->io_request->cmd == MMC_IO_LOCK)			return mmc_cim_lock_unlock;				if ( !(r1.status & R1_CARD_IS_LOCKED) ) {			slot->flags &= ~MMC_SLOT_FLAG_LOCKED;			return mmc_cim_read_write_block;		} else 			slot->flags |=  MMC_SLOT_FLAG_LOCKED;		break;	default:		break;	}err_out:	DEBUG(0, ": failure during cmd %d, error=%d (%s)\n", dev->request.cmd,	      retval, mmc_result_to_string(retval));//#ifdef CONFIG_ARCH_EZX_E680	/* add by w20598 */        if (!mmc_slot_enable)	{	   if (MMC_IO_READ == dev->io_request->cmd)	       mmc_media_transfer_done(dev->io_request,0);	   else	       mmc_media_transfer_done(dev->io_request,1);	   dev->io_request = NULL;        }	else	/* add end *///#endif	    mmc_finish_io_request(dev,0);	return mmc_cim_default_state;}static void * mmc_cim_handle_request( struct mmc_dev *dev, int first ){	DEBUG(2," first=%d\n",first);	if ( !first && !mmc_has_valid_request(dev)) {		DEBUG(0, ": invalid request\n");//#ifdef CONFIG_ARCH_EZX_E680      	       /* add by w20598 */               if (!mmc_slot_enable)	       {		    if (MMC_IO_READ == dev->io_request->cmd)	                mmc_media_transfer_done(dev->io_request,0);	            else	                mmc_media_transfer_done(dev->io_request,1);	            dev->io_request = NULL;               }	       else	      /* add end *///#endif 	            mmc_finish_io_request(dev,0);	       return mmc_cim_default_state;	}	if ( first )		return mmc_cim_get_status;//#ifdef CONFIG_ARCH_EZX_E680		       /* add by w20598 */       if (!mmc_slot_enable)       {       	    if (MMC_IO_READ == dev->io_request->cmd)	       mmc_media_transfer_done(dev->io_request,0);	    else	       mmc_media_transfer_done(dev->io_request,1);	    dev->io_request = NULL;            return mmc_cim_default_state;         }       else       /* add end *///#endif	return mmc_cim_read_write_block;}/****************************************************************** * * State machine routines to initialize card(s) * ******************************************************************//*  CIM_SINGLE_CARD_ACQ  (frequency at 400 kHz)  --- Must enter from GO_IDLE_STATE ---  1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]  2. SEND_OP_COND (Full Range) [CMD1]   {optional}  3. SEND_OP_COND (Set Range ) [CMD1]     If busy, delay and repeat step 2  4. ALL_SEND_CID              [CMD2]     If timeout, set an error (no cards found)  5. SET_RELATIVE_ADDR         [CMD3]  6. SEND_CSD                  [CMD9]  7. SET_DSR                   [CMD4]    Only call this if (csd.dsr_imp).  8. Set clock frequency (check available in csd.tran_speed) */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 = 1;		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");		if (slot->sd) 			mmc_simple_cmd(dev, MMC_APP_CMD,  0, RESPONSE_R1);		else			mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3);		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));			/* reset the card to idle*/			mmc_simple_cmd(dev, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE);			slot->sd = 0;		}                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 );				/*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */		if ( retval && (retval != MMC_ERROR_CRC)) {			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);                		/*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */	        if ( retval && (retval != MMC_ERROR_CRC)) {			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;}/*  CIM_INIT_STACK       (frequency at 400 kHz)  1. GO_IDLE_STATE (CMD0)  2. Do CIM_SINGLE_CARD_ACQ*/static void * mmc_cim_init_stack( struct mmc_dev *dev, int first ){	DEBUG(2,"\n");	if ( first ) {		mmc_simple_cmd(dev, MMC_CIM_RESET, 0, RESPONSE_NONE);		return NULL;	}	switch (dev->request.cmd) {	case MMC_CIM_RESET:		if ( dev->slot[0].state == CARD_STATE_EMPTY )			return mmc_cim_default_state;		dev->slot[0].state = CARD_STATE_IDLE;		return mmc_cim_single_card_acq;	default:		DEBUG(0,": invalid state %d\n", dev->request.cmd);		break;	}	return NULL;}/****************************************************************** *  Default state - start here ******************************************************************/static void * mmc_cim_default_state( struct mmc_dev *dev, int first ){	DEBUG(2,"\n");	mmc_check_eject(dev);	if (mmc_check_insert(dev))		return mmc_cim_init_stack;	else if (mmc_has_valid_request(dev))	{//#ifdef CONFIG_ARCH_EZX_E680		  /* add by w20598 */	          if (!mmc_slot_enable)	          {		       if (MMC_IO_READ == dev->io_request->cmd)		           mmc_media_transfer_done(dev->io_request,0);		       else		           mmc_media_transfer_done(dev->io_request,1);		       dev->io_request = NULL;                       return mmc_cim_default_state;  		  }		  else		 /* add end *///#endif                      return mmc_cim_handle_request;    }                    	return NULL;}/****************************************************************** *  State function handler ******************************************************************/typedef void *(*state_func_t)(struct mmc_dev *, int);static state_func_t g_single_card = &mmc_cim_default_state;void mmc_protocol_single_card( struct mmc_dev *dev, int state_flags ){	state_func_t    sf;	sf = g_single_card(dev,0);	while ( sf ) {		g_single_card = sf;		sf = g_single_card(dev,1);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -