📄 jadei2s.c
字号:
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 + -