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

📄 ymfpci_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -