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

📄 wtaudioin.c

📁 MCF5249的音频驱动程序,可以实现PCM的实时播放和采集
💻 C
📖 第 1 页 / 共 2 页
字号:
#define   DMA1_CTL				(*mcfReg32p(MCFDMA_DCR1))#define   DMA0_SA				(*mcfReg32p(MCFDMA_SAR0))#define   DMA1_SA				(*mcfReg32p(MCFDMA_SAR1))#define   DMA0_DA				(*mcfReg32p(MCFDMA_DAR0))#define   DMA1_DA				(*mcfReg32p(MCFDMA_DAR1))#define   DMA0_BC				(*mcfReg16p(MCFDMA_BCR0))#define   DMA1_BC				(*mcfReg16p(MCFDMA_BCR1))/* *	General purpose IO registers (in MBAR2). */#define	MCFSIM2_GPIOREAD	0x0		/* GPIO read values */#define	MCFSIM2_GPIOWRITE	0x4		/* GPIO write values */#define	MCFSIM2_GPIOENABLE	0x8		/* GPIO enabled */#define	MCFSIM2_GPIOFUNC	0xc		/* GPIO function */#define	MCFSIM2_GPIO1READ	0xb0		/* GPIO1 read values */#define	MCFSIM2_GPIO1WRITE	0xb4		/* GPIO1 write values */#define	MCFSIM2_GPIO1ENABLE	0xb8		/* GPIO1 enabled */#define	MCFSIM2_GPIO1FUNC	0xbc		/* GPIO1 function */#define	MCF_SDATAI3        0x00000200#define	MCF_SDATAI4        0x00000400/****************************************************************************/// audio devicetypedef struct WTAudio_dev{	int major;	unsigned char * rxbuf; //	int rxBufSize;  // max audio data count  if buffer; = buffersize/4   	int rxdmaStart;      //   	unsigned int nDmaCount;}WTAudio_dev;WTAudio_dev AudioDev={AUDIOINMAJOR,0,BUFSIZE,0,0};#define BUFFERINC(x,y,z)  ((x+y)%z)  //z: num of package  y: inc  x: indicate/****************************************************************************/void WTAudio_chipinit(void){#if DEBUG    printk("WTAudio_chipinit()\n");#endif    //*mcf2Reg32p(MCFA_IIS2CONFIG) = MCFA_IIS_CLK8 | MCFA_IIS_TXSRC_IIS1 |    //              MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK32BIT;    //*mcf2Reg32p(MCFA_IIS1CONFIG) = MCFA_IIS_CLK8 | MCFA_IIS_TXSRC_PDOR3 |	//MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK32BIT;     /* INTPUTCLK, PDOR3, SCLKINVERT*/	*mcf2Reg32p(MCFA_IIS1CONFIG) |=  0x00000800;    	*mcf2Reg32p(MCFA_IIS1CONFIG) |= MCFA_IIS_CLKINPUT |            MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK64BIT;// |MCFA_IIS_SCLKINV;      /*	*mcf2Reg32p(MCFSIM2_GPIO1FUNC) &= ~MCF_SDATAI3;	*mcf2Reg32p(MCFA_IIS3CONFIG) |=  0x00000800;    *mcf2Reg32p(MCFA_IIS3CONFIG) = MCFA_IIS_CLKIIS1 |            MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK64BIT;	*/    /* DataInControl, 1 Samples, PDIR2 */    *mcf2Reg32p(MCFA_DATAINCTRL) |= MCFA_DIC_PDIR2_IIS1 | MCFA_DIC_PDIR2_1SAMP;//MCFA_DIC_PDIR2_1SAMP;}/****************************************************************************//* ****************************************   Divide the rx buffer into DMABCNT dma buffers,   each time start dma to feed one of the dma buffers,   and each dma buffer should be aligned by 4bytes,   so the rx buffer should be aligned by 16bytes.*******************************************/static inline void WTAudio_rx_dmarun(){	if(WTAudio_rxdmaing)		return;	KDEBUG("rx_dmarun!\n");     	/* Set DMA transfer count */	set_dma_mode(WTAUDIO_RXDMA, DMA_MODE_READ | DMA_MODE_LONG_BIT);  	set_dma_device_addr(WTAUDIO_RXDMA, (MCF_MBAR2 + MCFA_PDIR2));  	set_dma_addr(WTAUDIO_RXDMA, (int)&AudioDev.rxbuf[AudioDev.rxdmaStart]);  	set_dma_count(WTAUDIO_RXDMA, nDmaCount);  	WTAudio_rxdmaing = 1;    	printk("rxbuf = %x\n",AudioDev.rxBufSize);  	printk("sa= %x da = %x\n",*mcfReg32p(0x340),*mcfReg32p(0x344));  	printk("Dmactl = %x count = %x\n",*mcfReg32p(0x348),*mcfReg8p(0x34c));  	printk("statue = %x vector = %x\n",*mcfReg8p(0x350),*mcfReg8p(0x354));  	printk("dmaroute= %x\n",*mcf2Reg32p(0x188));  	printk("bufA = %x\n", AudioDev.rxbuf);    	//WTAudio_rxbusy = 1;	//data buffer is aligned by 4bytes	enable_dma(WTAUDIO_RXDMA);}void WTAudio_rx_dmaisr(int irq, void *dev_id, struct pt_regs *regs){	KDEBUG("rx_dmaisr\n");	disable_dma(WTAUDIO_RXDMA);	WTAudio_rxdmaing = 0;	//adjust the data buffer 	//AudioDev.rxdmaStart = (AudioDev.rxdmaStart+(AudioDev.rxBufSize/DMABCNT)) % (AudioDev.rxBufSize);	AudioDev.rxdmaStart = 0;	AudioDev.nDmaCount = 0;	WTAudio_rx_dmarun();		} ssize_tWTAudio_read(struct file *filp, char *buf, size_t count, loff_t * ppos){	unsigned long bufcnt,slen;    	KDEBUG("m5249_read(buf=%x,count=0x%d)\n", (int) buf, count);   	if (count <= 0)return 0;	bufcnt = count ;tryagain:		if(bufcnt <= BUFSIZE)	{ 		slen = bufcnt;		AudioDev.nDmaCount = bufcnt;	}	else	{		slen = BUFSIZE;		AudioDev.nDmaCount = BUFSIZE;	}	WTAudio_rx_dmarun();	while(1)	{		if(!WTAudio_rxdmaing) break;		}	copy_to_user(buf,(char *)AudioDev.rxbuf,slen);	bufcnt -= slen;	if(bufcnt > 0)		goto tryagain;	          	 KDEBUG("WTAudio_read returned %d.\n", count);    	 return count; }void WTAudio_txdrain(void){#ifdef DEBUG    	printk("WTAudio_txdrain()\n");#endif    	WTAudio_rxbusy =0;	current->state = TASK_INTERRUPTIBLE;	schedule_timeout(1);	return;    	while (!signal_pending(current)) {		if (WTAudio_rxbusy == 0)	    		break;   	 }}/****************************************************************************/int WTAudio_open(struct inode *inode, struct file *filp){#if DEBUG    printk("WTAudio_open()\n");#endif#ifdef MODULE	MOD_INC_USE_COUNT;#endif	if (WTAudio_isopen)		return (-EBUSY);	WTAudio_isopen = 1;        	return (0);}int WTAudio_release(struct inode *inode, struct file *filp){#if DEBUG    printk("WTAudio_release()\n");#endif#ifdef MODULE       MOD_DEC_USE_COUNT;#endif	WTAudio_txdrain();	disable_dma(WTAUDIO_RXDMA);	WTAudio_rxdmaing = 0;	AudioDev.rxdmaStart = 0;	AudioDev.nDmaCount = 0;	WTAudio_isopen = 0;	WTAudio_rxbusy = 0;    	return (0);}/****************************************************************************/int WTAudio_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg){	int err =0;	int ret = 0;	//int val;		if(_IOC_DIR(cmd) & _IOC_READ)		err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));	else if (_IOC_DIR(cmd) & _IOC_WRITE)       	err =  !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));	    	if (err) return -EFAULT;	return ret;	}/****************************************************************************/struct file_operations WTAudio_fops = {  open:WTAudio_open,	/* open */  read:WTAudio_read,	/*read */  release:WTAudio_release,	/* release */  ioctl:WTAudio_ioctl,	/* ioctl */};/****************************************************************************/int __init WTAudio_init(void){     if (register_chrdev(AUDIOINMAJOR, "WTAUDIOIN", &WTAudio_fops) < 0) {	printk(KERN_WARNING "WTAUDIOIN: failed to register major %d\n",	       AUDIOINMAJOR);	return (0);    }	AudioDev.rxbuf = (unsigned char *)kmalloc(AudioDev.rxBufSize, GFP_KERNEL);    if (AudioDev.rxbuf  == NULL) {	printk("WTAUDIOIN: failed to allocate [%d] buffer\n",(AudioDev.rxBufSize));    }    printk("mem = %x\n",AudioDev.rxbuf);#ifdef MODULE		SET_MODULE_OWNER(&WTAudio_fops);#endif	printk("WTAUDIOIN RX: DMA channel=%d, irq=%d\n",	       WTAUDIO_RXDMA, WTAUDIO_RXDMAIRQ);	if (request_irq(WTAUDIO_RXDMAIRQ, WTAudio_rx_dmaisr,			(SA_INTERRUPT | IRQ_FLG_FAST), "AUDIO_IN(DMA)", NULL))	{	    printk("WTAUDIOIN: RX DMA IRQ %d already in use?\n",		   WTAUDIO_RXDMAIRQ);	}	//dmap = (BYTE *) dma_base_addr[WTAUDIO_RXDMA]; //选择通道	//dmap[MCFDMA_DIVR] = WTAUDIO_RXDMAIRQ;  //设置DMA中断向量:121	*mcfReg8p(MCFDAM_INTVR1) = WTAUDIO_RXDMAIRQ;	//*mcfReg8p(MCFDMA_INTVR0) = WTAUDIO_RXDMAIRQ;	/* Set interrupt level and priority */		*mcfReg8p(MCFSIM_ICRDMA1) = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;	//*mcfReg8p(MCFSIM_ICRDMA0) = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;			//*mcfReg8p(MCFSIM_ICRDMA1) = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI1;	//*((DWORD*) (MCF_MBAR + MCFSIM_IMR)) &=~MCFSIM_IMR_DMA0;	*mcfReg32p(MCFSIM_IMR) &=~MCFSIM_IMR_DMA1;	//*mcfReg32p(MCFSIM_IMR) &= ~MCFSIM_IMR_DMA0;		/* Set DMA to use channel 1 for audio rx */	*mcf2Reg8p(MCFA_DMACONF) &= ~(MCFA_DMA_1REQ); //PDIR2 on dma1	*mcf2Reg32p(MCFSIM2_DMAROUTE) |= (0x00000081<<8); //dam1 audio source 2		/* Set DMA to use channel 0 for audio */	//*mcf2Reg8p(MCFA_DMACONF) &= ~MCFA_DMA_0REQ; //	//*mcf2Reg32p(MCFSIM2_DMAROUTE) = 0x00000081; //dam0 audio source 1	if (request_dma(WTAUDIO_RXDMA, "AUDIO_IN")) {	    printk("WTAUDIO: RX DMA channel %d already in use?\n",		   WTAUDIO_RXDMA);	}     	WTAudio_chipinit();//	sema_init (&sem,1);//	memset((void *)DelayBuf,0,AudioDev.packsize);	return (0);	}#ifdef MODULEvoid WTAudio_cleanup(void){      kfree(AudioDev.rxbuf);      free_dma(WTAUDIO_RXDMA);      unregister_chrdev(AUDIOINMAJOR, "WTAUDIOIN");      printk("release WTAUDIO!!!\n");}module_init(WTAudio_init);module_exit(WTAudio_cleanup);MODULE_LICENSE("GPL");#endif/****************************************************************************/

⌨️ 快捷键说明

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