📄 trident_main.c
字号:
/*--------------------------------------------------------------------------- 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 snd_pcm_hardware_t snd_trident_spdif_7018 ={ .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,};static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime){ snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; trident_t *trident; if (voice) { trident = voice->trident; snd_trident_free_voice(trident, voice); }}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; voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) return -EAGAIN; 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; voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) return -EAGAIN; voice->spdif = 1; voice->substream = substream; spin_lock_irq(&trident->reg_lock); 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; if (trident->device == TRIDENT_DEVICE_ID_SI7018) { runtime->hw = snd_trident_spdif; } else { runtime->hw = snd_trident_spdif_7018; } trident->spdif_pcm_ctl->vd[0].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); unsigned int temp; spin_lock_irq(&trident->reg_lock); // restore default SPDIF setting if (trident->device != TRIDENT_DEVICE_ID_SI7018) { outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); } else { outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)); if (trident->spdif_ctrl) { temp |= SPDIF_EN; } else { temp &= ~SPDIF_EN; } outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); } spin_unlock_irq(&trident->reg_lock); trident->spdif_pcm_ctl->vd[0].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; voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) return -EAGAIN; voice->capture = 1; 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; voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (voice == NULL) return -EAGAIN; voice->foldback_chan = substream->number; voice->substream = substream; 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_hw_params, .hw_free = snd_trident_hw_free, .prepare = snd_trident_playback_prepare, .trigger = snd_trident_trigger, .pointer = snd_trident_playback_pointer,};static snd_pcm_ops_t snd_trident_nx_playback_ops = { .open = snd_trident_playback_open, .close = snd_trident_playback_close, .ioctl = snd_trident_ioctl, .hw_params = snd_trident_hw_params, .hw_free = snd_trident_hw_free, .prepare = snd_trident_playback_prepare, .trigger = snd_trident_trigger, .pointer = snd_trident_playback_pointer, .page = snd_pcm_sgbuf_ops_page,};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_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -