📄 ymfpci_main.c
字号:
snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) return err; ypcm = runtime->private_data; ypcm->output_front = 0; ypcm->output_rear = 1; spin_lock_irq(&chip->reg_lock); snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL, snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2); ymfpci_open_extension(chip); chip->spdif_pcm_bits = chip->spdif_bits; snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits); chip->spdif_opened++; spin_unlock_irq(&chip->reg_lock); chip->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id); return 0;}static int snd_ymfpci_playback_4ch_open(snd_pcm_substream_t * substream){ ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) return err; ypcm = runtime->private_data; ypcm->output_front = 0; ypcm->output_rear = 1; spin_lock_irq(&chip->reg_lock); ymfpci_open_extension(chip); chip->rear_opened++; spin_unlock_irq(&chip->reg_lock); return 0;}static int snd_ymfpci_capture_open(snd_pcm_substream_t * substream, u32 capture_bank_number){ ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); if (ypcm == NULL) return -ENOMEM; ypcm->chip = chip; ypcm->type = capture_bank_number + CAPTURE_REC; ypcm->substream = substream; ypcm->capture_bank_number = capture_bank_number; chip->capture_substream[capture_bank_number] = substream; runtime->hw = snd_ymfpci_capture; /* FIXME? True value is 256/48 = 5.33333 ms */ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX); runtime->private_data = ypcm; runtime->private_free = snd_ymfpci_pcm_free_substream; snd_ymfpci_hw_start(chip); return 0;}static int snd_ymfpci_capture_rec_open(snd_pcm_substream_t * substream){ return snd_ymfpci_capture_open(substream, 0);}static int snd_ymfpci_capture_ac97_open(snd_pcm_substream_t * substream){ return snd_ymfpci_capture_open(substream, 1);}static int snd_ymfpci_playback_close_1(snd_pcm_substream_t * substream){ return 0;}static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream){ ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_pcm_t *ypcm = substream->runtime->private_data; snd_kcontrol_t *kctl; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear && chip->rear_opened > 0) { chip->rear_opened--; ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return snd_ymfpci_playback_close_1(substream);}static int snd_ymfpci_playback_spdif_close(snd_pcm_substream_t * substream){ ymfpci_t *chip = snd_pcm_substream_chip(substream); spin_lock_irq(&chip->reg_lock); chip->spdif_opened = 0; ymfpci_close_extension(chip); snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL, snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & ~2); snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits); spin_unlock_irq(&chip->reg_lock); chip->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id); return snd_ymfpci_playback_close_1(substream);}static int snd_ymfpci_playback_4ch_close(snd_pcm_substream_t * substream){ ymfpci_t *chip = snd_pcm_substream_chip(substream); spin_lock_irq(&chip->reg_lock); if (chip->rear_opened > 0) { chip->rear_opened--; ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); return snd_ymfpci_playback_close_1(substream);}static int snd_ymfpci_capture_close(snd_pcm_substream_t * substream){ ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm = runtime->private_data; if (ypcm != NULL) { chip->capture_substream[ypcm->capture_bank_number] = NULL; snd_ymfpci_hw_stop(chip); } return 0;}static snd_pcm_ops_t snd_ymfpci_playback_ops = { .open = snd_ymfpci_playback_open, .close = snd_ymfpci_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ymfpci_playback_hw_params, .hw_free = snd_ymfpci_playback_hw_free, .prepare = snd_ymfpci_playback_prepare, .trigger = snd_ymfpci_playback_trigger, .pointer = snd_ymfpci_playback_pointer,};static snd_pcm_ops_t snd_ymfpci_capture_rec_ops = { .open = snd_ymfpci_capture_rec_open, .close = snd_ymfpci_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ymfpci_capture_hw_params, .hw_free = snd_ymfpci_capture_hw_free, .prepare = snd_ymfpci_capture_prepare, .trigger = snd_ymfpci_capture_trigger, .pointer = snd_ymfpci_capture_pointer,};static void snd_ymfpci_pcm_free(snd_pcm_t *pcm){ ymfpci_t *chip = pcm->private_data; chip->pcm = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}int __devinit snd_ymfpci_pcm(ymfpci_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, "YMFPCI", device, 32, 1, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_ymfpci_pcm_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_rec_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "YMFPCI"); 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;}static snd_pcm_ops_t snd_ymfpci_capture_ac97_ops = { .open = snd_ymfpci_capture_ac97_open, .close = snd_ymfpci_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ymfpci_capture_hw_params, .hw_free = snd_ymfpci_capture_hw_free, .prepare = snd_ymfpci_capture_prepare, .trigger = snd_ymfpci_capture_trigger, .pointer = snd_ymfpci_capture_pointer,};static void snd_ymfpci_pcm2_free(snd_pcm_t *pcm){ ymfpci_t *chip = pcm->private_data; chip->pcm2 = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}int __devinit snd_ymfpci_pcm2(ymfpci_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, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_ymfpci_pcm2_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_ac97_ops); /* global setup */ pcm->info_flags = 0; sprintf(pcm->name, "YMFPCI - %s", chip->device_id == PCI_DEVICE_ID_YAMAHA_754 ? "Direct Recording" : "AC'97"); chip->pcm2 = 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;}static snd_pcm_ops_t snd_ymfpci_playback_spdif_ops = { .open = snd_ymfpci_playback_spdif_open, .close = snd_ymfpci_playback_spdif_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ymfpci_playback_hw_params, .hw_free = snd_ymfpci_playback_hw_free, .prepare = snd_ymfpci_playback_prepare, .trigger = snd_ymfpci_playback_trigger, .pointer = snd_ymfpci_playback_pointer,};static void snd_ymfpci_pcm_spdif_free(snd_pcm_t *pcm){ ymfpci_t *chip = pcm->private_data; chip->pcm_spdif = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}int __devinit snd_ymfpci_pcm_spdif(ymfpci_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, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_ymfpci_pcm_spdif_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_spdif_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "YMFPCI - IEC958"); chip->pcm_spdif = 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;}static snd_pcm_ops_t snd_ymfpci_playback_4ch_ops = { .open = snd_ymfpci_playback_4ch_open, .close = snd_ymfpci_playback_4ch_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ymfpci_playback_hw_params, .hw_free = snd_ymfpci_playback_hw_free, .prepare = snd_ymfpci_playback_prepare, .trigger = snd_ymfpci_playback_trigger, .pointer = snd_ymfpci_playback_pointer,};static void snd_ymfpci_pcm_4ch_free(snd_pcm_t *pcm){ ymfpci_t *chip = pcm->private_data; chip->pcm_4ch = NULL; snd_pcm_lib_preallocate_free_for_all(pcm);}int __devinit snd_ymfpci_pcm_4ch(ymfpci_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, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0) return err; pcm->private_data = chip; pcm->private_free = snd_ymfpci_pcm_4ch_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_4ch_ops); /* global setup */ pcm->info_flags = 0; strcpy(pcm->name, "YMFPCI - Rear PCM"); chip->pcm_4ch = 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;}static int snd_ymfpci_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_ymfpci_spdif_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ymfpci_t *chip = snd_kcontrol_chip(kcontrol); spin_lock_irq(&chip->reg_lock); ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff; spin_unlock_irq(&chip->reg_lock); return 0;}static int snd_ymfpci_spdif_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int val; int change; val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) | (ucontrol->value.iec958.status[1] << 8); spin_lock_irq(&chip->reg_lock); change = chip->spdif_bits != val; chip->spdif_bits = val; if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 1) && chip->pcm_spdif == NULL) snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits); spin_unlock_irq(&chip->reg_lock); return change;}static snd_kcontrol_new_t snd_ymfpci_spdif_default __devinitdata ={ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .info = snd_ymfpci_spdif_default_info, .get = snd_ymfpci_spdif_default_get, .put = snd_ymfpci_spdif_default_put};static int snd_ymfpci_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_ymfpci_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ymfpci_t *chip = snd_kcontrol_chip(kcontrol); spin_lock_irq(&chip->reg_lock); ucontrol->value.iec958.status[0] = 0x3e; ucontrol->value.iec958.status[1] = 0xff; spin_unlock_irq(&chip->reg_lock); return 0;}static snd_kcontrol_new_t snd_ymfpci_spdif_mask __devinitdata ={ .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_ymfpci_spdif_mask_info, .get = snd_ymfpci_spdif_mask_get,};static int snd_ymfpci_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_ymfpci_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ymfpci_t *chip = snd_kcontrol_chip(kcontrol); spin_lock_irq(&chip->reg_lock); ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff; spin_unlock_irq(&chip->reg_lock); return 0;}static int snd_ymfpci_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int val; int change; val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) | (ucontrol->value.iec958.status[1] << 8); spin_lock_irq(&chip->reg_lock); change = chip->spdif_pcm_bits != val; chip->spdif_pcm_bits = val; if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 2)) snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits); spin_unlock_irq(&chip->reg_lock); return change;}static snd_kcontrol_new_t snd_ymfpci_spdif_stream __devinitdata ={ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), .info = snd_ymfpci_spdif_stream_info, .get = snd_ymfpci_spdif_stream_get,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -