📄 em8xxx_alsa.c
字号:
em8xxx_t *chip = (em8xxx_t *) snd_kcontrol_chip(kcontrol); chip->decoder_weight = NULL;}static snd_kcontrol_new_t snd_em8xxx_control[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Hardware Master Playback Volume", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 0xffff, .info = snd_em8xxx_info_hw_volume, .get = snd_em8xxx_get_hw_volume, .put = snd_em8xxx_put_hw_volume, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .info = snd_em8xxx_spdif_default_info, .get = snd_em8xxx_spdif_default_get, .put = snd_em8xxx_spdif_default_put }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_em8xxx_spdif_mask_info, .get = snd_em8xxx_spdif_mask_get, }, { .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = snd_em8xxx_uswitch_info, .get = snd_em8xxx_spdout_enable_get, .put = snd_em8xxx_spdout_enable_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Decoder Weight", .index = 0, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .private_value = 0xffff, .info = snd_em8xxx_info_weight, .get = snd_em8xxx_get_weight, .put = snd_em8xxx_put_weight, }};static int __devinit snd_em8xxx_mixer(em8xxx_t *chip){ snd_card_t *card; int err,idx; card = chip->card; strcpy(card->mixername, "EM8xxx"); for (idx = 0; idx < ARRAY_SIZE(snd_em8xxx_control); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_em8xxx_control[idx], chip); if ((err = snd_ctl_add(card, kctl)) < 0){ printk("error adding control ! \n"); return err; } switch (idx) { case 0: chip->master_volume = kctl; kctl->private_free = snd_em8xxx_hwv_free; break; case 1: chip->spdif_default_ctl = kctl; kctl->private_free = snd_em8xxx_spdif_default_free; break; case 2: chip->spdif_mask_ctl = kctl; kctl->private_free = snd_em8xxx_spdif_mask_free; break; case 3: chip->spdif_switch_ctl = kctl; kctl->private_free = snd_em8xxx_spdif_switch_free; break; case 4: chip->decoder_weight = kctl; kctl->private_free = snd_em8xxx_weight_free; break; } } return 0;}/* ******************************************************************** ************* PCM PART DRIVER ************** ******************************************************************** */static snd_pcm_ops_t snd_em8xxx_playback_ops = { .open = snd_em8xxx_playback_open, .close = snd_em8xxx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_em8xxx_pcm_hw_params, .hw_free = snd_em8xxx_pcm_hw_free, .prepare = snd_em8xxx_playback_prepare, .trigger = snd_em8xxx_playback_trigger, .pointer = snd_em8xxx_playback_pointer, .ack = snd_em8xxx_playback_ack,};static snd_pcm_ops_t snd_em8xxx_capture_ops = { .open = snd_em8xxx_capture_open, .close = snd_em8xxx_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_em8xxx_pcm_hw_params, .hw_free = snd_em8xxx_pcm_hw_free, .prepare = snd_em8xxx_capture_prepare, .trigger = snd_em8xxx_capture_trigger, .pointer = snd_em8xxx_capture_pointer, .ack = snd_em8xxx_capture_ack,};static snd_pcm_hardware_t snd_em8xxx_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000, .rate_min = 8000, .rate_max = 96000, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = 32*(1024), .period_bytes_min = 2048, .period_bytes_max = 32*(1024), .periods_min = 2, .periods_max = 32, .fifo_size = 8000,};static snd_pcm_hardware_t snd_em8xxx_capture = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8), .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000, .rate_min = 8000, .rate_max = 96000, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = 32*(1024), .period_bytes_min = 4096, .period_bytes_max = 32*(1024), .periods_min = 2, .periods_max = 32, .fifo_size = 8000,};static RMstatus init_audio(em8xxx_t *pS){ struct em8xxxprivate *pE=Etable+(pS-Stable); RMstatus err; #if !defined(WITH_UCODE_BOOTLOADER) && !defined(WITH_XLOADED_UCODE) struct MM_Malloc_in_type in; enum ProcessorState run; RMuint32 audio_engine=EMHWLIB_MODULE(AudioEngine,audio_engine_index); struct MM_Malloc_out_type out; struct DemuxEngine_MicrocodeDRAMSize_in_type demux_size_in; struct DemuxEngine_MicrocodeDRAMSize_out_type demux_size_out; struct DemuxEngine_Microcode_type demux_ucode; RMuint32 demux_engine=EMHWLIB_MODULE(DemuxEngine,0); struct AudioEngine_MicrocodeDRAMSize_in_type size_in; struct AudioEngine_MicrocodeDRAMSize_out_type size_out; struct AudioEngine_Microcode_type ucode; // Loading Demux module run = CPU_RESET; EM8XXXSNDSP(pE, demux_engine, RMDemuxEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while resetting CPU! \n")); return err; } run = CPU_STOPPED; EM8XXXSNDSP(pE, demux_engine, RMDemuxEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while stopping CPU! \n")); return err; } // Loading Microcode for Demux Module demux_size_in.MicrocodeVersion = 1; EM8XXXSNDEXP(pE, demux_engine, RMDemuxEnginePropertyID_MicrocodeDRAMSize, &demux_size_in, sizeof(demux_size_in), &demux_size_out, sizeof(demux_size_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMDemuxEnginePropertyID_MicrocodeDRAMSize! %s\n")); return err; } demux_ucode.MicrocodeVersion = demux_size_in.MicrocodeVersion; if (demux_size_out.Size){ in.dramtype=RUA_DRAM_CACHED; in.Size=demux_size_out.Size; EM8XXXSNDEXP(pE, EMHWLIB_MODULE(MM,audio_mmID), RMMMPropertyID_Malloc, &in,sizeof(in), &out,sizeof(out)); if(err==RM_OK) demux_ucode.Address= (RMuint32)out.Address; else { RMDBGLOG((ENABLE," memory manager not existent\n")); return 0; } RMDBGLOG((ENABLE, "demux ucode cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", demux_ucode.Address, demux_size_out.Size, demux_ucode.Address + demux_size_out.Size)); } else { demux_ucode.Address = 0; RMDBGLOG((ENABLE, "demux ucode doesn't need DRAM\n")); } EM8XXXSNDSP(pE, demux_engine, RMDemuxEnginePropertyID_Microcode, &demux_ucode, sizeof(demux_ucode)); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error while loading microcode for Demux Module! \n")); return err; } // starting the DemuxEngine Module run = CPU_RUNNING; EM8XXXSNDSP(pE, demux_engine, RMDemuxEnginePropertyID_State, &run, sizeof(run)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting property DemuxEngineProperty_State! \n")); return err; } // 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; }#else EM8XXXSNDSP(pE, DemuxEngine, RMDemuxEnginePropertyID_TimerInit, NULL, 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while launching STC code inside TDMX %d\n", err)); return err; }#endif // WITH_UCODE_BOOTLOADER RMDBGLOG((ENABLE, "End of audio init! \n")); return RM_OK; }static RMstatus open_audio_decoder(em8xxx_t *pS){ struct em8xxxprivate *pE=Etable+(pS-Stable); RMstatus err; struct AudioDecoder_DRAMSizeX_in_type dram_in; struct AudioDecoder_DRAMSizeX_out_type dram_out; struct AudioDecoder_OpenX_type profile; enum ProcessorState run; RMuint32 audio_engine=EMHWLIB_MODULE(AudioEngine,audio_engine_index); RMuint32 audio_decoder=EMHWLIB_MODULE(AudioDecoder,audio_decoder_index); struct MM_Malloc_in_type in; struct MM_Malloc_out_type out; struct STC_Open_type stc_open; struct AudioEngine_DecoderSharedMemory_type shared; struct AudioEngine_DecoderSharedMemoryInfo_in_type info_in; struct AudioEngine_DecoderSharedMemoryInfo_out_type info_out; printk("opening STC \n"); // STC Opening stc_open.master=Master_STC; if(audio_engine_index==0) stc_open.stc_timer_id=audio_decoder_index*3; else if (audio_decoder_index==2) stc_open.stc_timer_id=0; else stc_open.stc_timer_id=2; stc_open.stc_time_resolution=90000; stc_open.video_timer_id=NO_TIMER; stc_open.video_time_resolution=0; stc_open.video_offset=0; if(audio_engine_index==0) stc_open.audio_timer_id=audio_decoder_index*3+1; else if (audio_decoder_index==2) stc_open.audio_timer_id=1; else stc_open.audio_timer_id=3; stc_open.audio_time_resolution=90000; stc_open.audio_offset=0; EM8XXXSNDSP(pE,EMHWLIB_MODULE(STC,audio_decoder_index),RMSTCPropertyID_Open,&stc_open,sizeof(stc_open)); if (RMFAILED(err)){ printk("Error while opening STC Module! \n"); return err; } RMDBGLOG((ENABLE, "Use STC master : %d audio : %d\n",stc_open.stc_timer_id, stc_open.audio_timer_id)); pS->firstPTS = TRUE; pS->audio_set = FALSE; /*Allocation of Shared memory*/ 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)); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -