⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ymfpci_main.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 5 页
字号:
	}}static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_ymfpci_pcm *ypcm;	struct snd_kcontrol *kctl;	int err;		if ((err = snd_ymfpci_playback_open_1(substream)) < 0)		return err;	ypcm = runtime->private_data;	ypcm->output_front = 1;	ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;	spin_lock_irq(&chip->reg_lock);	if (ypcm->output_rear) {		ymfpci_open_extension(chip);		chip->rear_opened++;	}	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 0;}static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_ymfpci_pcm *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(struct snd_pcm_substream *substream){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_ymfpci_pcm *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(struct snd_pcm_substream *substream,				   u32 capture_bank_number){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_ymfpci_pcm *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(struct snd_pcm_substream *substream){	return snd_ymfpci_capture_open(substream, 0);}static int snd_ymfpci_capture_ac97_open(struct snd_pcm_substream *substream){	return snd_ymfpci_capture_open(substream, 1);}static int snd_ymfpci_playback_close_1(struct snd_pcm_substream *substream){	return 0;}static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;	struct snd_kcontrol *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(struct snd_pcm_substream *substream){	struct snd_ymfpci *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(struct snd_pcm_substream *substream){	struct snd_ymfpci *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(struct snd_pcm_substream *substream){	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_ymfpci_pcm *ypcm = runtime->private_data;	if (ypcm != NULL) {		chip->capture_substream[ypcm->capture_bank_number] = NULL;		snd_ymfpci_hw_stop(chip);	}	return 0;}static struct snd_pcm_ops 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 struct snd_pcm_ops 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,};int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm){	struct snd_pcm *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;	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 struct snd_pcm_ops 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,};int __devinit snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm){	struct snd_pcm *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;	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 struct snd_pcm_ops 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,};int __devinit snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm){	struct snd_pcm *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;	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 struct snd_pcm_ops 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,};int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm){	struct snd_pcm *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;	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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_ymfpci_spdif_default_get(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_ymfpci *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;	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;	spin_unlock_irq(&chip->reg_lock);	return 0;}static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,					 struct snd_ctl_elem_value *ucontrol){	struct snd_ymfpci *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 struct snd_kcontrol_new 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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,				      struct snd_ctl_elem_value *ucontrol){	struct snd_ymfpci *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 struct snd_kcontrol_new 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(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_ymfpci_spdif_stream_get(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_ymfpci *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;	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;	spin_unlock_irq(&chip->reg_lock);	return 0;}static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;	val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |	      (ucontrol->value.iec958.status[1] << 8);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -