📄 i2s_jz4740.c
字号:
record_filler = record_fill_1x8_u; __i2s_set_oss_sample_size(8); __i2s_set_iss_sample_size(16); dma_src_size(AUDIO_READ_DMA, 16); dma_dest_size(AUDIO_READ_DMA, 32); dma_src_size(AUDIO_WRITE_DMA, 32); dma_dest_size(AUDIO_WRITE_DMA, 8); dma_block_size(AUDIO_WRITE_DMA,8); dma_block_size(AUDIO_READ_DMA,4); __i2s_set_transmit_trigger(16 - 4); __i2s_set_receive_trigger(2); __aic_enable_mono2stereo(); break; case TYPE(AFMT_U8, 2): jz_audio_b = 8; replay_filler = replay_fill_all; record_filler = record_fill_2x8_u; dma_src_size(AUDIO_READ_DMA, 16); dma_dest_size(AUDIO_READ_DMA, 32); dma_src_size(AUDIO_WRITE_DMA, 32); dma_dest_size(AUDIO_WRITE_DMA, 8); dma_block_size(AUDIO_WRITE_DMA,8); dma_block_size(AUDIO_READ_DMA,4); __i2s_set_oss_sample_size(8); __i2s_set_iss_sample_size(16); __i2s_set_transmit_trigger(16 - 4); __i2s_set_receive_trigger(2); __aic_disable_mono2stereo(); break; case TYPE(AFMT_S16_LE, 1): jz_audio_b = 16; replay_filler = replay_fill_all; record_filler = record_fill_1x16_s; __i2s_set_oss_sample_size(16); __i2s_set_iss_sample_size(16); dma_src_size(AUDIO_READ_DMA, 16); dma_dest_size(AUDIO_READ_DMA, 32); dma_src_size(AUDIO_WRITE_DMA, 32); dma_dest_size(AUDIO_WRITE_DMA, 16); dma_block_size(AUDIO_WRITE_DMA,16); dma_block_size(AUDIO_READ_DMA,4); __i2s_set_transmit_trigger(16 - 8); __i2s_set_receive_trigger(2); printf("-----------------------%d\n",IS_WRITE_PCM); if(IS_WRITE_PCM) __aic_enable_mono2stereo(); break; case TYPE(AFMT_S16_LE, 2): jz_audio_b = 16; replay_filler = replay_fill_all; record_filler = record_fill_all; __i2s_set_oss_sample_size(16); __i2s_set_iss_sample_size(16); dma_src_size(AUDIO_READ_DMA, 16); dma_dest_size(AUDIO_READ_DMA, 32); dma_src_size(AUDIO_WRITE_DMA, 32); dma_dest_size(AUDIO_WRITE_DMA, 16); dma_block_size(AUDIO_READ_DMA,16); dma_block_size(AUDIO_WRITE_DMA,16); __i2s_set_transmit_trigger(16 - 4); __i2s_set_receive_trigger(4); __aic_disable_mono2stereo(); break; }}static void set_volume_reg(int val){ long tmp_val; //set REG_ICDC_CDCCR1 if(val == 0) { new_mute=1; if(new_mute!= old_mute) flag_CDCCR=1; }else { new_mute=0; if(new_mute!= old_mute) flag_CDCCR=1; } //set REG_ICDC_CDCCR2 if(val >= 0 && val <= 16 ) { new_hw_vol=0; if(new_hw_vol!= old_hw_vol) flag_CDCCR=1; } else if(val >= 17 && val <= 20 ) { new_hw_vol=1; if(new_hw_vol!= old_hw_vol) flag_CDCCR=1; } else if(val >= 21 && val <= 25 ) { new_hw_vol=2; if(new_hw_vol!= old_hw_vol) flag_CDCCR=1; } else { new_hw_vol=3; if(new_hw_vol!= old_hw_vol) flag_CDCCR=1; }}int pcm_ioctl(unsigned int cmd, unsigned long arg){ long val; val=arg; switch (cmd) { case PCM_DATA_FINISH: if(in_busy_queue.count == 0) return 1; return 0; case PCM_SET_SAMPLE_RATE: jz_audio_set_speed(arg); break; case PCM_SET_CHANNEL: jz_audio_set_channels(arg); break; case PCM_SET_FORMAT: jz_audio_set_format(arg); break; case PCM_SET_VOL: if (arg > 100) arg = 100; if(!IS_WRITE_PCM){ i2s_codec_set_mic(arg); }else{ i2s_codec_set_volume(arg); } break; case PCM_SET_MUTE: i2s_codec_set_mute(arg); break; case PCM_SET_HP_VOL: if(val < 0) val = 0; if(val > 31) val = 31; if (val >= 0 && val <= 31) { jz_audio_factor = Factor_table[val];// printf("jz_audio_factor:%d %d\n",jz_audio_factor,val); jz_audio_volume = val; set_volume_reg(val);// printf("REG_ICDC_CDCCR1 : 0x%08x\n",REG_ICDC_CDCCR1);// printf("REG_ICDC_CDCCR2 : 0x%08x\n",REG_ICDC_CDCCR2); } break; case PCM_SET_PAUSE: pause_flag=1; __aic_disable_replay(); break; case PCM_SET_PLAY: pause_flag=0; //pcm_start(); __aic_enable_replay(); break; case PCM_SET_REPLAY: //WAIT_POWERON(); jz_audio_reset(); if(IS_WRITE_PCM == 0) { if(HP_on_off_flag == 1) { HP_on_off_flag = 0; HP_turn_off(); } IS_WRITE_PCM=1; first_record_call = 0; in_codec_app1(); } break; case PCM_SET_RECORD: //WAIT_POWERON(); jz_audio_reset(); IS_WRITE_PCM=0; first_record_call = 1; if(HP_on_off_flag == 1) { HP_on_off_flag = 0; HP_turn_off(); } in_codec_app12(); break; case PCM_SET_RECORD_FM: //WAIT_POWERON();// jz_audio_reset(); IS_WRITE_PCM=0; first_record_call = 1; in_codec_app9(); break; case PCM_RESET: //dma_stop(AUDIO_WRITE_DMA); //out_full_queue.count = 0; //out_busy_queue.count = 0; //out_empty_queue.count = QUEUE_MAX; //__aic_flush_fifo(); WAIT_POWERON(); i2s_codec_set_mute(0); i2s_codec_reset(); break; case PCM_REINIT: //dma_stop(AUDIO_WRITE_DMA); out_full_queue.count = 0; out_busy_queue.count = 0; out_empty_queue.count = QUEUE_MAX; //__aic_flush_fifo(); if(pause_flag) { pause_flag=0; __aic_flush_fifo(); __aic_enable_replay(); jz_audio_reset_buffer(); } i2s_codec_reset(); break; case PCM_GET_HP_VOL: return jz_audio_volume; case PCM_GET_VOL: return i2s_codec_get_volume(); case PCM_GET_SPACE: { int dnum = elements_in_queue(&out_empty_queue); //printf("dnum = %d %d\n",dnum,dma_get_count(AUDIO_WRITE_DMA)); if (dnum > 0) return (dnum) * PAGE_SIZE - dma_get_count(AUDIO_WRITE_DMA); else return 0; } case PCM_SET_VOLFUNCTION: set_audio_volume((void *)arg); break; case PCM_GET_SAMPLE_MAX: return ((32767 * jz_audio_factor) >> 8); break; case PCM_POWER_OFF: jz_codec_poweroff(0); break; case PCM_POWER_ON: jz_codec_poweron(0); break; default: printf("pcm_ioctl:Unsupported I/O command: %08x\n", cmd); return -1; } return 0;}int pcm_can_write(void){ if (elements_in_queue(&out_empty_queue) > 0) return 1; return 0;}int pcm_can_read(void){ if (elements_in_queue(&in_full_queue) > 0) return 1; return 0;}int pcm_read(char *buffer, int count){ int id, ret = 0, left_count, copy_count, cnt = 0,ps; U8 err; // printf("buffer:0x%x,count = 0x%x\r\n",buffer,count); if (count <= 0) return -1; if(jz_audio_format==AFMT_U8) { ps=PAGE_SIZE/2; } else{ ps=PAGE_SIZE; } if (count < ps) { copy_count = count;//*16 / (jz_audio_channels * jz_audio_format); } else copy_count = ps; //printf("copy_count = 0x%x,PAGE_SIZE = 0x%x\r\n",copy_count,PAGE_SIZE); left_count = count; if (first_record_call) { first_record_call = 0; if ((id = get_buffer_id(&in_empty_queue)) >= 0) { put_buffer_id(&in_busy_queue, id); in_dma_buf_data_count[id] = copy_count;//(jz_audio_format / 8); //in_dma_buf_data_count[id] = copy_count * (jz_audio_format / 8); __i2s_enable_receive_dma(); __i2s_enable_record(); dma_start(AUDIO_READ_DMA, PHYADDR(AIC_DR), in_dma_pbuf[id], in_dma_buf_data_count[id]); OSSemPend(rx_sem, 0, &err); } } while (left_count > 0) { if (elements_in_queue(&in_full_queue) <= 0) OSSemPend(rx_sem, 0, &err); if ((id = get_buffer_id(&in_full_queue)) >= 0) { /* * FIXME: maybe the buffer is too small. */ cnt = record_filler((unsigned long)buffer+ret, copy_count, id); //printf("ret = 0x%x,copy_count = 0x%x\r\n",ret,copy_count); put_buffer_id(&in_empty_queue, id); } if (elements_in_queue(&in_busy_queue) == 0) { if ((id = get_buffer_id(&in_empty_queue)) >= 0) { put_buffer_id(&in_busy_queue, id); in_dma_buf_data_count[id] = copy_count; //(jz_audio_format / 8); //in_dma_buf_data_count[id] = copy_count * (jz_audio_format / 8); __i2s_enable_receive_dma(); __i2s_enable_record(); dma_start(AUDIO_READ_DMA, PHYADDR(AIC_DR), in_dma_pbuf[id], in_dma_buf_data_count[id]); } } if (ret + cnt > count) cnt = count - ret; ret += cnt; left_count -= cnt; } return ret;}static unsigned int Page_Size = PAGE_SIZE;void pcm_set_write_pagesize(unsigned int pagesize){ if(pagesize == 0) Page_Size = PAGE_SIZE; else Page_Size = pagesize;}int pcm_write(char *buffer, int count){ int id, ret = 0, left_count, copy_count;// printf("pcm_write %x %x\n",count, PAGE_SIZE); if(count > Page_Size) { left_count = count / Page_Size * Page_Size; while (left_count > 0) { if (elements_in_queue(&out_empty_queue) == 0) return ret; if ((id = get_buffer_id(&out_empty_queue)) >= 0) { replay_filler( (unsigned long)buffer + ret, Page_Size, id); put_buffer_id(&out_full_queue, id); } left_count -= Page_Size; ret += Page_Size; if(elements_in_queue(&out_busy_queue) == 0) { if ((id = get_buffer_id(&out_full_queue)) >= 0) { put_buffer_id(&out_busy_queue, id); __i2s_enable_transmit_dma(); __i2s_enable_replay(); dma_start(AUDIO_WRITE_DMA, out_dma_pbuf[id], PHYADDR(AIC_DR), out_dma_buf_data_count[id]); } } } }else { if (elements_in_queue(&out_empty_queue) == 0) return ret; //for dma data translate copy_count = count / 32 * 32; // 32 size align if(copy_count > 0) { // printf("copy_cnt:%d count:%d unsigned long:%d %d %d\n",copy_count,count,sizeof(unsigned long),sizeof(signed long),sizeof(char)); if ((id = get_buffer_id(&out_empty_queue)) >= 0) { replay_filler( (unsigned long)buffer, copy_count, id); put_buffer_id(&out_full_queue, id); } if(elements_in_queue(&out_busy_queue) == 0) { if ((id = get_buffer_id(&out_full_queue)) >= 0) { put_buffer_id(&out_busy_queue, id); __i2s_enable_transmit_dma(); __i2s_enable_replay(); dma_start(AUDIO_WRITE_DMA, out_dma_pbuf[id], PHYADDR(AIC_DR), out_dma_buf_data_count[id]); } } ret = copy_count; }else ret = 0; } return ret;}static unsigned char dma_pool[PAGE_SIZE * QUEUE_MAX ] __attribute__((aligned(32)));extern void in_codec_app1(void);extern void in_codec_app11(void);int pcm_init(){ int i; unsigned char *p = dma_pool; p = (unsigned char *)KSEG1ADDR((unsigned int )p); set_audio_volume(0); jz_i2s_initHw(); if (jz_i2s_codec_init() < 0) return -1; tx_sem = OSSemCreate(0); rx_sem = OSSemCreate(0); //pre_tx_sem = OSSemCreate(0); //pause_sem = OSSemCreate(0); /* for(i=0;i < 64;i++) { save_last_samples[i].left = 0; save_last_samples[i].right = 0; } */ dma_request(AUDIO_READ_DMA, jz_i2s_record_dma_irq, 0, DMAC_DCCSR_DAM|DMAC_DCCSR_RDIL_IGN, DMAC_DRSR_RS_AICIN); dma_request(AUDIO_WRITE_DMA, jz_i2s_replay_dma_irq, 0, DMAC_DCCSR_SAM | DMAC_DCCSR_RDIL_IGN | DMAC_DCMD_DWDH_16, DMAC_DRSR_RS_AICOUT); //DMAC_DRSR_RS_AUTO); jz_audio_reset(); /* Aligned in PAGE_SIZE */ for (i = 0; i < QUEUE_MAX; i++) { out_dma_buf[i] = (unsigned long)p; out_dma_pbuf[i] = PHYADDR((unsigned int)out_dma_buf[i]); in_dma_buf[i] = (unsigned long)p; //p += PAGE_SIZE*16; in_dma_pbuf[i] = PHYADDR((unsigned int)in_dma_buf[i]); p += PAGE_SIZE; } REG_AIC_SR = 0x00000008; REG_AIC_FR |= 0x50; __i2s_enable(); new_hw_vol=0; old_hw_vol=0; pcm_ioctl(PCM_SET_VOL,0); /* 0-3 */ new_mute=0; old_mute=0; pcm_ioctl(PCM_SET_MUTE,1); /* 0-1 */ pcm_ioctl(PCM_SET_HP_VOL,10); /* 0-32 */ pcm_ioctl(PCM_SET_REPLAY,0);#if 0 printf("REG_GPIO_PXFUN(3):0x%08x\n",REG_GPIO_PXFUN(3)); printf("REG_GPIO_PXSEL(3):0x%08x\n",REG_GPIO_PXSEL(3)); printf("REG_CPM_SCR:0x%08x\n",REG_CPM_SCR); printf("REG_CPM_CPCCR:0x%08x\n",REG_CPM_CPCCR); printf("REG_CPM_I2SCDR:0x%08x\n",REG_CPM_I2SCDR); printf("REG_AIC_FR:0x%08x\n",REG_AIC_FR); printf("REG_AIC_CR:0x%08x\n",REG_AIC_CR); printf("REG_AIC_SR:0x%08x\n",REG_AIC_SR); printf("REG_AIC_I2SCR:0x%08x\n",REG_AIC_I2SCR); printf("REG_AIC_I2SSR:0x%08x\n",REG_AIC_I2SSR); printf("REG_AIC_I2SDIV:0x%08x\n",REG_AIC_I2SDIV); printf("REG_ICDC_CDCCR1:0x%08x\n",REG_ICDC_CDCCR1); printf("REG_ICDC_CDCCR2:0x%08x\n",REG_ICDC_CDCCR2);#endif if(jz_codepower_sem == NULL) jz_codepower_sem = OSSemCreate(1); jz_codec_poweroff(0); return 0;}static void code_reset_thread(void *p){ printf("+++++++++++++code_reset_thread = %x \n",code_power); REG_ICDC_CDCCR1 = 0x001b2303; //reset OSTimeDly(1); REG_ICDC_CDCCR1 = 0x001b2302; OSTimeDly(1); REG_ICDC_CDCCR2 = 0x00000800; REG_ICDC_CDCCR1 = 0x001f2102; OSTimeDly(55); REG_ICDC_CDCCR1 = 0x00033302; REG_ICDC_CDCCR1 = 0x14033302; OSTimeDly(55 * 3); REG_AIC_DR = 0x1ffff; REG_AIC_DR = 0x1ffff; printf("----------------code_reset_thread = %x \n",code_power); REG_ICDC_CDCCR2 = save_REG_ICDC_CDCCR2; REG_ICDC_CDCCR1 = save_REG_ICDC_CDCCR1; i2s_codec_set_volume(old_hw_vol); i2s_codec_set_mute(1); code_power = 0; OSTaskDel(CODE_RESET_THREAD_PRIO);}void jz_codec_poweron(int d){ #if 0 OP_CODEPOWER_LOCK(); power_count++; WAIT_POWERON(); printf("++++++++++++++++%s\n",__FUNCTION__); if(power_count > 1) { OP_CODEPOWER_UNLOCK(); return; } code_power = 1; OSTaskCreateExt(code_reset_thread, (void *)0, (void *)&code_reset_buf[CODE_RESET_BUFSIZE - 1], CODE_RESET_THREAD_PRIO,CODE_RESET_THREAD_PRIO, &code_reset_buf[0],CODE_RESET_BUFSIZE,(void*)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); while((code_power) && d) OSTimeDly(10); OP_CODEPOWER_UNLOCK(); printf("--------------------%s\n",__FUNCTION__); #endif}void jz_codec_poweroff(int d){ i2s_codec_set_mute(0); #if 0 OP_CODEPOWER_LOCK(); power_count--; if(power_count <= 0) power_count = 0; else { OP_CODEPOWER_UNLOCK(); return; } printf("++++++++++++++++%s\n",__FUNCTION__); WAIT_POWERON(); REG_AIC_DR = 1; REG_AIC_DR = 1; OSTimeDly(1); save_REG_ICDC_CDCCR1 = REG_ICDC_CDCCR1; save_REG_ICDC_CDCCR2 = REG_ICDC_CDCCR2; REG_ICDC_CDCCR1 = 0x001b2102; REG_ICDC_CDCCR2 = 0x10020084; printf("--------------------%s\n",__FUNCTION__); OP_CODEPOWER_UNLOCK(); #endif}#if (DM==1)int codec_poweron(void){}int codec_poweroff(void){}int codec_preconvert(void){// __i2s_set_transmit_trigger(2);#if 0 u32 ret; unsigned long flags; flags = spin_lock_irqsave();// ret = out_busy_queue.count; ret = (*(volatile u32*)0xb0020014 >>8) & 0x3f; spin_unlock_irqrestore(flags); // while((((*(volatile u32*)0xb0020014) >> 8) & 0x3f) < 0x16); // printf("tfl = %d\r\n",(((*(volatile u32*)0xb0020014) >> 8) & 0x3f)); // printf("ret = %d",ret); if( ret > 0x14)// if(ret > 0)#endif return 1; // return 0;}int codec_convert(void){// preconvert_control=0;// __i2s_set_transmit_trigger(16 - 2);}void mng_init_codec(void){ struct dm_jz4740_t codec_dm; codec_dm.name = "Codec driver"; codec_dm.init = pcm_init; codec_dm.poweron = codec_poweron; codec_dm.poweroff = codec_poweroff; codec_dm.convert = codec_convert; codec_dm.preconvert = codec_preconvert; dm_register(0,&codec_dm);}#endifvoid jz_memmove_handler(unsigned int arg){ REG_DMAC_DCCSR(arg) = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -