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

📄 jadei2s.c

📁 Audio codec--TLV320AIC31 驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
                else if(use_i2s==2)
                        {
				for( i=0; i<count; i++ )
                        transmitData( 2 , &script_wm8976_m[i][1] , script_wm8976_m[i][0]/2 );
                        debug("now record init mode\n");
                }
                else if (use_i2s==3)
                        {       
                     		printk("now full-duplex init mode\n");  
				for( i=0; i<count; i++ )					                           
					transmitData( 2 , &script_wm8976[i][1] , script_wm8976[i][0]/2 );
                        }
                else 
                	{
				for( i=0; i<count; i++ )
		   		transmitData( 2 , &script_wm8976_p[i][1] , script_wm8976_m[i][0]/2 );	
                	}

                mdelay(1);
        }
        dele_i2c();

        printk("SOUND: wm8976%d\n",use);
        return 0;
}


static int mode_init( unsigned int mode)
{
	int i;
	unsigned char	aic23_for_line[][3]={
			{0x34,0x08,0x12},
			};

	unsigned char 	aic23_for_mic[][3]={
			 {0x34,0x08,0x15},
			};	

       init_i2c();
        
	if (mode==1)
	{
		debug(" we have a line input\n");	
		for (i=0;i<2;i++)
			transmitData( 2 , &aic23_for_line[i][1], 0x34/2 );
	}
	else
	{
		debug("we have a mic input\n");
		for (i=0;i<2;i++)
			transmitData( 2 , &aic23_for_mic[i][1], 0x34/2 );
	}
        
        mdelay(2);

	return 0;
}

static irqreturn_t i2s_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
        u32 st;
	unsigned int gpio_org;

  	
	
	gpio_org=readl(GPIO5_DATA);
	if (gpio_org &0x01) mode=1;
	else mode=0;
	
        
	gpio_org=readl(GPIO5_IE);	
	
	gpio_org &=0xfe;
	writel(gpio_org, GPIO5_IE);
        
	st = readl(GPIO5_RIS);
        if(st & 0x01)
        {        
		writel(st, GPIO5_IC);
	}
	else
       	{
		printk(" this is not i2s interrupt\n");
	 	return IRQ_HANDLED;	
	}
       
	mode_init(mode);
	
        
 	gpio_org=readl(GPIO5_IE);
        gpio_org |=0x1;
  	writel(gpio_org, GPIO5_IE);
	
	return IRQ_HANDLED;
}

int init_GPIO5() 
{	 
    unsigned int gpio_org;
     gpio5_base = ioremap(0x2002c000, SZ_4K);
     if(gpio5_base==NULL){
                printk("<1> remap GPIO5 error\n");
                return -ENODEV;
       	 }

        //-----Configure the GPIO 5_0 lines to detect tlv320aic23b intr -----

	 gpio_org = readl(GPIO5_DIR) &(0xfffe);
	writel(gpio_org, GPIO5_DIR);
        
	gpio_org = readl(GPIO5_IC) &(0xfffe);
	writel(0x01, GPIO5_IC);
        
	gpio_org = readl(GPIO5_IS) &(0xfffe);
	writel(gpio_org, GPIO5_IS);/* 0=edge triggle ,1=level triggle*/
        
	gpio_org = readl(GPIO5_IBE) &(0xfffe);
	 gpio_org |= 0x1;
	writel(gpio_org, GPIO5_IBE);	/*I want to use both edge triggle */
        //writel(0x01, GPIO_IEV);
        
	
	gpio_org = readl(GPIO5_IE) &(0xfffe);
	gpio_org |=0x1;
	writel(gpio_org , GPIO5_IE);
	return 0;
}

