📄 em8xxx_alsa.c
字号:
// Get the information for DRAM parameters for AudioDecoder Module dram_in.ProtectedFlags = 0; dram_in.MaxChannelOutCount = MAXCHANNELOUTCOUNT; dram_in.PtsFIFOCount = 30*60; dram_in.PCMLineCount = PCMLINECOUNT; dram_in.InbandFIFOCount = 128; dram_in.BitstreamFIFOSize = AUDIO_BITSTREAM_FIFO_SIZE; // DMA total buffer size dram_in.XferFIFOCount = AUDIO_DMA_BUFFER_COUNT; 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; profile.InbandFIFOCount = dram_in.InbandFIFOCount; 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; profile.UnprotectedSize = dram_out.UnprotectedSize; pS->AudioProfileCachedAddr = 0; 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; } else RMDBGLOG((ENABLE, "Audio profile created! \n")); // 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; } else RMDBGLOG((ENABLE, "CPU now running! \n")); pS->prepared = FALSE; return err;}static RMstatus open_audio_capture(em8xxx_t *pS){ struct em8xxxprivate *pE=Etable+(pS-Stable); RMstatus err; struct AudioCapture_DRAMSize_in_type capture_dram_in; struct AudioCapture_DRAMSize_out_type capture_dram_out; struct AudioCapture_Open_type capture_profile; enum ProcessorState run; RMuint32 audio_engine=EMHWLIB_MODULE(AudioEngine,audio_engine_index); RMuint32 audio_capture=EMHWLIB_MODULE(AudioCapture,audio_capture_index); struct MM_Malloc_in_type in; struct MM_Malloc_out_type out; // 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)); // 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; } /* Open the capture dma pool */ pS->capture_dmapool_id=kdmapool_open(pE->pllad,NULL,SERIALIN_DMA_BUFFER_COUNT,SERIALIN_DMA_BUFFER_SIZE_LOG2); printk("capture_dmapool id = %ld\n", pS->capture_dmapool_id); prepare_data(pS); return err;}static RMstatus set_audio_parameters(em8xxx_t *pS){ RMuint32 audio_engine = EMHWLIB_MODULE(AudioEngine,audio_engine_index); struct em8xxxprivate *pE = Etable +(pS-Stable); enum AudioEngine_SerialOut_type serialOutStatus; struct AudioEngine_SampleFrequencyFromSource_type sf; struct AudioEngine_I2SConfig_type i2s; enum AudioEngine_SpdifOut_type spdif_out; RMstatus err; struct AudioEngine_Volume_type volume; int i,closed; enum AudioDecoder_State_type state; RMDBGLOG((DISABLE, "set audio parameters \n")); // Volume Initialization for (i = 0; i <= 9; i++){ volume.Channel = i; volume.Volume = 0x10000000; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_Volume, &volume, sizeof(volume)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while setting audio volume! \n")); return err; } } // We have to know if the other decoder is working closed=1;#ifdef RMFEATURE_HAS_AUDIO_ENGINE_1 switch(audio_engine_index){ case 0: EM8XXXSNDGP(pE,EMHWLIB_MODULE(AudioDecoder,1-audio_decoder_index),RMAudioDecoderPropertyID_State,&state,sizeof(state)); if (state != AudioDecoder_State_Closed) closed=0; break; case 1: if (audio_decoder_index==2){ EM8XXXSNDGP(pE,EMHWLIB_MODULE(AudioDecoder,3),RMAudioDecoderPropertyID_State,&state,sizeof(state)); } else EM8XXXSNDGP(pE,EMHWLIB_MODULE(AudioDecoder,2),RMAudioDecoderPropertyID_State,&state,sizeof(state)); if (state != AudioDecoder_State_Closed) closed=0; break; } #else EM8XXXSNDGP(pE,EMHWLIB_MODULE(AudioDecoder,1-audio_decoder_index),RMAudioDecoderPropertyID_State,&state,sizeof(state)); if (state != AudioDecoder_State_Closed) closed=0; #endif // RMFEATURE_HAS_AUDIO_ENGINE_1 if(closed==1){ /* Setting the sample freqency */ EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_SampleFrequency, &pS->sample_rate, sizeof(pS->sample_rate)); if (RMFAILED(err)){ printk("Error while setting the sample frequency\n"); return err; } // Applying AudioEngine Module Options spdif_out = AudioEngine_SpdifOut_Active; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_SpdifOut, &spdif_out, sizeof(spdif_out)); if (RMFAILED (err)) { RMDBGLOG((ENABLE, "Error setting spdif_out property! \n")); return err; } pS->spdif_enable=1; sf.GeneratorNumber = 3; sf.SampleFrequency = pS->sample_rate; sf.Source = 1; sf.SourceFrequency = 27000000; sf.IntermediateFrequency = 148500000; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_SampleFrequencyFromSource, &sf, sizeof(sf)); if (RMFAILED (err)) { RMDBGLOG((ENABLE, "Error setting sf property! \n")); return err; } i2s.DataAlignment = 1; i2s.SClkInvert = TRUE; i2s.FrameInvert = TRUE; i2s.MSBFirst = TRUE; i2s.SampleSize16Bit = FALSE; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_I2SConfig, &i2s, sizeof(i2s)); if (RMFAILED (err)) { RMDBGLOG((ENABLE, "Error setting i2s property! \n")); return err; } serialOutStatus = AudioEngine_SerialOut_SO_ENABLE; EM8XXXSNDSP(pE, audio_engine, RMAudioEnginePropertyID_SerialOut, &serialOutStatus, sizeof(serialOutStatus)); if (RMFAILED (err)) { RMDBGLOG((ENABLE, "Error setting serialOut property! \n")); return err; } } RMDBGLOG((ENABLE, "Audio Engine properties set \n")); pS->prepared=TRUE; return RM_OK;}static RMstatus prepare_audio_decoder(em8xxx_t *pS){ long timeout; enum AudioDecoder_Command_type command; enum AudioDecoder_Codec_type codec; RMuint32 audio_decoder = EMHWLIB_MODULE(AudioDecoder,audio_decoder_index); struct em8xxxprivate *pE=Etable+(pS-Stable); RMstatus err; struct AudioDecoder_PcmCdaParameters_type pcm_parameters; struct AudioDecoder_MixerWeight_type cmdblock; RMuint32 pts_delay = PTS_FIRST_DELAY; // Weight Initialisation // Mixer weight initialization cmdblock.MixerValue_ch0=0x10000000; cmdblock.MixerValue_ch1=0x10000000; cmdblock.MixerValue_ch2=0x10000000; cmdblock.MixerValue_ch3=0x10000000; cmdblock.MixerValue_ch4=0x10000000; cmdblock.MixerValue_ch5=0x10000000; cmdblock.MixerValue_ch6=0x10000000; cmdblock.MixerValue_ch7=0x10000000; EM8XXXSNDSP( pE, audio_decoder,RMAudioDecoderPropertyID_MixerWeight,&cmdblock,sizeof(cmdblock)); pS->weight_l=VOLUME_INDEX_0DB; pS->weight_r=VOLUME_INDEX_0DB; codec = pS->format; // Uninit timeout = 0; command = AudioDecoder_Command_Uninit; EM8XXXSNDSP(pE,audio_decoder,RMAudioDecoderPropertyID_Command,&command,sizeof(command)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Unable to Uninit \n")); return err; } kc_udelay(1000); // Format EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_Codec, &codec, sizeof(codec)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error setting codec property! \n")); return err; } // PCM Parameters switch(pS->channel_count) { case 1: pcm_parameters.ChannelAssign = PcmCda1_C; break; case 2: default: pcm_parameters.ChannelAssign = PcmCda2_LR; break; } pcm_parameters.BitsPerSample = pS->nb_bits_per_sample; pcm_parameters.SamplingFrequency = pS->sample_rate; pcm_parameters.MsbFirst = pS->MSBFirst; pcm_parameters.OutputDualMode = DualMode_Stereo; pcm_parameters.OutputSpdif = OutputSpdif_Uncompressed; pcm_parameters.OutputChannels = Audio_Out_Ch_LR; pcm_parameters.OutputLfe = FALSE; pcm_parameters.SignedPCM = (pS->nb_bits_per_sample==16) ? TRUE : FALSE; pcm_parameters.BassMode = 0; EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_PcmCdaParameters, &pcm_parameters, sizeof(pcm_parameters)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting pcm parameters! \n")); return err; } //Init command = AudioDecoder_Command_Init; EM8XXXSNDSP(pE, audio_decoder, RMAudioDecoderPropertyID_Command, &command, sizeof(command)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while initializing audio decoder! \n")); return err; } timeout =0; kc_udelay(1000); printk("audio parameters are set : samplerate = %d, nb_bits_per_sample = %d, channelcount = %d\n", pS->sample_rate,pS->nb_bits_per_sample ,pS->channel_count);/* Pre fill Buffer to avoid underrun */ EM8XXXSNDSP(pE,EMHWLIB_MODULE(AudioDecoder,audio_decoder_index),RMAudioDecoderPropertyID_PreFillBuffer,&pts_delay,sizeof(pts_delay)); if (RMFAILED(err)){ printk("error while prefilling buffer"); } pS->audio_set=TRUE; return RM_OK;}static RMstatus start_stc(em8xxx_t *chip){ struct STC_Speed_type speed; RMstatus err; struct em8xxxprivate *pE = Etable + (chip-Stable); enum AudioDecoder_Command_type command; enum AudioDecoder_State_type state;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -