📄 trident_main.c
字号:
} else { if (evoice != NULL) { snd_trident_free_voice(trident, evoice); voice->extra = evoice = NULL; } } return 0;}/*--------------------------------------------------------------------------- snd_trident_hw_params Description: Set the hardware parameters for the playback device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params){ int err; err = snd_trident_allocate_pcm_mem(substream, hw_params); if (err >= 0) err = snd_trident_allocate_evoice(substream, hw_params); return err;}/*--------------------------------------------------------------------------- snd_trident_playback_hw_free Description: Release the hardware resources for the playback device. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_hw_free(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice ? voice->extra : NULL; if (trident->tlb.entries) { if (voice && voice->memblk) { snd_trident_free_pages(trident, voice->memblk); voice->memblk = NULL; } } snd_pcm_lib_free_pages(substream); if (evoice != NULL) { snd_trident_free_voice(trident, evoice); voice->extra = NULL; } return 0;}/*--------------------------------------------------------------------------- snd_trident_playback_prepare Description: Prepare playback device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_playback_prepare(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice->extra; snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number]; spin_lock_irq(&trident->reg_lock); /* set delta (rate) value */ voice->Delta = snd_trident_convert_rate(runtime->rate); voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); /* set Loop Begin Address */ if (voice->memblk) voice->LBA = voice->memblk->offset; else voice->LBA = runtime->dma_addr; voice->CSO = 0; voice->ESO = runtime->buffer_size - 1; /* in samples */ voice->CTRL = snd_trident_control_mode(substream); voice->FMC = 3; voice->GVSel = 1; voice->EC = 0; voice->Alpha = 0; voice->FMS = 0; voice->Vol = mix->vol; voice->RVol = mix->rvol; voice->CVol = mix->cvol; voice->Pan = mix->pan; voice->Attribute = 0;#if 0 voice->Attribute = (1<<(30-16))|(2<<(26-16))| (0<<(24-16))|(0x1f<<(19-16));#else voice->Attribute = 0;#endif snd_trident_write_voice_regs(trident, voice); if (evoice != NULL) { evoice->Delta = voice->Delta; evoice->spurious_threshold = voice->spurious_threshold; evoice->LBA = voice->LBA; evoice->CSO = 0; evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */ evoice->CTRL = voice->CTRL; evoice->FMC = 3; evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1; evoice->EC = 0; evoice->Alpha = 0; evoice->FMS = 0; evoice->Vol = 0x3ff; /* mute */ evoice->RVol = evoice->CVol = 0x7f; /* mute */ evoice->Pan = 0x7f; /* mute */#if 0 evoice->Attribute = (1<<(30-16))|(2<<(26-16))| (0<<(24-16))|(0x1f<<(19-16));#else evoice->Attribute = 0;#endif snd_trident_write_voice_regs(trident, evoice); evoice->isync2 = 1; evoice->isync_mark = runtime->period_size; evoice->ESO = (runtime->period_size * 2) - 1; } spin_unlock_irq(&trident->reg_lock); return 0;}/*--------------------------------------------------------------------------- snd_trident_capture_hw_params Description: Set the hardware parameters for the capture device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params){ return snd_trident_allocate_pcm_mem(substream, hw_params);}/*--------------------------------------------------------------------------- snd_trident_capture_prepare Description: Prepare capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_capture_prepare(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; unsigned int val, ESO_bytes; spin_lock_irq(&trident->reg_lock); // Initilize the channel and set channel Mode outb(0, TRID_REG(trident, LEGACY_DMAR15)); // Set DMA channel operation mode register outb(0x54, TRID_REG(trident, LEGACY_DMAR11)); // Set channel buffer Address, DMAR0 expects contiguous PCI memory area voice->LBA = runtime->dma_addr; outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0)); if (voice->memblk) voice->LBA = voice->memblk->offset; // set ESO ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1; outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6)); outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4)); ESO_bytes++; // Set channel sample rate, 4.12 format val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate; outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); // Set channel interrupt blk length if (snd_pcm_format_width(runtime->format) == 16) { val = (unsigned short) ((ESO_bytes >> 1) - 1); } else { val = (unsigned short) (ESO_bytes - 1); } outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL)); // Right now, set format and start to run captureing, // continuous run loop enable. trident->bDMAStart = 0x19; // 0001 1001b if (snd_pcm_format_width(runtime->format) == 16) trident->bDMAStart |= 0x80; if (snd_pcm_format_signed(runtime->format)) trident->bDMAStart |= 0x20; if (runtime->channels > 1) trident->bDMAStart |= 0x40; // Prepare capture intr channel voice->Delta = snd_trident_convert_rate(runtime->rate); voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); voice->isync = 1; voice->isync_mark = runtime->period_size; voice->isync_max = runtime->buffer_size; // Set voice parameters voice->CSO = 0; voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1; voice->CTRL = snd_trident_control_mode(substream); voice->FMC = 3; voice->RVol = 0x7f; voice->CVol = 0x7f; voice->GVSel = 1; voice->Pan = 0x7f; /* mute */ voice->Vol = 0x3ff; /* mute */ voice->EC = 0; voice->Alpha = 0; voice->FMS = 0; voice->Attribute = 0; snd_trident_write_voice_regs(trident, voice); spin_unlock_irq(&trident->reg_lock); return 0;}/*--------------------------------------------------------------------------- snd_trident_si7018_capture_hw_params Description: Set the hardware parameters for the capture device. Parameters: substream - PCM substream class hw_params - hardware parameters Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params){ int err; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) return err; return snd_trident_allocate_evoice(substream, hw_params);}/*--------------------------------------------------------------------------- snd_trident_si7018_capture_hw_free Description: Release the hardware resources for the capture device. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice ? voice->extra : NULL; snd_pcm_lib_free_pages(substream); if (evoice != NULL) { snd_trident_free_voice(trident, evoice); voice->extra = NULL; } return 0;}/*--------------------------------------------------------------------------- snd_trident_si7018_capture_prepare Description: Prepare capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice->extra; spin_lock_irq(&trident->reg_lock); voice->LBA = runtime->dma_addr; voice->Delta = snd_trident_convert_adc_rate(runtime->rate); voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); // Set voice parameters voice->CSO = 0; voice->ESO = runtime->buffer_size - 1; /* in samples */ voice->CTRL = snd_trident_control_mode(substream); voice->FMC = 0; voice->RVol = 0; voice->CVol = 0; voice->GVSel = 1; voice->Pan = T4D_DEFAULT_PCM_PAN; voice->Vol = 0; voice->EC = 0; voice->Alpha = 0; voice->FMS = 0; voice->Attribute = (2 << (30-16)) | (2 << (26-16)) | (2 << (24-16)) | (1 << (23-16)); snd_trident_write_voice_regs(trident, voice); if (evoice != NULL) { evoice->Delta = snd_trident_convert_rate(runtime->rate); evoice->spurious_threshold = voice->spurious_threshold; evoice->LBA = voice->LBA; evoice->CSO = 0; evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */ evoice->CTRL = voice->CTRL; evoice->FMC = 3; evoice->GVSel = 0; evoice->EC = 0; evoice->Alpha = 0; evoice->FMS = 0; evoice->Vol = 0x3ff; /* mute */ evoice->RVol = evoice->CVol = 0x7f; /* mute */ evoice->Pan = 0x7f; /* mute */ evoice->Attribute = 0; snd_trident_write_voice_regs(trident, evoice); evoice->isync2 = 1; evoice->isync_mark = runtime->period_size; evoice->ESO = (runtime->period_size * 2) - 1; } spin_unlock_irq(&trident->reg_lock); return 0;}/*--------------------------------------------------------------------------- snd_trident_foldback_prepare Description: Prepare foldback capture device for playback. Parameters: substream - PCM substream class Returns: Error status ---------------------------------------------------------------------------*/static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice->extra; spin_lock_irq(&trident->reg_lock); /* Set channel buffer Address */ if (voice->memblk) voice->LBA = voice->memblk->offset; else voice->LBA = runtime->dma_addr; /* set target ESO for channel */ voice->ESO = runtime->buffer_size - 1; /* in samples */ /* set sample rate */ voice->Delta = 0x1000; voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size); voice->CSO = 0; voice->CTRL = snd_trident_control_mode(substream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -