📄 cs46xx_lib.c
字号:
}static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream);static int snd_cs46xx_playback_close_iec958(snd_pcm_substream_t * substream){ int err; cs46xx_t *chip = snd_pcm_substream_chip(substream); snd_printdd("close raw iec958 channel\n"); err = snd_cs46xx_playback_close(substream); down (&chip->spos_mutex); cs46xx_iec958_post_close (chip); up (&chip->spos_mutex); return err;}#endifstatic int snd_cs46xx_capture_open(snd_pcm_substream_t * substream){ cs46xx_t *chip = snd_pcm_substream_chip(substream); if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->capt.hw_buf) < 0) return -ENOMEM; chip->capt.substream = substream; substream->runtime->hw = snd_cs46xx_capture; if (chip->accept_valid) substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; chip->active_ctrl(chip, 1);#ifdef CONFIG_SND_CS46XX_NEW_DSP snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes);#endif return 0;}static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream){ cs46xx_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; cs46xx_pcm_t * cpcm; cpcm = runtime->private_data; /* when playback_open fails, then cpcm can be NULL */ if (!cpcm) return -ENXIO;#ifdef CONFIG_SND_CS46XX_NEW_DSP down (&chip->spos_mutex); if (cpcm->pcm_channel) { cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); cpcm->pcm_channel = NULL; } up (&chip->spos_mutex);#else chip->playback_pcm = NULL;#endif cpcm->substream = NULL; snd_dma_free_pages(&cpcm->hw_buf); chip->active_ctrl(chip, -1); return 0;}static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream){ cs46xx_t *chip = snd_pcm_substream_chip(substream); chip->capt.substream = NULL; snd_dma_free_pages(&chip->capt.hw_buf); chip->active_ctrl(chip, -1); return 0;}#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic snd_pcm_ops_t snd_cs46xx_playback_rear_ops = { .open = snd_cs46xx_playback_open_rear, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_direct_pointer,};static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = { .open = snd_cs46xx_playback_open_rear, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_indirect_pointer, .ack = snd_cs46xx_playback_transfer,};static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = { .open = snd_cs46xx_playback_open_clfe, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_direct_pointer,};static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = { .open = snd_cs46xx_playback_open_clfe, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_indirect_pointer, .ack = snd_cs46xx_playback_transfer,};static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = { .open = snd_cs46xx_playback_open_iec958, .close = snd_cs46xx_playback_close_iec958, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_direct_pointer,};static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = { .open = snd_cs46xx_playback_open_iec958, .close = snd_cs46xx_playback_close_iec958, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_indirect_pointer, .ack = snd_cs46xx_playback_transfer,};#endifstatic snd_pcm_ops_t snd_cs46xx_playback_ops = { .open = snd_cs46xx_playback_open, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_direct_pointer,};static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = { .open = snd_cs46xx_playback_open, .close = snd_cs46xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_playback_hw_params, .hw_free = snd_cs46xx_playback_hw_free, .prepare = snd_cs46xx_playback_prepare, .trigger = snd_cs46xx_playback_trigger, .pointer = snd_cs46xx_playback_indirect_pointer, .ack = snd_cs46xx_playback_transfer,};static snd_pcm_ops_t snd_cs46xx_capture_ops = { .open = snd_cs46xx_capture_open, .close = snd_cs46xx_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_capture_hw_params, .hw_free = snd_cs46xx_capture_hw_free, .prepare = snd_cs46xx_capture_prepare, .trigger = snd_cs46xx_capture_trigger, .pointer = snd_cs46xx_capture_direct_pointer,};static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = { .open = snd_cs46xx_capture_open, .close = snd_cs46xx_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cs46xx_capture_hw_params, .hw_free = snd_cs46xx_capture_hw_free, .prepare = snd_cs46xx_capture_prepare, .trigger = snd_cs46xx_capture_trigger, .pointer = snd_cs46xx_capture_indirect_pointer, .ack = snd_cs46xx_capture_transfer,};static void snd_cs46xx_pcm_free(snd_pcm_t *pcm){ cs46xx_t *chip = pcm->private_data; chip->pcm = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm){ cs46xx_t *chip = pcm->private_data; chip->pcm_rear = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm){ cs46xx_t *chip = pcm->private_data; chip->pcm_center_lfe = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm){ cs46xx_t *chip = pcm->private_data; chip->pcm_iec958 = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}#define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)#else#define MAX_PLAYBACK_CHANNELS 1#endifint __devinit snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL; if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_cs46xx_pcm_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "CS46xx"); chip->pcm = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 256*1024); if (rpcm) *rpcm = pcm; return 0;}#ifdef CONFIG_SND_CS46XX_NEW_DSPint __devinit snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL; if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_cs46xx_pcm_rear_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "CS46xx - Rear"); chip->pcm_rear = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 256*1024); if (rpcm) *rpcm = pcm; return 0;}int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL; if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_cs46xx_pcm_center_lfe_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "CS46xx - Center LFE"); chip->pcm_center_lfe = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 256*1024); if (rpcm) *rpcm = pcm; return 0;}int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; if (rpcm) *rpcm = NULL; if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_cs46xx_pcm_iec958_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "CS46xx - IEC958"); chip->pcm_rear = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 256*1024); if (rpcm) *rpcm = pcm; return 0;}#endif/* * Mixer routines */static void snd_cs46xx_mixer_free_ac97_bus(ac97_bus_t *bus){ cs46xx_t *chip = bus->private_data; chip->ac97_bus = NULL;}static void snd_cs46xx_mixer_free_ac97(ac97_t *ac97){ cs46xx_t *chip = ac97->private_data; snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), return); if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; chip->eapd_switch = NULL; } else chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;}static int snd_cs46xx_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0x7fff; return 0;}static int snd_cs46xx_vol_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ cs46xx_t *chip = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value; unsigned int val = snd_cs46xx_peek(chip, reg); ucontrol->value.integer.value[0] = 0xffff - (val >> 16); ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); return 0;}static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ cs46xx_t *chip = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value; unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | (0xffff - ucontrol->value.integer.value[1])); unsigned int old = snd_cs46xx_peek(chip, reg); int change = (old != val); if (change) { snd_cs46xx_poke(chip, reg, val); } return change;}#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic int snd_cs46xx_vol_dac_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ cs46xx_t *chip = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; return 0;}static int snd_cs46xx_vol_dac_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ cs46xx_t *chip = snd_kcontrol_chip(kcontrol); int change = 0; if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { cs46xx_dsp_set_dac_volume(chip, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1]); change = 1; } return change;}#if 0static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ cs46xx_t *chip = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left; ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -