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

📄 record.c

📁 at91rm9200开发板上音频接口—UDA1380的linux2.4驱动及测试例程
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "khead.h"#include <sound_config.h>#include <dev_table.h>#include <linux/soundcard.h>#include "sound.h"#include <asm/arch/pio.h>#include <asm/arch/AT91RM9200_PDC.h>#include <asm/arch/AT91RM9200_SSC.h>#include <linux/spinlock.h>#include "lib_SSC.h"                                                                                                                                                                /* HHTech add, uda1380 i2c commands */extern unsigned int I2C_test(void);extern unsigned int I2C_read(unsigned int reg, unsigned int *_data, int);extern unsigned int I2C_write(unsigned int reg, unsigned int data, int);#define I2S_ASY_MASTER_TX_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\AT91C_SSC_CKS_DIV   +\AT91C_SSC_CKO_CONTINOUS      +\AT91C_SSC_START_FALL_RF +\((1<<16) & AT91C_SSC_STTDLY) +\((((nb_bit_by_slot*nb_slot_by_frame)/2)-1) <<24))#define I2S_ASY_TX_FRAME_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\(nb_bit_by_slot-1)  +\AT91C_SSC_MSBF   +\(((nb_slot_by_frame-1)<<8) & AT91C_SSC_DATNB)  +\(((nb_bit_by_slot-1)<<16) & AT91C_SSC_FSLEN) +\AT91C_SSC_FSOS_NEGATIVE)                                                                                                                                static int audio_dev_dsp; static spinlock_t tx_count_lock;static spinlock_t rx_count_lock;static wait_queue_head_t rx_buffer_end;                                                                                AT91PS_SSC ssc_regs;AT91PS_PDC pdc_regs;AT91PS_AIC aic_regs;                                                                                //#define dmatrans#define BUFSIZE (256*1024)#define DMASIZE (64*1024)int a9200_isopen;int a9200_txbusy,a9200_rxbusy;int a9200_dmaing,a9200_rxdmaing;unsigned int a9200_speed;unsigned int a9200_stereo;unsigned int a9200_bits;unsigned int a9200_format;volatile unsigned int a9200_rxstart;volatile unsigned int a9200_rxend;unsigned char *a9200_tx_buf;unsigned char *a9200_rx_buf;volatile unsigned int a9200_dmastart;volatile unsigned int a9200_dmacount,a9200_rxdmacount;volatile unsigned int a9200_append;                                                                                unsigned char uda1380_rx_init[] = {	0x00, 0x0f, 0x3f,	0x01, 0x00, 0x88,	0x02, 0xaf, 0xff,	0x03, 0x00, 0x00,	0x04, 0x02, 0x02,	0x10, 0x00, 0x00,	0x11, 0xb0, 0xb0,	0x12, 0x00, 0x00,	0x13, 0x00, 0x00,	0x14, 0x00, 0x00,	0x20, 0x00, 0x00,	0x21, 0x08, 0x08,	0x22, 0x16, 0x0C,	0x23, 0x00, 0x00};	void codec_init(unsigned char *command){        int ic;        unsigned int msb, lsb, data, reg;                                                                                //      PDEBUG("Testing I2C\n");//        printk("Init uda1380...\n");        for (ic = 0; ic < 42; ic += 3) {                reg = command[ic];                lsb = command[ic + 1];                msb = command[ic + 2];                data = msb << 8 | lsb;                I2C_write(reg, data, 2);              //I2C_read(reg,&tata,2);              //printk("0x%p data set to = %p ( %p )\n",reg,tata,data);        }//      printk("UDA1380 init ok.\n");}                                                                                void SSC_init(void){  //      printk("Init SSC...\n");        ssc_regs = (AT91PS_SSC) AT91C_VA_BASE_SSC1;        pdc_regs = (AT91PS_PDC) AT91C_VA_BASE_PDC_SSC1;        aic_regs = (AT91PS_AIC) AT91C_VA_BASE_AIC;                a9200_speed = 44100;        a9200_format = AFMT_S16_BE;        a9200_bits = 16;        a9200_stereo = 1;        a9200_isopen = 1;        a9200_rxbusy = 0;        a9200_dmaing = 0;        a9200_rxdmaing = 0;                spin_lock_init(&tx_count_lock);        spin_lock_init(&rx_count_lock);                init_waitqueue_head(&rx_buffer_end);                                                                                        AT91_SYS->PMC_PCER = 1 << AT91C_ID_SSC1;/* Peripheral Clock Enable */        /*soft reset */        ssc_regs->SSC_CR = AT91C_SSC_SWRST;        /* Clear Transmit and Receive Counters */        AT91F_PDC_Close(pdc_regs);        AT91F_SSC_SetBaudrate(ssc_regs, AT91C_MASTER_CLOCK,FILE_SAMPLING_FREQ *(BITS_BY_SLOT * SLOT_BY_FRAME));                                                                                        ssc_regs->SSC_IDR = 0xCFF;      //disabled all                                                                                        aic_regs->AIC_IECR = 0x1 << AT91C_ID_SSC1; //Enable interrupt                                                                                        /* SSC Transmit Clock Mode Register */        ssc_regs->SSC_TCMR = I2S_ASY_MASTER_TX_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);        /* SSC Transmit Frame Mode Register */        ssc_regs->SSC_TFMR = I2S_ASY_TX_FRAME_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);        /* SSC_RFMR */        ssc_regs->SSC_RFMR = I2S_ASY_TX_FRAME_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);        /* SSC_RCMR */        ssc_regs->SSC_RCMR = I2S_ASY_MASTER_TX_SETTING(BITS_BY_SLOT,SLOT_BY_FRAME);}                                                                                static unsigned int ssi_audio_setbits(int dev, unsigned int bits){   return 1 ;  }                                                                                static signed short ssi_audio_setchannel(int dev, signed short channels){   return 1 ;  }                                                                                static int ssi_audio_setspeed(int dev, int speed){   return 1 ;  }void a9200_mute(void){}                                                                  /******************************************************************************************************* Input:*       dev:         The major number of the device.*       cmd:         The command to control the codec.* Value Returned:    1       success.*                    -1      falure.** Description: This routine will be used to control the codec.** Modification History:*       8 JAN,2002, Initial version.                    Li Qin*******************************************************************************************************/static int at91_audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg){     //   int val, ret = 0;     //   U32 tmpdata;     //   U8 lsb, msb;        return 1;}//int a9200_tx_dmarunflag=0;void __inline__ a9200_tx_dmarun(void){	unsigned long *bp;	U32 dma_tx_addr;	//	if(a9200_tx_dmarunflag==0)//	{//	  printk("a9200_tx_dmarun.\n");//	  a9200_tx_dmarunflag = 1;//	}	a9200_dmaing = 1;	a9200_txbusy = 1;	bp = (unsigned long *) & a9200_tx_buf[a9200_dmastart];	dma_tx_addr = virt_to_phys((void *)bp);	AT91F_PDC_SetTx(pdc_regs,(char *)dma_tx_addr,a9200_dmacount/2);//	AT91F_PDC_SetNextTx(pdc_regs,(char *)dma_tx_addr,a9200_dmacount/2);        //pdc_regs->PDC_PTCR = AT91C_PDC_TXTDIS;	pdc_regs->PDC_PTCR = AT91C_PDC_TXTEN;	ssc_regs->SSC_CR = AT91C_SSC_TXEN;//printk("pdc_ptsr = %p ssc_sr = %p \n",pdc_regs->PDC_PTSR,ssc_regs->SSC_SR);	ssc_regs->SSC_IER = 0x1 << 2; // endtx interrupt	}//int a9200_tx_dmabufflag=0;void a9200_tx_dmabuf(void){	// if already running//	if(a9200_tx_dmabufflag == 0)//	{//	  printk("a9200_tx_dmabuf.\n");//	  a9200_tx_dmabufflag = 1;//	}	  	if(a9200_dmaing)		return;  spin_lock(&tx_count_lock);	// set dma buff size	a9200_dmacount = (a9200_append >= a9200_dmastart) ? (a9200_append - a9200_dmastart) : (BUFSIZE - a9200_dmastart);	if(a9200_dmacount > DMASIZE)		a9200_dmacount = DMASIZE ;	if(a9200_dmacount > 0)		a9200_tx_dmarun();	else		a9200_txbusy = 0;			spin_unlock(&tx_count_lock);}//int a9200_rx_dmarunflag=0;void __inline__ a9200_rx_dmarun(void){        unsigned long *bp;        U32 dma_rx_addr;        a9200_rxdmaing = 1;        a9200_rxbusy = 1;//  if(a9200_rx_dmarunflag==0)// {//  printk("a9200_rx_dmarun. \n");//  a9200_rx_dmarunflag=1;// }        bp = (unsigned long *) a9200_rx_buf + a9200_rxstart;        dma_rx_addr = virt_to_phys((void *)bp);        AT91F_PDC_SetRx(pdc_regs,(char *)dma_rx_addr,a9200_rxdmacount);        pdc_regs->PDC_PTCR = AT91C_PDC_RXTEN;        ssc_regs->SSC_CR = AT91C_SSC_RXEN;//printk("pdc_ptsr = %p ssc_sr = %p \n",pdc_regs->PDC_PTSR,ssc_regs->SSC_SR);        ssc_regs->SSC_IER = 0x1 << 6; // enable endrx interrupt//printk("ssc_imr = %p \n",ssc_regs->SSC_IMR);}//int a9200_rx_dmabufflag=0;void a9200_rx_dmabuf(void){        // if already running then nothing to do//      if(a9200_rx_dmabufflag ==0)//      {//       printk("a9200_rx_dmabuf \n");//       a9200_rx_dmabufflag = 1;//      }        if(a9200_rxdmaing)                return;  //printk("a9200_rxend = %d \n",a9200_rxend);        // set dma transfer count        spin_lock(&rx_count_lock);        a9200_rxdmacount = a9200_rxend - a9200_rxstart;        a9200_rxdmacount = (a9200_rxdmacount > DMASIZE) ? DMASIZE : a9200_rxdmacount;        if(a9200_rxdmacount > 0)        {                a9200_rx_dmarun();        }        else        {                ssc_regs->SSC_IDR = 0x1 << 6;                ssc_regs->SSC_CR = AT91C_SSC_RXDIS;                a9200_rxbusy = 0;                wake_up_interruptible(&rx_buffer_end);        }  spin_unlock(&rx_count_lock);}//int rxflag=0;//int txflag=0;void a9200_dma_isr(int irq,void *dev_id,struct pt_regs *regs){  	// clear dma interrupt  aic_regs->AIC_ICCR = 0x1 << AT91C_ID_SSC1; // clear interrupt    if((ssc_regs->SSC_SR & (0x1 << 6)) && (ssc_regs->SSC_IMR & (0x1 << 6)) )  {  //if(rxflag==0) // {//	  printk("rx interrupt ... \n");//	  rxflag=1;//	}	ssc_regs->SSC_IDR = 0x1 << 6; // disbale endrx interrupt	a9200_rxdmaing = 0;	a9200_rxstart += a9200_rxdmacount;		//printk("a9200_rxstart = %d \n",a9200_rxstart);  spin_lock(&rx_count_lock);	a9200_rxdmacount = 0;	spin_unlock(&rx_count_lock);	a9200_rx_dmabuf();  }

⌨️ 快捷键说明

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