int init_AIC23()
{
	int i , count;

	printk("enter init_AIC23\n");

	if(use_i2s==1)
		count=sizeof(script_aic23_l) / sizeof(script_aic23_l[0]);
		else if (use_i2s==2) count=sizeof(script_aic23_r) / sizeof(script_aic23_r[0]);
	  	 else  count=sizeof(script_aic23_q) / sizeof(script_aic23_q[0]);

	PinMask( 1 , 1 );	// enable i2c pin mask
	init_i2c();	
	debug("after i2c_init\n");
	
	if(use_i2s==1){
		for( i=0; i<count; i++ )	
			transmitData( 2 , &script_aic23_l[i][1] , script_aic23_l[i][0]/2 );
			debug("init line  in mode\n");
		}
	else if(use_i2s==2)
			{
			for( i=0; i<count; i++ )	
			transmitData( 2 , &script_aic23_r[i][1] , script_aic23_r[i][0]/2 );
			debug("now init  record mode\n");
		}
	else  
			{
			printk("now init FULL -DUPLEX  mode\n");
			for( i=0; i<count; i++ )	
		 		transmitData( 2 , &script_aic23_q[i][1] , script_aic23_q[i][0]/2 );						
			}
			
		mdelay(1);
	
	printk("SOUND: AIC23%d\n",use);
	return 0;
}

int init_i2sbase()
{
	IIS_BASE = ioremap(IIS_BASE_HW, 0x1000);
	if(IIS_BASE == 0){
		printk("SOUND: i2s remap failed\n");
		return -1;
	}

	*IIS_CPSR=0x004;   //48k
	*IIS_IMSC=0x000f;
	*IIS_DMACR=0x03;
	*IIS_CR1=0x0002;
	*IIS_CR0=0x033f; 

	return 0;
}



static void
i2s_dma_done(int a, int b, void *data)
{
	if(comp_record) complete(comp_record);

	if(b){
		printk("<1>i2s dma error:%x, %x\n", a, b);
	}
	
}

int init_record_dma(){
    ch_r= ver_request_dma(0, "iis_r", 11, 12);

	if(ch_r < 0){
		printk("<1> alloc i2s dma error\n");
		return ch_r;
	}else{
		printk("<1> i2s  record dma chan: %d\n", ch_r);
	}

	memset(&pa_r, 0, sizeof (pa_r));


 	  pa_r.SWidth = DMAC_TSIZE_HALFWORD;

	pa_r.DWidth = DMAC_TSIZE_WORD;
        pa_r.SBsize = 0x4;
        pa_r.DBsize = 0x1;
        pa_r.FlowCntrl = FLOW_PER_MEM_DMAC;
        pa_r.SIncr = 0;
        pa_r.DIncr = 1;

	if (ver_set_dma(ch_r, &pa_r) != 0) {
		printk("<1>i2s read:set dma fail:\n");
		return -1;
	}

	return 0;
}

int start_record_dma()
{
	i2s_dma_loop(ch_r, i2s_dma_done, NULL);
	
	Record_PhyAddr = i2sbufbaseaddr();
	if(!Record_PhyAddr){
		debug("SOUND: get Record_PhyAddr fail\n");
		return -1;
	}
	debug("Record_PhyAddr = %x \n",Record_PhyAddr);
	
	Record_MemAddr = (int)ioremap(Record_PhyAddr, RECBUFSIZE*4);
	if(!Record_MemAddr){
		debug("SOUND: get Record_MemAddr fail\n");
		return -1;
	}
	debug("Record_MemAddr = %x \n",Record_MemAddr);

	return 0;
}

int free_record_dma()
{
	return ver_free_dma(ch_r);
}

int free_play_dma()
{
	return ver_free_dma(ch_p);
}


int init_playback_dma(){
	ch_p=ver_request_dma(0, "iis_p", 11, 12);
	if(ch_p < 0){
		debug("<1>i2s playback dma error\n");
		return ch_p;
	}else{
		debug("SOUND: i2s play dma chan: %d\n", ch_p);
	}

	memset(&pa_p, 0, sizeof(pa_p));

	pa_p.SWidth = DMAC_TSIZE_WORD;
	pa_p.DWidth = DMAC_TSIZE_HALFWORD;
 
	pa_p.SBsize = 0x4;
	 pa_p.DBsize = 0x1;
        pa_p.FlowCntrl = FLOW_MEM_PER_DMAC;
        pa_p.SIncr = 1;
        pa_p.DIncr = 0;

	if (ver_set_dma(ch_p, &pa_p) != 0) {
		debug("<1>i2s write:set  play dma fail:\n");
		return -1;
	}else{
		printk("SOUND: set dma_play OK\n");
		return 0;
	}
}


