📄 em8xxx_alsa.c
字号:
RMuint32 audio_decoder = EMHWLIB_MODULE(AudioDecoder,audio_decoder_index); RMuint32 AudioBtsThreshold=AUDIO_BTS_THRESHOLD; if(!chip->STCStarted){ chip->STCStarted = TRUE; /* To avoid the DAC to play non-valid data we start/stop the stc in the same time we do a Pause/Play on the AudioDecoder */ EM8XXXSNDGP(pE, audio_decoder, RMAudioDecoderPropertyID_State, &state, sizeof(state)); if(state!=AudioDecoder_State_Playing){ EM8XXXSNDSP(pE,audio_decoder, RMAudioDecoderPropertyID_AudioBtsThreshold, &AudioBtsThreshold,sizeof(RMuint32)); command = AudioDecoder_Command_Play; EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_Command, &command, sizeof(command)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while sending play command to audio decoder! \n")); } kc_udelay(100000); } // Run STC speed.nominator = 1; speed.denominator = 1; EM8XXXSNDSP(pE, EMHWLIB_MODULE(STC,audio_decoder_index), RMSTCPropertyID_Speed, &speed, sizeof(speed)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while setting STC speed! \n")); return err; } EM8XXXSNDSP(pE, EMHWLIB_MODULE(STC,audio_decoder_index), RMSTCPropertyID_Play,NULL,0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while sending Play command to STC! \n")); return err; } } return RM_OK;}static int em8xxx_pcm_playback_update (em8xxx_t *chip){ snd_pcm_substream_t *substream = chip->playback_substream; snd_pcm_runtime_t *runtime = substream->runtime; /* We send at each interrupt a block which size is equal to period_size. Thus, we have to notify the Alsa Pcm middle layer that the period is elapsed, and it can the update the appl-ptr. */ playback_update_position(chip); if(chip->last_count==frames_to_bytes(runtime,runtime->period_size)) snd_pcm_period_elapsed(substream); return 0;}static int em8xxx_pcm_capture_update (em8xxx_t *chip){ snd_pcm_substream_t *substream = chip->capture_substream; /* We send at each interrupt a block which size is equal to period_size. Thus, we have to notify the Alsa Pcm middle layer that the period is elapsed, and it can the update the appl-ptr. */ capture_update_position(chip); snd_pcm_period_elapsed(substream); return 0;}static int playback_update_position (em8xxx_t *chip){ int last_ptr,size; snd_pcm_substream_t *substream = chip->playback_substream; snd_pcm_runtime_t *runtime = substream->runtime; last_ptr = chip->hw_ptr+bytes_to_frames(runtime,chip->last_count); size = last_ptr - chip->hw_ptr; chip->hw_ptr = last_ptr; chip->transferred += size; if (chip->hw_ptr >= (int)runtime->buffer_size) chip->hw_ptr %= runtime->buffer_size; return 0;}static int capture_update_position (em8xxx_t *chip){ int last_ptr,size; snd_pcm_substream_t *substream = chip->capture_substream; snd_pcm_runtime_t *runtime = substream->runtime; last_ptr = chip->capture_hw_ptr+runtime->period_size; size = last_ptr - chip->capture_hw_ptr; chip->capture_hw_ptr = last_ptr; chip->capture_transferred += size; if (chip->capture_hw_ptr >= (int)runtime->buffer_size) chip->capture_hw_ptr %= runtime->buffer_size; return 0;}static int send_data_callback(void *pE,RMuint32 bus_address){ struct em8xxxprivate * real_pE = (struct em8xxxprivate *) pE; em8xxx_t *chip = Stable+(real_pE-Etable); struct emhwlib_info Info; struct emhwlib_info *pInfo = &Info; struct em8xxx_data param; RMuint32 Info_size; snd_pcm_substream_t * substream = chip->playback_substream; snd_pcm_runtime_t *runtime = substream->runtime; RMstatus err=RM_PENDING; void * context; size_t count; RMDBGLOG((DISABLE,"Send_data_callback\n")); if (chip->running){ if(bus_address!=0) em8xxx_pcm_playback_update(chip); count=frames_to_bytes(runtime,runtime->period_size); chip->last_count=count; pInfo = NULL; Info_size = 0; param.moduleId = EMHWLIB_MODULE(AudioDecoder,audio_decoder_index); param.poolId = MAXDMAPOOL; param.dataSize = count; param.bus_addr = kc_virt_to_bus((unsigned long)runtime->dma_area+frames_to_bytes(runtime,chip->hw_ptr)); kc_flush_cache((void *) (kc_virt_to_phys((unsigned long)runtime->dma_area+frames_to_bytes(runtime,chip->hw_ptr))), count); context =(void *) (((real_pE-Etable) << 16) + param.poolId + 1); // here we are in tasklet mode, so we have to lock for SMP case kc_spin_lock(real_pE->lock); err=EMhwlibSendBuffer(real_pE->pemhwlib, param.moduleId, param.bus_addr, param.dataSize, pInfo, Info_size, context); kc_spin_unlock(real_pE->lock); } return 0;}static RMstatus prepare_data(em8xxx_t *pS){ struct em8xxx_data param; struct em8xxxprivate *pE = Etable + (pS-Stable); RMuint8 *buffer=NULL; RMuint32 timeout = 0; RMstatus err=RM_OK; RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index); struct ReadBufferInfo prop; RMuint32 nb_buf=0; while (1) { timeout=0; buffer=kdmapool_getbuffer(pE->pllad,pS->capture_dmapool_id,&timeout); if (buffer==NULL){ break; } nb_buf++; param.moduleId = audio_capture; param.poolId = pS->capture_dmapool_id; param.bus_addr = kdmapool_get_bus_address(pE->pllad,pS->capture_dmapool_id,buffer, 0); param.dataSize = (1<<SERIALIN_DMA_BUFFER_SIZE_LOG2); prop.address = param.bus_addr; prop.size = param.dataSize; prop.context = (void *) ((pE-Etable) + param.poolId + 1); EM8XXXSNDSP(pE, param.moduleId, RMGenericPropertyID_AddReadBuffer, &prop, sizeof(prop)); buffer=NULL; } printk("prepared %ld buffers \n",nb_buf); return err; }static RMuint32 receive_data_callback(void *pE,RMuint32 ModuleID,RMuint32 mask){ struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE; em8xxx_t *chip = Stable + (real_pE-Etable); RMuint32 status=0; RMDBGLOG((DISABLE,"receive_data_callabck\n")); if (mask & SOFT_IRQ_EVENT_XFER_RECEIVE_READY) { tasklet_schedule(&chip->receive_data_tq); status |= SOFT_IRQ_EVENT_XFER_RECEIVE_READY; } return status;}static void receive_data_interrupt(unsigned long private_data){ em8xxx_t *chip = (em8xxx_t *) private_data; struct em8xxxprivate *pE = Etable +(chip-Stable); RMstatus err; RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index); struct em8xxx_data param; void *context; RMuint8 info[INFO_SIZE]; RMuint32 infoSize = INFO_SIZE; RMuint32 event_mask; RMuint32 i,j; snd_pcm_substream_t * substream = chip->capture_substream; snd_pcm_runtime_t *runtime = substream->runtime; struct ReadBufferInfo prop; /* Clear Event */ RMDBGLOG((ENABLE,"Receive_data_interrupt\n")); event_mask = SOFT_IRQ_EVENT_XFER_RECEIVE_READY; // we are in tasklet mode, we have to lock for SMP kc_spin_lock(pE->lock); EMhwlibSetProperty(pE->pemhwlib,audio_capture,RMGenericPropertyID_ClearEventMask,&event_mask, sizeof(event_mask)); kc_spin_unlock(pE->lock); while(1){ if(chip->capture_pBuf==NULL){ /* Receive buffer */ param.moduleId = audio_capture; param.poolId = chip->capture_dmapool_id; param.infoSize = infoSize; printk("receive buffer \n"); // we are in tasklet mode, so we have to lock for SMP kc_spin_lock(pE->lock); err=EMhwlibReceiveBuffer(pE->pemhwlib, param.moduleId, &(param.bus_addr), &(param.dataSize), info, &(param.infoSize), &context); kc_spin_unlock(pE->lock); if (RMFAILED(err)){ break; } chip->capture_buffer_bus_addr = param.bus_addr; chip->capture_pBuf=kdmapool_get_virt_address(pE->pllad,chip->capture_dmapool_id,chip->capture_buffer_bus_addr, 0); chip->capture_buffer_size = param.dataSize; chip->capture_readable = param.dataSize; chip->i_start=0; } else{ chip->i_start=chip->last_i; } i=chip->i_start; j=chip->j_start; while(j<frames_to_bytes(runtime,runtime->period_size)){ if (i>=chip->capture_buffer_size){ break; } switch(chip->state){ case 0: if(chip->nb_bits_per_sample==8) runtime->dma_area[(j+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i]+128; else runtime->dma_area[(j+1+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i]; j++; break; case 1: if(chip->nb_bits_per_sample==16){ runtime->dma_area[(j-1+frames_to_bytes(runtime,chip->capture_hw_ptr))]=chip->capture_pBuf[i]; j++; } break; default: break; } i++; chip->state++; if(chip->channel_count==1) chip->state %= 6; else chip->state %= 3; } chip->last_i = i; chip->last_j = j; if(j==frames_to_bytes(runtime,runtime->period_size)){ em8xxx_pcm_capture_update(chip); chip->j_start=0; } else{ chip->j_start=chip->last_j; } if (i>=chip->capture_buffer_size){ prop.address = chip->capture_buffer_bus_addr; prop.size = chip->capture_buffer_size; prop.context = (void *) ((pE-Etable) + chip->capture_dmapool_id + 1); printk("add read buffer \n"); //we are in tasklet mode, so we have to lock for SMP kc_spin_lock(pE->lock); EMhwlibSetProperty(pE->pemhwlib, param.moduleId, RMGenericPropertyID_AddReadBuffer, &prop, sizeof(prop)); kc_spin_unlock(pE->lock); chip->capture_pBuf = NULL; } } return;}static int snd_em8xxx_free_ptr(struct em8xxxprivate *pE,RMuint32 ptr){ RMuint32 dramIndex=0xffffffff; RMstatus err; if ((MEM_BASE_dram_controller_0<=ptr)&&(ptr<MEM_BASE_dram_controller_1)) dramIndex=0; if ((MEM_BASE_dram_controller_1<=ptr)&&(ptr<MEM_BASE_dram_controller_1+(512*1024*1024))) dramIndex=1; if (dramIndex<=1) { EM8XXXSNDSP(pE, EMHWLIB_MODULE(MM,dramIndex), RMMMPropertyID_Free, (void *)(&ptr),sizeof(void *)); if(err!=RM_OK) RMDBGLOG((ENABLE,"rm_ptr_free: pointer 0x%08lx cannot be freed\n",ptr)); } else RMDBGLOG((ENABLE,"rm_ptr_free: pointer %p not in a dram controller\n",ptr)); return 0;}static void em8xxx_playback_stop_interrupt(unsigned long private_data){ em8xxx_t *chip = (em8xxx_t *) private_data; struct em8xxxprivate *pE = Etable +(chip-Stable); RMstatus err;/* enum AudioDecoder_Command_type command; */ RMDBGLOG((DISABLE,"em8xxx_playback_stop_interrupt\n")); krua_unregister_sendcomplete_callback(pE);/* command = AudioDecoder_Command_Pause; *//* EM8XXXSNDSP(pE, EMHWLIB_MODULE(AudioDecoder,audio_decoder_index), RMAudioDecoderPropertyID_Command, &command, sizeof(command)); */ chip->transferred=0; chip->STCStarted=FALSE; EM8XXXSNDSP(pE,EMHWLIB_MODULE(STC,audio_decoder_index),RMSTCPropertyID_Stop, NULL,0);}static void em8xxx_capture_stop_interrupt(unsigned long private_data){ em8xxx_t *chip = (em8xxx_t *) private_data; struct em8xxxprivate *pE = Etable +(chip-Stable); enum AudioCapture_Capture_type cmd; RMstatus err; RMDBGLOG((DISABLE,"em8xxx_capture_stop_interrupt\n")); krua_unregister_event_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),receive_data_callback); // Disabling audio capture cmd = AudioCapture_Capture_Off; EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd));}static void em8xxx_playback_setaudio_interrupt(unsigned long private_data){ em8xxx_t *chip = (em8xxx_t *) private_data; snd_pcm_substream_t * substream = chip->playback_substream; snd_pcm_runtime_t *runtime = substream->runtime; RMDBGLOG((DISABLE,"em8xxx_playback_setaudio_interrupt\n")); if (!chip->prepared) { chip->hw_ptr=0; chip->appl_ptr=0; chip->format = AudioDecoder_Codec_PCM; chip->nb_bits_per_sample = runtime->sample_bits; chip->MSBFirst = FALSE; chip->sample_rate = runtime->rate; chip->channel_count = runtime->channels; set_audio_parameters(chip); prepare_audio_decoder(chip); start_stc(chip); } return;}static void em8xxx_capture_setaudio_interrupt(unsigned long private_data){ em8xxx_t *chip = (em8xxx_t *) private_data; snd_pcm_substream_t * substream = chip->capture_substream; snd_pcm_runtime_t *runtime = substream->runtime; RMDBGLOG((DISABLE,"em8xxx_capture_setaudio_interrupt\n")); if (!chip->prepared) { chip->capture_hw_ptr=0; chip->capture_appl_ptr=0; chip->format = AudioDecoder_Codec_PCM; chip->nb_bits_per_sample = runtime->sample_bits; chip->MSBFirst = FALSE; chip->sample_rate = runtime->rate; chip->channel_count = runtime->channels; printk("em8xxx_capture_setaudio_interrupt chip = %p \n",chip); set_audio_parameters(chip); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -