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

📄 mmc_pxa.c

📁 linux下mmc_sd卡的驱动.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
			card->info.read_bl_len = (1<<card->info.csd.read_bl_len);			card->info.write_bl_len = (1<<card->info.csd.write_bl_len);			card->info.capacity = (card->info.csd.c_size + 1) 					* (1<<(card->info.csd.c_size_mult + 2)) 					* card->info.read_bl_len;			MMC_DEBUG( MMC_DEBUG_LEVEL2, "card capacity=%dMb\n", 					card->info.capacity>>20 );			card->info.tran_speed = 20*1024; /* FIXME */			card->info.transfer_mode = MMC_TRANSFER_MODE_BLOCK_SINGLE; 		/* 2) set bus operation freq */			card_data->clkrt = pxa_mmc_clkrt( card->info.tran_speed );		/* 3) register card with MMC core */			mmc_register( MMC_REG_TYPE_CARD, card, 0 );		}/* IV. set DSR registers of the cards */#if 0 /* TODO */		if ( card->info.csd.dsr_imp ) {			set_dsr = TRUE;			/*  calculate DSR */		}#endif	}#if 0 /* TODO */	if ( set_dsr ) {			/* send CMD4 */	}#endif/* merge list of the newly inserted cards into controller card stack */	if ( !ctrlr->stack.ncards ) {		ctrlr->stack.first = stack->first;		ctrlr->stack.last = stack->last;	} else			ctrlr->stack.last->next = stack->first;		ctrlr->stack.ncards += stack->ncards;		ret = 0;	goto out;err_free:	__mmc_card_stack_free( stack );error:out:	return ret;}static inline int pxa_mmc_bus_width( mmc_controller_t ctrlr, mmc_card_t card, u8 width ){	int ret = 0;	if ((ret=pxa_mmc_stop_bus_clock( ctrlr )))            return ret;		MMC_CMD = CMD(55);	MMC_ARGH = card->info.rca;	MMC_ARGL = 0;	MMC_CMDAT =  MMC_CMDAT_R1;	if ((ret=pxa_mmc_complete_cmd(ctrlr, MMC_R1, FALSE)))		return ret;		if ((ret = pxa_mmc_stop_bus_clock( ctrlr )))		return ret;	MMC_CMD = CMD(6);	MMC_ARGH = 0;	MMC_ARGL = (width == 1) ?0:			(width == 4) ?2:				-1;	MMC_CMDAT = MMC_CMDAT_R1 | (1<<8);	/*if ((ret=pxa_mmc_complete_cmd(ctrlr, MMC_R1, FALSE)))		return ret;    	*/  	return 0;}static inline int pxa_mmc_send_csd( mmc_controller_t ctrlr ){	int ret = -EINVAL;		pxa_mmc_stop_bus_clock( ctrlr );		MMC_CMD = CMD(9);	MMC_ARGH = 0xa95d;	MMC_ARGL = 0x0;	MMC_CMDAT = MMC_CMDAT_R2;	ret = pxa_mmc_complete_cmd( ctrlr, MMC_R2, FALSE );	{ int i=15; 		for(i=15; i>=0; i--)			printk(KERN_EMERG"CSD %d is 0x%08x\n", i, PXA_MMC_RESPONSE(ctrlr, i));        }	return 0;}static inline void  pxa_mmc_send_rca( mmc_controller_t ctrlr){	int ret = -EINVAL;	u16 argl=0, argh=0;//	pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;	pxa_mmc_stop_bus_clock( ctrlr );		MMC_CMD = CMD(3);	MMC_ARGH = argh;	MMC_ARGL = argl;	MMC_CMDAT = MMC_CMDAT_R6;	ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE);        {  int i=6;	   for(i=5; i>=0; i--)		printk(KERN_EMERG"RCA %d is 0x%08x\n", i, PXA_MMC_RESPONSE(ctrlr, i));         }}static inline void pxa_mmc_send_cid( mmc_controller_t ctrlr){	int ret = -EINVAL;	u16 argl=0, argh=0;        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(2);        MMC_ARGH = argh;        MMC_ARGL = argl;        MMC_CMDAT = MMC_CMDAT_R2;        ret = pxa_mmc_complete_cmd(ctrlr, MMC_R2, FALSE);       // if(! ret)	  {   int i=15;              for(i=15; i>=0; i--)                { printk(KERN_EMERG"CID %d is 0x%08x\n ", i, PXA_MMC_RESPONSE(ctrlr, i));                  		}              printk(KERN_EMERG"CID[OID] is %c, %c \n", PXA_MMC_RESPONSE(ctrlr, 13), PXA_MMC_RESPONSE(ctrlr, 12));              printk(KERN_EMERG"CID[PNM] is %c. %c, %c, %c,%c\n", PXA_MMC_RESPONSE(ctrlr,11), PXA_MMC_RESPONSE(ctrlr, 10), PXA_MMC_RESPONSE(ctrlr, 9), PXA_MMC_RESPONSE(ctrlr, 8), PXA_MMC_RESPONSE(ctrlr, 7));                       }}static inline int pxa_mmc_send_cmd55( mmc_controller_t ctrlr ){ 	int ret = -EINVAL;	u16 argl=0, argh=0;        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(55);   /*APP_CMD, then the next command is  ACMD */	MMC_ARGH = argh;	MMC_ARGL = argl;	MMC_CMDAT = MMC_CMDAT_R1;		ret = pxa_mmc_complete_cmd(ctrlr, MMC_R1, FALSE);            return ret;}static inline int pxa_mmc_send_ocr( mmc_controller_t ctrlr ){	int ret = -EINVAL;	u16 argl=0, argh=0;        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(55);   /*APP_CMD, then the next command is  ACMD */	MMC_ARGH = argh;	MMC_ARGL = argl;	MMC_CMDAT = MMC_CMDAT_R1;		ret = pxa_mmc_complete_cmd(ctrlr, MMC_R1, FALSE);        if (!ret)   // is 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));                  }            while(! (PXA_MMC_RESPONSE(ctrlr, 4) & 0x80) )              { 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(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);                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));              }             }         else  // is MMC or non-card           printk(KERN_EMERG"pxa_mmc_send_ocr() CMD(55) error \n");	return ret;}/* MMC protocol macros: v3.4, p.120 */static int pxa_mmc_init_card_stack( mmc_controller_t ctrlr ){	int ret = -EIO;	u16 argl = 0U, argh = 0U;       	if ( !ctrlr || ctrlr->stack.ncards ) {		ret = -EINVAL;		goto error;	}         	/* initialize stack */  	/*     1) send CMD0 */	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )            {//printk("pxa_mmc_stop_bus_clock() error\n");		             goto error;}	/* 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 */	MMC_SPI = MMC_SPI_DISABLE;	MMC_CMD = CMD(0); /* CMD0 with zero argument */	MMC_ARGH = argh;	MMC_ARGL = argl;    	MMC_CMDAT = MMC_CMDAT_INIT;     	//MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD0(0x%04x%04x)\n", argh, argl );	if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_NORESPONSE, FALSE )) )             { MMC_DEBUG(MMC_DEBUG_LEVEL0, "pxa_mmc_complete_cmd error\n");		goto error; }           /* pxa_mmc_send_ocr(ctrlr);          pxa_mmc_send_cid(ctrlr);	 pxa_mmc_send_rca(ctrlr);	 pxa_mmc_send_rca(ctrlr);         pxa_mmc_send_csd(ctrlr);         */	/* update card stack */	if ( (ret = pxa_mmc_update_acq( ctrlr )) )	     {MMC_DEBUG(MMC_DEBUG_LEVEL0, "pxa_mmc_update_acq error \n");	 goto err_free; }	         //pxa_mmc_send_cid(ctrlr);        	/* move the controller to the IDLE state */ 	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )	     {MMC_DEBUG(MMC_DEBUG_LEVEL0, "pxa_mmc_stop_bus_clock error \n"); goto err_free;}    	pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );		ret = 0;	MMC_DEBUG( MMC_DEBUG_LEVEL2, "ncards=%d\n", ctrlr->stack.ncards );	goto out;err_free:	__mmc_card_stack_free( &ctrlr->stack ); error:out:	return ret;}static int pxa_mmc_check_card_stack( mmc_controller_t ctrlr ){	int ret = -1;	mmc_card_t card;	        //printk(KERN_EMERG"%s::%s\n\n",__FILE__,__FUNCTION__);	if ( !ctrlr )		goto error;		if ( ctrlr->stack.ncards > 0 )	 {/* for each card in the stack: */		for( card = ctrlr->stack.first; card; card = card->next ) {			u16 argh = card->info.rca;			u16 argl = 0UL;				/* 	1) send CMD9( card->rca ) */			if ( pxa_mmc_stop_bus_clock( ctrlr ) )				goto error;						/* SanDisk's cards do not respond to CMD9 */				MMC_CMD = CMD(13);			MMC_ARGH = argh;			MMC_ARGL = argl;			MMC_CMDAT = MMC_CMDAT_R1;						MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD13(0x%04x%04x)\n", 					argh, argl );			ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE );/* 	2) if card responded, it is still there */			if ( ret ) { //printk(KERN_EMERG"pxa_mmc_check_card_stack() MMC_CARD_STATE_UNPLUGGE ret is %d\n", ret);				card->state = MMC_CARD_STATE_UNPLUGGED;}		}	}	ret = 0;	error:	return ret;}/* This procedure links the bus master with a single card *  1)  cross checks with the internal stack management data if a card still *      exists in the slot *  2)  send CMD7( card->public.rca ) *  3)  setup data path and controller options  */static int pxa_mmc_setup_card( mmc_controller_t ctrlr, mmc_card_t card ) {	int ret = -ENODEV;	pxa_mmc_hostdata_t hostdata;	pxa_mmc_card_data_t card_data;	u16 argh = 0U;#ifdef CONFIG_MMC_DEBUG	u16 argl = 0U;#endif    	if ( !ctrlr || !card ) {		ret = -EINVAL;		goto error;	}    	if ( card->ctrlr != ctrlr ) {		MMC_DEBUG( MMC_DEBUG_LEVEL3, "card is on another bus\n" );		goto error;	}    	hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;	card_data = (pxa_mmc_card_data_t)card->card_data;	argh = card->info.rca;               /* select requested card */ 	if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) ) 		goto error;        	MMC_CMD = CMD(7);	MMC_ARGH = argh;	MMC_CMDAT = MMC_CMDAT_R1;	MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD7(0x%04x%04x)\n", argh, argl );	if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )		goto error;/* set controller options *///#ifndef CONFIG_MMC_DEBUG	MMC_CLKRT = card_data->clkrt; 	printk(" MMC_CLKRT = %x\n",MMC_CLKRT );//#endif    /* 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 );/*	if ((ret = pxa_mmc_bus_width(ctrlr, card, 4)))	{   printk(KERN_EMERG" ret is %d\n ", ret	);        	goto error;	       }*/	ret = 0;error:  	return ret;}static inline int pxa_mmc_iobuf_init( mmc_controller_t ctrlr, ssize_t cnt ){#ifdef PIO	pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;#endif #ifndef PIO/* TODO */#else	hostdata->iobuf.buf.pos = hostdata->iobuf.iodata;	hostdata->iobuf.buf.cnt = cnt;#endif	return 0;}/* TODO: ssize_t pxa_mmc_read_buffer( mmc_controller_t ctrlr, ssize_t cnt )effects: reads at most cnt bytes from the card to the controller I/O buffer;       takes care of partial data transfersrequieres: modifies: ctrlr->iobufreturns: number of bytes actually transferred or negative error code if there were any errors */ssize_t pxa_mmc_read_buffer( mmc_controller_t ctrlr, ssize_t cnt ){	ssize_t ret = -EIO;	pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;#ifndef PIO        	register int ndesc;	int chan = hostdata->iobuf.buf.chan;	pxa_dma_desc *desc;#endif

⌨️ 快捷键说明

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