static void
iisplay_dma_done(int a, int b, void *data)
{
	if(b)
		debug("<1>iis playback dma error:%x, %x\n", a, b);
	if(data)
		complete(data);
}

int start_play_dma(char *buf, int size){

	DECLARE_COMPLETION(comp_play);
	
	pa_p.sg_len = 0;
	pa_p.tsize = size;
	pa_p.sbuf = buf;
	pa_p.dbuf = (void *)(0x2003a008);

	pa_p.trans_done = iisplay_dma_done;
	pa_p.done_data = &comp_play;

	if (ver_start_dma(ch_p, &pa_p) != 0) {
		printk("<1>sound:start dma fail:\n");
		return -1;
	}
	
	wait_for_completion(&comp_play);

	return 0;
}


static int i2s_setFmt( int fmt) /* set the sample bit  16*/
{
	int tmp;

	tmp=fmt;
	if (tmp !=16)
		 return -ENOTTY;
      else
		return 0;
	
}

static int i2s_setChannel(int ch) /*set channel 1=mono, 2=stereo*/
{
	return 0;
}


int i2s_get_vol(){
	unsigned  short ret_vol;

	// the vol for play is (+6db to -73 db),the default is 0db	
	// the vol for record is ( +12db to -34.5 db),the default vol is 0db,each step is 1.5db
	//re_vol = org_vol_r - 0x17;
	//pl_vol = org_vol_p- 0x79;
	ret_vol = org_vol_r<<8 | org_vol_p;

	debug( "the vol for play is +6 to -73 , each step is 1db, vol for record is 8 to -23 ,each step is 1.5db \n");
	debug(" the vol for record is %x, the vol for play is %x\n",org_vol_r,org_vol_p);
	return ret_vol;
}

static int  i2s_aic23_setSpeed(unsigned  long  samplerate)
{
	int  sap_rat,tmp_scr,tmp_cpsr;
 	unsigned char aic23_for_speed[3]={0x34,0x10,0x00};	

	tmp_cpsr=(*IIS_CPSR);
        tmp_scr =(*IIS_CR0)& 0x00ff;
	sap_rat=(unsigned int )samplerate;
	 printk(" the need samplate is %d\n ", sap_rat);

	if (abs(samplerate-96)<=4) sap_rat=96;
	else if (abs(samplerate-48)<=4) sap_rat=48;
	else if (abs(samplerate-32)<=4) sap_rat=32;
	else if (abs(samplerate-8)<=4) sap_rat=8;
	else 
	{	
	   printk("without matched sample-rate\n");
	return -1;
	}
	
	printk(" with the cooperate rate %d\n ", sap_rat);

 	switch (sap_rat)
 	{
		case 96:
           		(*IIS_CR0) = tmp_scr | 0x0300;
	   		(*IIS_CPSR) = 0x00002;
	  	 	aic23_for_speed[2]= 0x0e;
			break;
		case 48:
			(*IIS_CR0) = tmp_scr | 0x0300;
                        (*IIS_CPSR) = 0x00004;
			aic23_for_speed[2]=0x00;   
			break;
		case 32:
			(*IIS_CR0) = tmp_scr | 0x0500;
                        (*IIS_CPSR) = 0x0004;
			aic23_for_speed[2]=0x0c;
			 break;
		case 8:
			(*IIS_CR0) = tmp_scr | 0x0500;
                        (*IIS_CPSR) = 0x00010;
			aic23_for_speed[2]=0x5;
		 	break;
		default:
			(*IIS_CR0) = tmp_scr | 0x0500;
                        (*IIS_CPSR) = 0x0004;
                        aic23_for_speed[2]=0x06;
                        break;
	}
	
	init_i2c();
	transmitData( 2 , &aic23_for_speed[1], 0x34/2 );
	debug(" the cro is ---->  %x\n", (*IIS_CR0));
	
	mdelay(1);
	
	dele_i2c();
 	return 1;


};


