📄 em8xxx_oss.c
字号:
static RMstatus cleanup_audio(struct sndprivate *pS){ RMuint32 profile; struct em8xxxprivate *pE = Etable +(pS-Stable); RMstatus err; // close audio profile profile=0; EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioDecoder,audio_decoder_index), RMAudioDecoderPropertyID_Close, &profile, sizeof(profile)); EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index), RMAudioCapturePropertyID_Close, &profile, sizeof(profile)); // close serialin dma pool kdmapool_close(pE->pllad,pS->capture_dmapool_id); // close STC EM8XXXSNDSP(pE,EMHWLIB_MODULE(STC,audio_decoder_index),RMSTCPropertyID_Close, NULL,sizeof(RMuint32)); // free SharedMemory if (EMHWLIB_MODULE(AudioDecoder,audio_decoder_index) != 0) { /* Free the audio shared memory per engine */ RMstatus err; RMuint32 connected_task_count; EM8XXXSNDGP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_ConnectedTaskCount, &connected_task_count, sizeof(connected_task_count)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get RMAudioEnginePropertyID_ConnectedTaskCount %lu\n", EMHWLIB_MODULE(AudioEngine,audio_engine_index))); return err; } if (connected_task_count == 0) { struct AudioEngine_DecoderSharedMemory_type shared; RMuint32 address; EM8XXXSNDGP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory0\n")); return err; } if (shared.Address) { RMDBGLOG((ENABLE, "FREE %lx_DRAM AUDIO SHARED MEMORY addr=0x%lx size=0x%lx!\n", audio_decoder_index, shared.Address, shared.Size)); address = shared.Address; shared.Address = 0; shared.Size = 0; EM8XXXSNDSP(pE, EMHWLIB_MODULE(AudioEngine,audio_engine_index), RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); /* Unlock the shared address */ rm_free_ptr (pE, address); } } else { RMDBGLOG((ENABLE, "CANNOT FREE AUDIO SHARED MEMORY. There are still %lx audio tasks opened. \n", connected_task_count)); } } // free resources#if !defined(WITH_UCODE_BOOTLOADER) && !defined(WITH_XLOADED_UCODE) if (pS->AudioUCodeAddr); rm_free_ptr (pE,pS->AudioUCodeAddr);#endif // WITH_UCODE_BOOTLOADER if (pS->AudioProfileCachedAddr); rm_free_ptr (pE,pS->AudioProfileCachedAddr); if (pS->AudioProfileUncachedAddr); rm_free_ptr (pE,pS->AudioProfileUncachedAddr); if (pS->SerialinProfileCachedAddr); rm_free_ptr (pE,pS->SerialinProfileCachedAddr); if (pS->SerialinProfileUncachedAddr); rm_free_ptr (pE,pS->SerialinProfileUncachedAddr); return RM_OK;}static RMstatus init_audio(struct sndprivate *pS){ struct em8xxxprivate *pE=Etable+(pS-Stable); RMstatus err; enum ProcessorState run; struct AudioDecoder_DRAMSizeX_in_type dram_in; struct AudioDecoder_DRAMSizeX_out_type dram_out; struct AudioDecoder_OpenX_type profile; struct AudioCapture_DRAMSize_in_type capture_dram_in; struct AudioCapture_DRAMSize_out_type capture_dram_out; struct AudioCapture_Open_type capture_profile; RMuint32 audio_capture=EMHWLIB_MODULE(AudioCapture,audio_capture_index); RMuint32 audio_decoder=EMHWLIB_MODULE(AudioDecoder,audio_decoder_index); RMuint32 audio_engine=EMHWLIB_MODULE(AudioEngine,audio_engine_index); struct MM_Malloc_in_type in; struct MM_Malloc_out_type out; struct AudioEngine_DecoderSharedMemory_type shared; struct AudioEngine_DecoderSharedMemoryInfo_in_type info_in; struct AudioEngine_DecoderSharedMemoryInfo_out_type info_out;#if !defined(WITH_UCODE_BOOTLOADER) && !defined(WITH_XLOADED_UCODE) struct AudioEngine_MicrocodeDRAMSize_in_type size_in; struct AudioEngine_MicrocodeDRAMSize_out_type size_out; struct AudioEngine_Microcode_type ucode;#endif // WITH_UCODE_BOOTLOADER printk("initializing audio parameters \n");#if !defined(WITH_UCODE_BOOTLOADER) && !defined(WITH_XLOADED_UCODE) // Loading AudioEngine Module run = CPU_RESET; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while resetting CPU! \n")); return err; } run = CPU_STOPPED; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while stopping CPU! \n")); return err; } // Loading MicroCode for AudioEngine Module size_in.MicrocodeVersion = 1; // memory allocation for the microcode EM8XXXSNDEXP( pE, audio_engine, RMAudioEnginePropertyID_MicrocodeDRAMSize, &size_in, sizeof(size_in), &size_out, sizeof(size_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while allocating memory for audio microcode! \n")); return err; } ucode.MicrocodeVersion = size_in.MicrocodeVersion; in.dramtype=RUA_DRAM_CACHED; in.Size=size_out.Size; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err==RM_OK) ucode.Address= (RMuint32)out.Address; else { RMDBGLOG((ENABLE," memory manager not existent\n")); return 0; } printk("audio ucode cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", ucode.Address, size_out.Size, ucode.Address + size_out.Size); pS->AudioUCodeAddr = ucode.Address; // microcode loading EM8XXXSNDSP( pE, audio_engine, RMAudioEnginePropertyID_Microcode, &ucode, sizeof(ucode)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while loading audio microcode! \n")); return err; } #endif // WITH_UCODE_BOOTLOADER // Get the information for DRAM parameters for AudioCapture Module capture_dram_in.SerialInFIFOSize = SERIALIN_FIFO_SIZE; capture_dram_in.XferFIFOCount = SERIALIN_DMA_BUFFER_COUNT; // Memory allocation for AudioCapture Module EM8XXXSNDEXP(pE, audio_capture, RMAudioCapturePropertyID_DRAMSize, &capture_dram_in, sizeof(capture_dram_in), &capture_dram_out, sizeof(capture_dram_out)); // Creation of the audio capture profile capture_profile.CaptureMode = 0; // File mode capture_profile.Delay=0; capture_profile.SI_CONF=0x107 | (1 << 3); capture_profile.SerialInFIFOSize = capture_dram_in.SerialInFIFOSize; capture_profile.XferFIFOCount = capture_dram_in.XferFIFOCount; capture_profile.CachedSize = capture_dram_out.CachedSize; if (capture_profile.CachedSize > 0){ in.dramtype=RUA_DRAM_CACHED; in.Size=capture_profile.CachedSize; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err==RM_OK) capture_profile.CachedAddress= (RMuint32)out.Address; else { RMDBGLOG((ENABLE," memory manager not existent\n")); return 0; } printk("audio capture cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", capture_profile.CachedAddress, capture_profile.CachedSize, capture_profile.CachedAddress + capture_profile.CachedSize); } else { capture_profile.CachedAddress = 0; } pS->SerialinProfileCachedAddr = capture_profile.CachedAddress; capture_profile.UncachedSize = capture_dram_out.UncachedSize; if (capture_profile.UncachedSize > 0){ in.dramtype=RUA_DRAM_UNCACHED; in.Size=capture_profile.UncachedSize; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err==RM_OK) capture_profile.UncachedAddress = (RMuint32)out.Address; else { RMDBGLOG((ENABLE," memory manager not existent\n")); return 0; } printk("audio capture uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", capture_profile.UncachedAddress, capture_profile.UncachedSize, capture_profile.UncachedAddress + capture_profile.UncachedSize); } else { capture_profile.UncachedAddress = 0; } pS->SerialinProfileUncachedAddr = capture_profile.UncachedAddress; EM8XXXSNDSP(pE, audio_capture, RMAudioCapturePropertyID_Open, &capture_profile, sizeof(capture_profile)); // Shared memory allocation info_in.Reserved1 = 0; info_in.Reserved2 = 0; EM8XXXSNDEXP(pE, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemoryInfo, &info_in, sizeof(info_in), &info_out, sizeof(info_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMAudioDecoderPropertyID_DecoderDataMemory!\n")); return err; } /* check if audio shared memory is already set in audio engine */ EM8XXXSNDGP(pE, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory\n")); return err; } if (shared.Address) { printk("=================%lx_DRAM AUDIO SHARED MEMORY is already set addr=0x%lx size=0x%lx\n", audio_engine, shared.Address, shared.Size); } else { /* allocate and set the shared memory used by all decoders of the same engine */ shared.Size = info_out.DecoderSharedSize; if (shared.Size) { in.dramtype=RUA_DRAM_CACHED; in.Size=shared.Size; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err == RM_OK) shared.Address = (RMuint32)out.Address; else { shared.Address = 0; RMDBGLOG((ENABLE, "ERROR: could not allocate shared 0x%08lX bytes in DRAM %lu!\n", shared.Address, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGPRINT((ENABLE, "===============ALLOCATING %lx_DRAM AUDIO SHARED MEMORY addr: 0x%08lX, size 0x%08lX\n", audio_engine, shared.Address, shared.Size)); EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); } } // Get the information for DRAM parameters for AudioDecoder Module dram_in.MaxChannelOutCount = MAXCHANNELOUTCOUNT; dram_in.PCMLineCount = PCMLINECOUNT; dram_in.BitstreamFIFOSize = (1 << AUDIO_DMA_BUFFER_SIZE_LOG2) * AUDIO_DMA_BUFFER_COUNT; // DMA total buffer size dram_in.XferFIFOCount = AUDIO_DMA_BUFFER_COUNT; dram_in.ProtectedFlags = 0; dram_in.PtsFIFOCount = 30*60; dram_in.InbandFIFOCount = 128; dram_in.XtaskInbandFIFOCount = 0; // Memory allocation for AudioDecoder Module EM8XXXSNDEXP(pE, audio_decoder, RMAudioDecoderPropertyID_DRAMSizeX, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "No memory available for Audio RISC Processor! \n")); return err; } // Creation of the audio profile profile.ProtectedFlags = 0; /*All memory is unprotected*/ profile.MaxChannelOutCount = dram_in.MaxChannelOutCount; profile.PtsFIFOCount = dram_in.PtsFIFOCount;//PTS_FIFO_COUNT; profile.InbandFIFOCount = dram_in.InbandFIFOCount;//INBAND_FIFO_COUNT; profile.PCMLineCount = dram_in.PCMLineCount; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.XtaskInbandFIFOCount = 0; profile.XtaskId = 0; profile.OutputSamplesProtectedAddress = 0; profile.OutputSamplesProtectedSize = 0; profile.BitstreamProtectedAddress = 0; profile.BitstreamProtectedSize = 0; pS->AudioProfileCachedAddr = 0; profile.UnprotectedSize = dram_out.UnprotectedSize; if (profile.UnprotectedSize > 0){ in.dramtype=RUA_DRAM_UNCACHED; in.Size = profile.UnprotectedSize; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err==RM_OK) profile.UnprotectedAddress = (RMuint32)out.Address; else { RMDBGLOG((ENABLE," memory manager not existent\n")); return 0; } printk("audio uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.UnprotectedAddress, profile.UnprotectedSize, profile.UnprotectedAddress + profile.UnprotectedSize); } else { profile.UnprotectedAddress = 0; } pS->AudioProfileUncachedAddr = profile.UnprotectedAddress; profile.STCId = audio_decoder_index; EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_OpenX, &profile, sizeof(profile)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while creating audio profile! \n")); return err; } // starting the Audio RISC run = CPU_RUNNING; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while starting CPU! \n")); return err; } pS->capture_enable = FALSE; pS->playback_enable = FALSE; return RM_OK; }static int rm_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; RMDBGLOG((ENABLE,"Trying to free %08lx with memory manager %d \n",ptr,dramIndex)); if (dramIndex<=1) { EM8XXXSNDSP(pE, EMHWLIB_MODULE(MM,0), 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 int rm_release_dsp(struct inode *inode, struct file *file){ struct sndprivate *pS=(struct sndprivate *)file->private_data; struct em8xxxprivate *pE; RMstatus err; enum AudioCapture_Capture_type cmd; RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index); enum AudioDecoder_Command_type command; RMuint32 bus_addr; printk("closes em8xxx sound device (/dev/dsp%d)\n", pS->dsp_dev); pE=Etable+(pS-Stable); pS->format = 0; pS->sample_rate = 0; pS->channel_count = 0; pS->i_start=0; pS->j_start=0; pS->last_i=0; pS->last_j=0; pS->capture_readable=0; pS->capture_buffer_size=0; pS->capture_read=0; pS->capture_enable = FALSE; pS->playback_enable = FALSE; pS->state=0; // send off command to audio capture cmd = AudioCapture_Capture_Off; EM8XXXSNDSP(pE, audio_capture,RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd)); prepare_data(pS); command = AudioDecoder_Command_Stop; EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioDecoder,audio_decoder_index), RMAudioDecoderPropertyID_Command, &command, sizeof(command)); krua_unregister_event_callback(pE,EMHWLIB_MODULE(AudioCapture,audio_capture_index),event_callback); tasklet_kill(&pS->event_tq); if(pS->pBuf != NULL){ // release buffer bus_addr = kdmapool_get_bus_address(pE->pllad,pS->dmapool_id,pS->pBuf,0); kdmapool_release(pE->pllad,pS->dmapool_id,bus_addr); } // close dma pool kdmapool_close(pE->pllad,pS->dmapool_id); cleanup_audio(pS); pS->dsp_open_count --; return 0;}static ssize_t rm_read_dsp(struct file *file, char *buffer, size_t count, loff_t *ppos){ RMstatus rc,err; RMuint32 audio_capture = EMHWLIB_MODULE(AudioCapture,audio_capture_index); struct em8xxx_data param; void *context; RMuint8 info[INFO_SIZE]; RMuint32 infoSize = INFO_SIZE; size_t to_read; struct sndprivate *pS=(struct sndprivate *)file->private_data; struct em8xxxprivate *pE=Etable+(pS-Stable); RMuint32 samples; RMint32 i,j; printk("rm_read_dsp \n"); samples = bytes_to_samples(pS,count); to_read = samples * 6; // in the microcode we capture in 24 bits, 2 channels. if(!pS->capture_enable){ rc=start_capture(pE); if(RMFAILED(rc)){ printk("error while starting capture \n"); return -EINVAL; } } while(1){ RMuint32 it=0; if(pS->capture_pBuf == NULL){ // Receive buffer printk("receive buffer \n"); param.moduleId = audio_capture; param.poolId = pS->capture_dmapool_id; param.infoSize = infoSize; err=RM_INSUFFICIENT_SIZE; while(err==RM_INSUFFICIENT_SIZE){ it ++; if(it >= 10){ printk("forced to quit loop \n"); return -EINVAL; } kc_spin_lock_bh(pE->lock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -