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

📄 mmc_pxa.c

📁 linux下mmc_sd卡的驱动.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
				ret = MMC_ERROR_ERASE_RESET;				goto mmc_error;			}		}	}    	if ( ret >= 0 )		pxa_mmc_set_state( ctrlr,  PXA_MMC_FSM_END_CMD );	goto out;mmc_error:#if 1	if ( send_abort ) {		/* send CMD12 to abort failed transfer */            	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )                	goto error;    	        MMC_CMD = CMD(12); /* STOP_TRANSMISSION */        	MMC_CMDAT = MMC_CMDAT_R1;    				if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )		        goto error;    				ret = -EIO;		goto error;	}#endiferror:	/* move controller to the IDLE state */       // printk(__FILE__" "__FUNCTION__"error RET IS %d\n", ret);        	pxa_mmc_stop_bus_clock( ctrlr );	pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );out:	return ret;}/* int pxa_mmc_complete_io( mmc_controller_t ctrlr, mmc_dir_t cmd, mmc_dir_t dir, mmc_transfer_mode_t mode )Effects: finilizes data transfer request  Reqires: controller is in the END_BUFFER stateModifies: moves controller to the IDLE stateReturns: zero upon success or error condition code otherwise */static mmc_error_t pxa_mmc_complete_io( mmc_controller_t ctrlr, mmc_dir_t dir, mmc_transfer_mode_t mode ){	int ret = MMC_ERROR_GENERIC; 	if ( pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_END_IO ) )		goto error;    	switch ( mode ) {	case MMC_TRANSFER_MODE_STREAM: /* FIXME */		if ( dir == MMC_WRITE ) {		/* 1. wait for STOP_CMD intr */			if ( (ret = pxa_mmc_init_completion( ctrlr,					MMC_I_MASK_STOP_CMD )) )				goto error;			if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 					MMC_I_REG_STOP_CMD )) )				goto error;		}		/* 2. send CMD12 */		if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )			goto error;    		MMC_CMD = CMD(12); /* STOP_TRANSMISSION */		MMC_CMDAT = MMC_CMDAT_R1;		if ( dir == MMC_WRITE ) 			MMC_CMDAT |= MMC_CMDAT_BUSY;            		/* 3. wait for CMD12 to complete */		MMC_DEBUG( MMC_DEBUG_LEVEL3, "ready for CMD12\n" );		if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )			goto error;            		/* 4. wait for DATA_TRAN_DONE intr */		if ( (ret = pxa_mmc_init_completion( ctrlr,				MMC_I_MASK_DATA_TRAN_DONE )) )			goto error;		if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 				MMC_I_REG_DATA_TRAN_DONE )) )			goto error;	    		if ( dir == MMC_WRITE ) {		/* 5. wait for PRG_DONE intr */			if ( (ret = pxa_mmc_init_completion( ctrlr,					MMC_I_MASK_PRG_DONE )) )				goto error;        	        if ( (ret = pxa_mmc_wait_for_completion( ctrlr,                 	        	MMC_I_REG_PRG_DONE )) )				goto error;		}		break;	case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:		/* 1. wait for DATA_TRAN done intr */		if ( (ret = pxa_mmc_init_completion( ctrlr,				MMC_I_MASK_DATA_TRAN_DONE )) )			goto error;		if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 				MMC_I_REG_DATA_TRAN_DONE )) )			goto error;            		/* 2. send CMD12 */		if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )			goto error;    		MMC_CMD = CMD(12); /* STOP_TRANSMISSION */		MMC_CMDAT = MMC_CMDAT_R1;		if ( dir == MMC_WRITE ) 			MMC_CMDAT |= MMC_CMDAT_BUSY;            		MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD12\n" );		if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )			goto error;        		if ( dir == MMC_WRITE ) {		/* 3. wait for PRG_DONE intr */			if ( (ret = pxa_mmc_init_completion( ctrlr,					MMC_I_MASK_PRG_DONE )) )				goto error;			if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 					MMC_I_REG_PRG_DONE )) )				goto error;		}		break;	case MMC_TRANSFER_MODE_BLOCK_SINGLE:		/* 1. wait for DATA_TRAN_DONE intr */		if ( (ret = pxa_mmc_init_completion( ctrlr,				MMC_I_MASK_DATA_TRAN_DONE )) )			goto error;		if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 				MMC_I_REG_DATA_TRAN_DONE )) )			goto error;            		if ( dir == MMC_WRITE ) {		/* 2. wait for PRG_DONE intr */			if ( (ret = pxa_mmc_init_completion( ctrlr,					MMC_I_MASK_PRG_DONE )) )				goto error;			if ( (ret = pxa_mmc_wait_for_completion( ctrlr, 					MMC_I_REG_PRG_DONE )) )				goto error;		}		break;	default:		MMC_DEBUG( MMC_DEBUG_LEVEL3, "unknown transfer mode\n" );		goto error;	}/* move the controller to the IDLE state */ 	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )		goto error;    	pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );	ret = 0;error:	return ret;}static inline int pxa_mmc_update_acq( mmc_controller_t ctrlr ){	int ret = -EINVAL;	pxa_mmc_hostdata_t hostdata = NULL;	mmc_card_t card = NULL;	mmc_card_stack_rec_t fake;	mmc_card_stack_t stack = &fake;	u16 argl = 0U, argh = 0U;	int ncards = 0;      	if ( !ctrlr )		goto error;	hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;		__mmc_card_stack_init( stack );        /*send the CMD55 to determined SD or MMC*/        ret =  pxa_mmc_send_cmd55( ctrlr );        if (!ret)   /* SD */            {		pxa_mmc_stop_bus_clock( ctrlr ); //	       MMC_CLKRT = MMC_CLKRT_0_3125MHZ;	       MMC_CLKRT = MMC_CLKRT_20MHZ;               MMC_RESTO = MMC_RES_TO_MAX;               MMC_CMD = CMD(41);   /*The command is ACMD, ask the accessed card to send its operating condition register(OCR)*/               MMC_ARGH = argh;               MMC_ARGL = argl;	                MMC_CMDAT = MMC_CMDAT_R3;               if(!(ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE)))                  {                      argh = (PXA_MMC_RESPONSE(ctrlr, 4)<<8) | PXA_MMC_RESPONSE(ctrlr, 3);                      argl = (PXA_MMC_RESPONSE(ctrlr, 2)<<8) | PXA_MMC_RESPONSE(ctrlr, 1);                                        /*    printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 4));                      printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 3));                      printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 2));                      printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 1));		      printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr,0));                  */                  }            /*continue send CMD55+CMD41, untile the card power up */            while(! (PXA_MMC_RESPONSE(ctrlr, 4) & 0x80) )              { pxa_mmc_stop_bus_clock( ctrlr );//               MMC_CLKRT = MMC_CLKRT_0_3125MHZ;               MMC_CLKRT = MMC_CLKRT_20MHZ;	//by huoran	       MMC_RESTO = MMC_RES_TO_MAX;               MMC_CMD = CMD(55);               MMC_ARGH = 0;               MMC_ARGL = 0;          		MMC_CMDAT = MMC_CMDAT_R1;                ret = pxa_mmc_complete_cmd(ctrlr, MMC_R1, FALSE);	                        pxa_mmc_stop_bus_clock( ctrlr );		MMC_CMD = CMD(41);		MMC_ARGH = argh | 0x80;                MMC_ARGL = argl;                        MMC_CMDAT = MMC_CMDAT_R3;                                ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE);		if (ret == MMC_ERROR_TIME_OUT_RESPONSE)			break;              //  argh = (PXA_MMC_RESPONSE(ctrlr, 4)<<8) | PXA_MMC_RESPONSE(ctrlr, 3);	//	argl = (PXA_MMC_RESPONSE(ctrlr, 2)<<8) | PXA_MMC_RESPONSE(ctrlr, 1);           /*     printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 4));                printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 3));                printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 2));		printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 1));		printk(KERN_EMERG"Volage is 0x%08x\n", PXA_MMC_RESPONSE(ctrlr, 0));           */              }         /*card identification, if the card present then ask it to send RCA */         for(;;)         { 		argh = 0; 		argl = 0; 		if ((ret=pxa_mmc_stop_bus_clock(ctrlr))) 			goto err_free;		MMC_CMD = CMD(2);		MMC_ARGH = argh;		MMC_ARGL = argl;		MMC_CMDAT = MMC_CMDAT_R2;		ret = pxa_mmc_complete_cmd(ctrlr, MMC_R2, FALSE);		if (ret==MMC_ERROR_TIME_OUT_RESPONSE)			break;		else if(ret)				goto err_free;		/*if the response have receive , then the card present,and ask the RCA*/				if ((ret = pxa_mmc_stop_bus_clock( ctrlr )))			goto err_free;		MMC_CMD = CMD(3);		MMC_ARGH = argh;		MMC_ARGL = argl;		MMC_CMDAT = MMC_CMDAT_R6;			ret = pxa_mmc_complete_cmd(ctrlr, MMC_R3, FALSE);				if (ret)			goto err_free; 		argh = (PXA_MMC_RESPONSE(ctrlr, 4)<<8) | PXA_MMC_RESPONSE(ctrlr, 3) ;		 		card = __mmc_card_alloc(sizeof(pxa_mmc_card_data_rec_t));		if (!card)			goto err_free;				card->info.rca = argh;		card->slot = ctrlr->slot_next++;		card->ctrlr =ctrlr;		if (!__mmc_card_stack_add(stack, card))			goto err_free;                            ++ncards;        }                  }   /* SD */        else   /* MMC */        {	/* max open-drain mode frequency is 400kHZ *///	MMC_CLKRT = MMC_CLKRT_0_3125MHZ;	MMC_CLKRT = MMC_CLKRT_20MHZ;	MMC_RESTO = MMC_RES_TO_MAX; /* set response timeout */	/*  discover and add cards to the stack */  	/* I. bus operation condition setup */	/*      1) send CMD1 */	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )		goto err_free;    	argl = 0x0000;	argh = 0x0004;	MMC_CMD = CMD(1);	MMC_ARGH = argh;	MMC_ARGL = argl;     	MMC_CMDAT = MMC_CMDAT_BUSY|MMC_CMDAT_R3;     	MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD1(0x%04x%04x)\n", argh, argl );	ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE );	if ( !ret ) {		argh = (PXA_MMC_RESPONSE( ctrlr, 4 ) << 8) 			| PXA_MMC_RESPONSE( ctrlr, 3 );		argl = (PXA_MMC_RESPONSE( ctrlr, 2 ) << 8)			| PXA_MMC_RESPONSE( ctrlr, 1 );	} else if ( ret != MMC_ERROR_TIME_OUT_RESPONSE ) 		goto err_free;    	if ( !argh && !argl ) {		MMC_DEBUG( MMC_DEBUG_LEVEL0, 			"assuming full voltage range support\n" );		argh = 0x00ff;		argl = 0xff00;	}    	/* 2) continuously send CMD1 'till there're busy cards */	for(;;) {                       		if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )			goto err_free;		MMC_CMD = CMD(1);		MMC_ARGH = argh;		MMC_ARGL = argl;		MMC_CMDAT = MMC_CMDAT_BUSY|MMC_CMDAT_R3;        		MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD1(0x%04x%04x)\n", argh, argl );		ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE );		if ( ret == MMC_ERROR_TIME_OUT_RESPONSE )			break; 		else if ( !ret ) {			/* busy state reported by LOW signal level 			 * (MMC v3.2, p.58)			 *			 * Thanks to Alexander Samoutin :)			 */			if ( !(PXA_MMC_RESPONSE( ctrlr, 4 ) & 0x80) ) {				MMC_DEBUG( MMC_DEBUG_LEVEL3, "busy state reported\n");				udelay( 20 );				continue;			} else 				break;		} else			goto err_free;	} // printk("end continuely send CMD1 \n\n");/* II. card identification: the cards in Ready state  *     are the only expected to respond  */     	for (;;) {		argh = 0U;		argl = 0U;                   // printk("run");		/* 1) send CMD2 */		if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )			goto err_free;        		MMC_CMD = CMD(2);		MMC_ARGH = 0x0003;		MMC_ARGL = 0xf300;		MMC_CMDAT = MMC_CMDAT_R2;        		MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD2(0x%04x%04x)\n", argh, argl );		ret = pxa_mmc_complete_cmd( ctrlr, MMC_R2, FALSE );		if ( ret == MMC_ERROR_TIME_OUT_RESPONSE )			break;        		else if ( ret ) /* bus error */			goto err_free;               // printk("run here, ret is %d \n\n ", ret);        	        /* TODO: store CID for the card */                	/* 2) assign RCA */		if ( !++ctrlr->rca_next ) /* overflow */			++ctrlr->rca_next;		argh = ctrlr->rca_next;                 	/* 3) send it to the card last responded (CMD3) */		if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )			goto err_free;        		MMC_CMD = CMD(3);		MMC_ARGH = argh;		MMC_ARGL = argl;		MMC_CMDAT = MMC_CMDAT_R1;		MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD3(0x%04x%04x)\n", argh, argl );		ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE );		if ( ret )   /* CMD3 failed */ 			goto err_free;		card = __mmc_card_alloc( sizeof( pxa_mmc_card_data_rec_t ) );		if ( !card ) {			MMC_ERROR( "out of memory\n" );			goto err_free;		}		card->info.rca = argh;  		card->slot = ctrlr->slot_next++; /* FIXME: minor encoding */		card->ctrlr = ctrlr;    		if ( !__mmc_card_stack_add( stack, card ) )			goto err_free;        		MMC_DEBUG( MMC_DEBUG_LEVEL2, "added card: "				"slot %d, RCA=0x%04x\n", card->slot, argh );		++ncards;	}       //  printk("end card identification \n\n");       }  /*MMC*/ 	if ( ncards ) {/* III. read CSD registers of all cards; DSR support also reported there */		for ( card = stack->first; card; card = card->next ) {			pxa_mmc_card_data_t card_data = 				(pxa_mmc_card_data_t)card->card_data;	    			/* 1) send CMD9 */			argh = card->info.rca;			argl = 0U;        			if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )				goto err_free;        			MMC_CMD = CMD(9);			MMC_ARGH = argh;			MMC_ARGL = argl;			MMC_CMDAT = MMC_CMDAT_R2;        			MMC_DEBUG( MMC_DEBUG_LEVEL3, 				"CMD9(0x%04x%04x)\n", argh, argl );			if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R2, FALSE )) )				goto err_free;        				memcpy( &card->info.csd, hostdata->mmc_res, 15 );			MMC_DUMP_CSD( card );	    

⌨️ 快捷键说明

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