static int i2s_wm8976_setSpeed( unsigned  long  samplerate)
{
 	int  sap_rat,tmp_scr,tmp_cpsr;
 	unsigned char wm8976_for_speed[]={0x34,0x0e,0x00};	

	tmp_cpsr=(*IIS_CPSR);
        tmp_scr =(*IIS_CR0)& 0x00ff;
	sap_rat=(unsigned int )samplerate;
	 printk(" the need samplate is %d\n ", sap_rat);

	if (abs(samplerate-48)<=4) sap_rat=48;
	else if (abs(samplerate-32)<=4) sap_rat=32;
	else if (abs(samplerate-24)<=4) sap_rat=24;
	else if (abs(samplerate-16)<=4) sap_rat=16;
	else if (abs(samplerate-8)<=4) sap_rat=8;
	else 
	{	
	   printk("without matched sample-rate\n");
	return -1;
	}
	
	printk(" with the cooperate rate %d\n ", sap_rat);

 	switch (sap_rat)
 	{
		case 48:
           		(*IIS_CR0) = tmp_scr | 0x0300;
	   		(*IIS_CPSR) = 0x00004;
	  	 	wm8976_for_speed[2]= 0x00;
			break;
		case 32:
          		(*IIS_CR0) = tmp_scr | 0x0500;
          		(*IIS_CPSR) = 0x0004;
			wm8976_for_speed[2]=0x02;   
			break;
		case 24:
			(*IIS_CR0) = tmp_scr | 0x0300;
        		(*IIS_CPSR) = 0x0008;
			wm8976_for_speed[2]=0x04;
			 break;
		case 16:
			(*IIS_CR0) = tmp_scr | 0x0500;
          		(*IIS_CPSR) = 0x00008;
			wm8976_for_speed[2]=0x5;
		 	break;
		case 12:
			(*IIS_CR0) = tmp_scr | 0x0300;
          		(*IIS_CPSR) = 0x00010;	
			wm8976_for_speed[2]=0x08;
			 break;
		default:
			(*IIS_CR0) = tmp_scr | 0x0500;
        		(*IIS_CPSR) = 0x00010;
	 		wm8976_for_speed[2]=0x0a;
	}
	
	init_i2c();
	transmitData( 2 , &wm8976_for_speed[1], 0x34/2 );
	
	mdelay(1);
	
	dele_i2c();
 	return 1;

}

static int i2s_aic23_SetReVol(unsigned int add_delvol){
	 unsigned char aic23_for_vol[3]={0x34,0x01,0x17};	
       	unsigned char value_vol;
	unsigned char add_del;
    
	add_del=(unsigned char)add_delvol;

		if  (add_del=='+') {
			if (volR_add > 0){ 
				org_vol_r++;
				volR_add--;
				volR_del++;
				}
			else{
				printk("now is the max vol\n");
				return -1;
			}
		}
 		else
		{	
			if  (add_del=='-') {
                		if (volR_del>0x0) {
						org_vol_r--;
						volR_del--;
						volR_add++;
					}
                		else{
                        		printk("now is the smallest vol\n");
                        		return -1;
                		}
		}
	}
	
	value_vol = org_vol_r;
	
	aic23_for_vol[2]=value_vol;        
	debug(" the Re_vol value is %x\n",aic23_for_vol[2]);	
	init_i2c();
        transmitData(2,&aic23_for_vol[1], 0x34/2);
        mdelay(1);

        dele_i2c();
        return 1;
	
}

static int i2s_aic23_SetPlVol(unsigned int add_delvol){
	unsigned char value_vol;
        unsigned char aic23_for_vol[]={0x34,0x05,0x79};
	unsigned char add_del;
    
        add_del=(unsigned char)add_delvol;
		
        if  (add_del=='+') {

⌨️ 快捷键说明

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