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

📄 ac97_sport.c

📁 Blackfin AC97 Interface driver
💻 C
📖 第 1 页 / 共 2 页
字号:
	rxTail = 0;	return 0;}void ac97_sport_close(void){	dev.codec_initialized = 0;  sport_enable(-1,-1);  //	bzero(&dev, sizeof(dev)); 	return;}void ac97_sport_start(void) { 	if( !dev.codec_initialized )   {    init_ac97();    sport_enable(1,1); 		//printk("ac97_sport_start\n");	  }		txHead = 0;	txTail = 0;		rxHead = 0;	rxTail = 0;}void ac97_sport_stop(void) { 	dev.codec_initialized = 0;	sport_enable(-1,-1); 	bfin_write_DMA4_CONFIG(0) ;		bfin_write_DMA3_CONFIG(0) ;	}void getrx(){	short i,count;	struct ac97_frame *pSrc; 	unsigned short tmpDest,tmptail;	pSrc = (struct ac97_frame *)&dev.rxbuf[ac97_rx_lastfrag*FRAG_SIZE];		tmptail = rxTail + 1;	if (tmptail >= AC97_BUFFER_SIZE)				{		tmptail = 0;	}	for(i=0; i<FRAG_SIZE; i++) 	{									if (tmptail != rxHead)			{						if (pSrc->ac97_tag & TAG_PCM_RIGHT)				{									tmpDest = (unsigned short)((pSrc->ac97_pcmleft12_pcmright4 & 0x000f) << 12);					tmpDest |= (unsigned short)(((unsigned short)(pSrc->ac97_pcmright16) >> 4) & 0x0fff);								rxbuf[rxTail++] = (short)tmpDest;						if (rxTail >= AC97_BUFFER_SIZE)								{						rxTail = 0;					}					tmptail = rxTail;				}								if ((tmptail != rxHead) && (bStereo))				{					if (pSrc->ac97_tag & TAG_PCM_LEFT)					{											tmpDest = (pSrc->ac97_cmddataL8_pcmleftH8 & 0x00ff) << 8;						tmpDest |= (pSrc->ac97_pcmleft12_pcmright4 >> 8) & 0x00ff;									rxbuf[rxTail++] = (short)tmpDest;							if (rxTail >= AC97_BUFFER_SIZE)									{							rxTail = 0;						}											tmptail = rxTail;													}					}					}											if (pSrc->ac97_tag & TAG_CMD)			{								tmpDest = (pSrc->ac97_addr4_data12 & 0x0fff) << 4;				tmpDest |= (pSrc->ac97_cmddataL8_pcmleftH8 & 0xf000) >> 12;							dev.register_cache[(pSrc->ac97_addr >> 8) & 0x7f] = tmpDest;			//				printk("reg=%x val=%x\n",(pSrc->ac97_addr >> 8)& 0x7f,tmpDest);					}											pSrc ++;													}	}ssize_t ac97_audio_read(uint16_t* pcmdata, size_t len){	int i;	short tmphead;	short realCount;			if ((!dev.codec_ready) || (!dev.codec_initialized))	{				return 0;	}	realCount = 0;	for(i=0; i<len; i++)	{					if (rxHead == rxTail)		{					break;		}		pcmdata[i] = rxbuf[rxHead++];		if (rxHead >= AC97_BUFFER_SIZE)		{			rxHead = 0;		}						realCount++;	}		return realCount;	}/* * on rx: check if we got any commands * return 0: success *        -EINPROGRESS: dma not asserted */int ac97_sport_handle_rx(void){	int  tmpFrag,i;	int status=0;	short tmptail;//	unsigned int next_dma_ptr;	status = bfin_read_DMA3_IRQ_STATUS();	if( !(status & DMA_DONE) )	{		bfin_write_DMA3_IRQ_STATUS(status);				return -EINPROGRESS;	}		bfin_write_DMA3_IRQ_STATUS(DMA_DONE);		    			dev.codec_ready = dev.rxbuf[ac97_rx_lastfrag*FRAG_SIZE].ac97_tag & TAG_VALID;			if(dev.codec_ready)	{		getrx();			 if (bReadWaiting)	 {	 	bReadWaiting = 0;		wake_up(&dev.audio_in_wait); /* wake up any proces waiting for at least 1 fragment */			 }	}		ac97_rx_lastfrag++;	if (ac97_rx_lastfrag>=FRAG_NUM)	{		ac97_rx_lastfrag = 0;	}		return 0;}ssize_t ac97_audio_write(const uint16_t* pcmdata, size_t len){		int i;	short tmptail;	short realCount;			if ((!dev.codec_ready) || (!dev.codec_initialized))	{				return 0;	}		tmptail = txTail+1;	if(tmptail >= AC97_BUFFER_SIZE)	{		tmptail = 0;	}	if (tmptail == txHead)	{						return 0;	}		realCount = 0;		tmptail = txTail;		for(i=0; i<len; i++)		{						tmptail++;			if (tmptail >= AC97_BUFFER_SIZE)			{				tmptail = 0;			}							if (tmptail == txHead)			{						break;			}			txbuf[txTail] = pcmdata[i];			txTail = tmptail;						realCount++;		}		return realCount;	}extern unsigned char lightstatus;#define MUTE_SHUT									0x01#define LCD_LIGHT_ADDR					0x203f6000	///#define pLCD_LIGHT_ADDR ((volatile unsigned char *)LCD_LIGHT_ADDR)unsigned char tx(){	int i;	unsigned long tmpData1,tmpData2,tmpData3;	unsigned short *pSrc;	struct ac97_frame* dest;	unsigned long tmpSrc;	unsigned int Bitmappos;		dest = (struct ac97_frame*)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE];	for (i=0;i<FRAG_SIZE;i++)	{		Bitmappos = 0x0001 << curBitmapCol;		if (pBitmap[curBitmapRow] & Bitmappos)		{			if(txHead != txTail)			{				tmpSrc = txbuf[txHead++];					if(txHead >= AC97_BUFFER_SIZE)				{					txHead = 0;				}										tmpData2 = (tmpSrc & 0xf000) >> 12;								tmpData3 = (tmpSrc & 0x0fff) << 4;							dest->ac97_pcmleft12_pcmright4 = tmpData2 ;										dest->ac97_pcmright16 = tmpData3;														if (bStereo)									{					tmpSrc = txbuf[txHead++];						if(txHead >= AC97_BUFFER_SIZE)					{						txHead = 0;					}					}							tmpData2 = (tmpSrc & 0xff00) >> 8;								tmpData3 = (tmpSrc & 0x00ff) << 8;							dest->ac97_cmddataL8_pcmleftH8 = tmpData2 ;										dest->ac97_pcmleft12_pcmright4 |= tmpData3;										dest->ac97_tag = TAG_VALID | TAG_PCM;			}			else			{										dest->ac97_cmddataL8_pcmleftH8 = 0 ;										dest->ac97_pcmleft12_pcmright4 = 0;											dest->ac97_pcmright16 = 0;								dest->ac97_tag = TAG_VALID | TAG_PCM;													}		}		else		{						dest->ac97_cmddataL8_pcmleftH8 = 0 ;										dest->ac97_pcmleft12_pcmright4 = 0;											dest->ac97_pcmright16 = 0;								dest->ac97_tag = TAG_VALID;		  }	  	  dest ++;		  	  curBitmapCol ++;	  if(curBitmapCol >= 32)	  {	  	curBitmapCol = 0;	  	curBitmapRow ++;	  	if (curBitmapRow >= BitmapLen)	  	{	  		curBitmapRow = 0;	    }	  }	}		return 1;}int ac97_sport_handle_tx(void){	short i;	int tmpFrag;	int status=0;  _ac97_cmd_t *pac97_cmd;  		status = bfin_read_DMA4_IRQ_STATUS();	if( !(status & DMA_DONE) )	{		bfin_write_DMA4_IRQ_STATUS(status);				 return -EINPROGRESS;	}	bfin_write_DMA4_IRQ_STATUS(DMA_DONE);		if(dev.codec_ready)	{				struct ac97_frame* dest;	 		 		if (!dev.codec_initialized)		{			init_ac97();//			return;		}				memset ((char *)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE],0,FRAG_SIZE*sizeof(struct ac97_frame));		tx();		dest = (struct ac97_frame*)&dev.txbuf[ac97_tx_lastfrag*FRAG_SIZE];		dest += 6;		while (pac97_cmd = outqueue_cmd())		{			dest->ac97_tag |= TAG_VALID | TAG_CMD;			dest->ac97_addr = pac97_cmd->reg;					dest->ac97_addr4_data12 = (pac97_cmd->value >> 4) & 0x0fff;						dest->ac97_cmddataL8_pcmleftH8 |= (pac97_cmd->value << 12) & 0xf000;			dest += 6;											//printk("cmd:reg = %x val=%x\n",pac97_cmd->reg,pac97_cmd->value);		}		if (bWriteWaiting)		{			bWriteWaiting = 0;	  	wake_up(&dev.audio_out_wait);  	}	} // codec ready		ac97_tx_lastfrag++;	if (ac97_tx_lastfrag >= FRAG_NUM)	{		ac97_tx_lastfrag = 0;	}	return 0;} // handle txint ac97_audio_read_min_bytes(){	int read_max;		if ((!dev.codec_ready) || (!dev.codec_initialized))	{		//printk("not ready\n");		return 0;	}	if(rxTail < rxHead )	{		read_max = AC97_BUFFER_SIZE - rxHead + rxTail;			}	else	{		read_max = rxTail - rxHead;	}		return read_max; }int ac97_wait_for_audio_read_with_timeout(unsigned long timeout){	bReadWaiting = 1;	return interruptible_sleep_on_timeout(&dev.audio_in_wait, timeout);}int ac97_wait_for_audio_write_with_timeout(unsigned long timeout){	bWriteWaiting = 1;	return interruptible_sleep_on_timeout(&dev.audio_out_wait, timeout);}//only for 48Kint ac97_audio_write_max_bytes(void){ 	int write_max;		if ((!dev.codec_ready) || (!dev.codec_initialized))	{		return 0;	}	if(txTail >= txHead )	{		write_max = AC97_BUFFER_SIZE - txTail + txHead;			}	else	{		write_max = txHead - txTail;	}		return write_max; }void ac97_set_sample_rate(unsigned int rate){	ac97_sport_set_register(AC97_PCM_FRONT_RATE,rate);		ac97_sport_set_register(AC97_PCM_LR_RATE,rate);		ac97_sport_get_register(AC97_PCM_FRONT_RATE);	ac97_sport_get_register(AC97_PCM_LR_RATE);}

⌨️ 快捷键说明

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