📄 trident_main.c
字号:
return 0; result = inw(TRID_REG(trident, T4D_SBBL_SBCL)); if (runtime->channels > 1) result >>= 1; result = runtime->buffer_size - result; // printk("capture result = 0x%x, cso = 0x%x\n", result, cso); return result;}/*--------------------------------------------------------------------------- snd_trident_spdif_pointer Description: This routine return the SPDIF playback position Parameters: substream - PCM substream class Returns: position of buffer ---------------------------------------------------------------------------*/static snd_pcm_uframes_t snd_trident_spdif_pointer(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 result; if (!voice->running) return 0; result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff; return result;}/* * Playback support device description */static snd_pcm_hardware_t snd_trident_playback ={ info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), formats: (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), rates: SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, rate_min: 4000, rate_max: 48000, channels_min: 1, channels_max: 2, buffer_bytes_max: (256*1024), period_bytes_min: 64, period_bytes_max: (256*1024), periods_min: 1, periods_max: 1024, fifo_size: 0,};/* * Capture support device description */static snd_pcm_hardware_t snd_trident_capture ={ info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), formats: (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), rates: SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, rate_min: 4000, rate_max: 48000, channels_min: 1, channels_max: 2, buffer_bytes_max: (128*1024), period_bytes_min: 64, period_bytes_max: (128*1024), periods_min: 1, periods_max: 1024, fifo_size: 0,};/* * Foldback capture support device description */static snd_pcm_hardware_t snd_trident_foldback ={ info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), formats: SNDRV_PCM_FMTBIT_S16_LE, rates: SNDRV_PCM_RATE_48000, rate_min: 48000, rate_max: 48000, channels_min: 2, channels_max: 2, buffer_bytes_max: (128*1024), period_bytes_min: 64, period_bytes_max: (128*1024), periods_min: 1, periods_max: 1024, fifo_size: 0,};/* * SPDIF playback support device description */static snd_pcm_hardware_t snd_trident_spdif ={ info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), formats: SNDRV_PCM_FMTBIT_S16_LE, rates: (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000), rate_min: 32000, rate_max: 48000, channels_min: 2, channels_max: 2, buffer_bytes_max: (128*1024), period_bytes_min: 64, period_bytes_max: (128*1024), periods_min: 1, periods_max: 1024, fifo_size: 0,};static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime){ unsigned long flags; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; trident_t *trident; if (voice) { trident = voice->trident; spin_lock_irqsave(&trident->reg_lock, flags); snd_trident_free_voice(trident, voice); spin_unlock_irqrestore(&trident->reg_lock, flags); }}static int snd_trident_playback_open(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; spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) { spin_unlock_irq(&trident->reg_lock); return -EAGAIN; } spin_unlock_irq(&trident->reg_lock); snd_trident_pcm_mixer_build(trident, voice, substream); voice->substream = substream; runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; runtime->hw = snd_trident_playback; snd_pcm_set_sync(substream); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); return 0;}/*--------------------------------------------------------------------------- snd_trident_playback_close Description: This routine will close the 4DWave playback device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/static int snd_trident_playback_close(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_pcm_mixer_free(trident, voice, substream); return 0;}/*--------------------------------------------------------------------------- snd_trident_spdif_open Description: This routine will open the 4DWave SPDIF device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/static int snd_trident_spdif_open(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) { spin_unlock_irq(&trident->reg_lock); return -EAGAIN; } voice->spdif = 1; voice->substream = substream; trident->spdif_pcm_bits = trident->spdif_bits; spin_unlock_irq(&trident->reg_lock); runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; runtime->hw = snd_trident_spdif; trident->spdif_pcm_ctl->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); return 0;}/*--------------------------------------------------------------------------- snd_trident_spdif_close Description: This routine will close the 4DWave SPDIF device. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/static int snd_trident_spdif_close(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); spin_lock_irq(&trident->reg_lock); // restore default SPDIF setting outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); spin_unlock_irq(&trident->reg_lock); trident->spdif_pcm_ctl->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id); return 0;}/*--------------------------------------------------------------------------- snd_trident_capture_open Description: This routine will open the 4DWave capture device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/static int snd_trident_capture_open(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) { spin_unlock_irq(&trident->reg_lock); return -EAGAIN; } voice->capture = 1; spin_unlock_irq(&trident->reg_lock); voice->substream = substream; runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; runtime->hw = snd_trident_capture; snd_pcm_set_sync(substream); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); return 0;}/*--------------------------------------------------------------------------- snd_trident_capture_close Description: This routine will close the 4DWave capture device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/static int snd_trident_capture_close(snd_pcm_substream_t * substream){ return 0;}/*--------------------------------------------------------------------------- snd_trident_foldback_open Description: This routine will open the 4DWave foldback capture device. Parameters: substream - PCM substream class Returns: status - success or failure flag ---------------------------------------------------------------------------*/static int snd_trident_foldback_open(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) { spin_unlock_irq(&trident->reg_lock); return -EAGAIN; } if (trident->tlb.entries) { voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); if (voice->memblk == NULL) { snd_trident_free_voice(trident, voice); spin_unlock_irq(&trident->reg_lock); return -ENOMEM; } } voice->substream = substream; voice->foldback_chan = substream->number; spin_unlock_irq(&trident->reg_lock); runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; runtime->hw = snd_trident_foldback; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); return 0;}/*--------------------------------------------------------------------------- snd_trident_foldback_close Description: This routine will close the 4DWave foldback capture device. For now we will simply free the dma transfer buffer. Parameters: substream - PCM substream class ---------------------------------------------------------------------------*/static int snd_trident_foldback_close(snd_pcm_substream_t * substream){ trident_t *trident = snd_pcm_substream_chip(substream); snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; voice = (snd_trident_voice_t *) runtime->private_data; /* stop capture channel */ spin_lock_irq(&trident->reg_lock); outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan)); spin_unlock_irq(&trident->reg_lock); return 0;}/*--------------------------------------------------------------------------- PCM operations ---------------------------------------------------------------------------*/static snd_pcm_ops_t snd_trident_playback_ops = { open: snd_trident_playback_open, close: snd_trident_playback_close, ioctl: snd_trident_ioctl, hw_params: snd_trident_playback_hw_params, hw_free: snd_trident_playback_hw_free, prepare: snd_trident_playback_prepare, trigger: snd_trident_trigger, pointer: snd_trident_playback_pointer,};static snd_pcm_ops_t snd_trident_capture_ops = { open: snd_trident_capture_open, close: snd_trident_capture_close, ioctl: snd_trident_ioctl, hw_params: snd_trident_capture_hw_params, hw_free: snd_trident_capture_hw_free, prepare: snd_trident_capture_prepare, trigger: snd_trident_trigger, pointer: snd_trident_capture_pointer,};static snd_pcm_ops_t snd_trident_si7018_capture_ops = { open: snd_trident_capture_open, close: snd_trident_capture_close, ioctl: snd_trident_ioctl, hw_params: snd_trident_si7018_capture_hw_params, hw_free: snd_trident_si7018_capture_hw_free, prepare: snd_trident_si7018_capture_prepare, trigger: snd_trident_trigger, pointer: snd_trident_playback_pointer,};static snd_pcm_ops_t snd_trident_foldback_ops = { open: snd_trident_foldback_open, close: snd_trident_foldback_close, ioctl: snd_tri
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -