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

📄 rme96.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			}			snd_rme96_playback_stop(rme96);		}		break;	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:		if (RME96_ISPLAYING(rme96)) {			snd_rme96_playback_stop(rme96);		}		break;	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:		if (!RME96_ISPLAYING(rme96)) {			snd_rme96_playback_start(rme96, 1);		}		break;			default:		return -EINVAL;	}	return 0;}static intsnd_rme96_capture_trigger(struct snd_pcm_substream *substream, 			  int cmd){	struct rme96 *rme96 = snd_pcm_substream_chip(substream);	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:		if (!RME96_ISRECORDING(rme96)) {			if (substream != rme96->capture_substream) {				return -EBUSY;			}			snd_rme96_capture_start(rme96, 0);		}		break;	case SNDRV_PCM_TRIGGER_STOP:		if (RME96_ISRECORDING(rme96)) {			if (substream != rme96->capture_substream) {				return -EBUSY;			}			snd_rme96_capture_stop(rme96);		}		break;	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:		if (RME96_ISRECORDING(rme96)) {			snd_rme96_capture_stop(rme96);		}		break;	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:		if (!RME96_ISRECORDING(rme96)) {			snd_rme96_capture_start(rme96, 1);		}		break;			default:		return -EINVAL;	}	return 0;}static snd_pcm_uframes_tsnd_rme96_playback_pointer(struct snd_pcm_substream *substream){	struct rme96 *rme96 = snd_pcm_substream_chip(substream);	return snd_rme96_playback_ptr(rme96);}static snd_pcm_uframes_tsnd_rme96_capture_pointer(struct snd_pcm_substream *substream){	struct rme96 *rme96 = snd_pcm_substream_chip(substream);	return snd_rme96_capture_ptr(rme96);}static struct snd_pcm_ops snd_rme96_playback_spdif_ops = {	.open =		snd_rme96_playback_spdif_open,	.close =	snd_rme96_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_rme96_playback_hw_params,	.prepare =	snd_rme96_playback_prepare,	.trigger =	snd_rme96_playback_trigger,	.pointer =	snd_rme96_playback_pointer,	.copy =		snd_rme96_playback_copy,	.silence =	snd_rme96_playback_silence,	.mmap =		snd_pcm_lib_mmap_iomem,};static struct snd_pcm_ops snd_rme96_capture_spdif_ops = {	.open =		snd_rme96_capture_spdif_open,	.close =	snd_rme96_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_rme96_capture_hw_params,	.prepare =	snd_rme96_capture_prepare,	.trigger =	snd_rme96_capture_trigger,	.pointer =	snd_rme96_capture_pointer,	.copy =		snd_rme96_capture_copy,	.mmap =		snd_pcm_lib_mmap_iomem,};static struct snd_pcm_ops snd_rme96_playback_adat_ops = {	.open =		snd_rme96_playback_adat_open,	.close =	snd_rme96_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_rme96_playback_hw_params,	.prepare =	snd_rme96_playback_prepare,	.trigger =	snd_rme96_playback_trigger,	.pointer =	snd_rme96_playback_pointer,	.copy =		snd_rme96_playback_copy,	.silence =	snd_rme96_playback_silence,	.mmap =		snd_pcm_lib_mmap_iomem,};static struct snd_pcm_ops snd_rme96_capture_adat_ops = {	.open =		snd_rme96_capture_adat_open,	.close =	snd_rme96_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_rme96_capture_hw_params,	.prepare =	snd_rme96_capture_prepare,	.trigger =	snd_rme96_capture_trigger,	.pointer =	snd_rme96_capture_pointer,	.copy =		snd_rme96_capture_copy,	.mmap =		snd_pcm_lib_mmap_iomem,};static voidsnd_rme96_free(void *private_data){	struct rme96 *rme96 = (struct rme96 *)private_data;	if (rme96 == NULL) {	        return;	}	if (rme96->irq >= 0) {		snd_rme96_playback_stop(rme96);		snd_rme96_capture_stop(rme96);		rme96->areg &= ~RME96_AR_DAC_EN;		writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);		free_irq(rme96->irq, (void *)rme96);		rme96->irq = -1;	}	if (rme96->iobase) {		iounmap(rme96->iobase);		rme96->iobase = NULL;	}	if (rme96->port) {		pci_release_regions(rme96->pci);		rme96->port = 0;	}	pci_disable_device(rme96->pci);}static voidsnd_rme96_free_spdif_pcm(struct snd_pcm *pcm){	struct rme96 *rme96 = (struct rme96 *) pcm->private_data;	rme96->spdif_pcm = NULL;}static voidsnd_rme96_free_adat_pcm(struct snd_pcm *pcm){	struct rme96 *rme96 = (struct rme96 *) pcm->private_data;	rme96->adat_pcm = NULL;}static int __devinitsnd_rme96_create(struct rme96 *rme96){	struct pci_dev *pci = rme96->pci;	int err;	rme96->irq = -1;	spin_lock_init(&rme96->lock);	if ((err = pci_enable_device(pci)) < 0)		return err;	if ((err = pci_request_regions(pci, "RME96")) < 0)		return err;	rme96->port = pci_resource_start(rme96->pci, 0);	if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);		return -ENOMEM;	}	if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,			"RME96", rme96)) {		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);		return -EBUSY;	}	rme96->irq = pci->irq;	/* read the card's revision number */	pci_read_config_byte(pci, 8, &rme96->rev);			/* set up ALSA pcm device for S/PDIF */	if ((err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0,			       1, 1, &rme96->spdif_pcm)) < 0)	{		return err;	}	rme96->spdif_pcm->private_data = rme96;	rme96->spdif_pcm->private_free = snd_rme96_free_spdif_pcm;	strcpy(rme96->spdif_pcm->name, "Digi96 IEC958");	snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_spdif_ops);	snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_spdif_ops);	rme96->spdif_pcm->info_flags = 0;	/* set up ALSA pcm device for ADAT */	if (pci->device == PCI_DEVICE_ID_RME_DIGI96) {		/* ADAT is not available on the base model */		rme96->adat_pcm = NULL;	} else {		if ((err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1,				       1, 1, &rme96->adat_pcm)) < 0)		{			return err;		}				rme96->adat_pcm->private_data = rme96;		rme96->adat_pcm->private_free = snd_rme96_free_adat_pcm;		strcpy(rme96->adat_pcm->name, "Digi96 ADAT");		snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_adat_ops);		snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops);				rme96->adat_pcm->info_flags = 0;	}	rme96->playback_periodsize = 0;	rme96->capture_periodsize = 0;		/* make sure playback/capture is stopped, if by some reason active */	snd_rme96_playback_stop(rme96);	snd_rme96_capture_stop(rme96);		/* set default values in registers */	rme96->wcreg =		RME96_WCR_FREQ_1 | /* set 44.1 kHz playback */		RME96_WCR_SEL |    /* normal playback */		RME96_WCR_MASTER | /* set to master clock mode */		RME96_WCR_INP_0;   /* set coaxial input */	rme96->areg = RME96_AR_FREQPAD_1; /* set 44.1 kHz analog capture */	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);	writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);		/* reset the ADC */	writel(rme96->areg | RME96_AR_PD2,	       rme96->iobase + RME96_IO_ADDITIONAL_REG);	writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);		/* reset and enable the DAC (order is important). */	snd_rme96_reset_dac(rme96);	rme96->areg |= RME96_AR_DAC_EN;	writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);	/* reset playback and record buffer pointers */	writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);	writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);	/* reset volume */	rme96->vol[0] = rme96->vol[1] = 0;	if (RME96_HAS_ANALOG_OUT(rme96)) {		snd_rme96_apply_dac_volume(rme96);	}		/* init switch interface */	if ((err = snd_rme96_create_switches(rme96->card, rme96)) < 0) {		return err;	}        /* init proc interface */	snd_rme96_proc_init(rme96);		return 0;}/* * proc interface */static void snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer){	int n;	struct rme96 *rme96 = (struct rme96 *)entry->private_data;		rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);	snd_iprintf(buffer, rme96->card->longname);	snd_iprintf(buffer, " (index #%d)\n", rme96->card->number + 1);	snd_iprintf(buffer, "\nGeneral settings\n");	if (rme96->wcreg & RME96_WCR_IDIS) {		snd_iprintf(buffer, "  period size: N/A (interrupts "			    "disabled)\n");	} else if (rme96->wcreg & RME96_WCR_ISEL) {		snd_iprintf(buffer, "  period size: 2048 bytes\n");	} else {		snd_iprintf(buffer, "  period size: 8192 bytes\n");	}		snd_iprintf(buffer, "\nInput settings\n");	switch (snd_rme96_getinputtype(rme96)) {	case RME96_INPUT_OPTICAL:		snd_iprintf(buffer, "  input: optical");		break;	case RME96_INPUT_COAXIAL:		snd_iprintf(buffer, "  input: coaxial");		break;	case RME96_INPUT_INTERNAL:		snd_iprintf(buffer, "  input: internal");		break;	case RME96_INPUT_XLR:		snd_iprintf(buffer, "  input: XLR");		break;	case RME96_INPUT_ANALOG:		snd_iprintf(buffer, "  input: analog");		break;	}	if (snd_rme96_capture_getrate(rme96, &n) < 0) {		snd_iprintf(buffer, "\n  sample rate: no valid signal\n");	} else {		if (n) {			snd_iprintf(buffer, " (8 channels)\n");		} else {			snd_iprintf(buffer, " (2 channels)\n");		}		snd_iprintf(buffer, "  sample rate: %d Hz\n",			    snd_rme96_capture_getrate(rme96, &n));	}	if (rme96->wcreg & RME96_WCR_MODE24_2) {		snd_iprintf(buffer, "  sample format: 24 bit\n");	} else {		snd_iprintf(buffer, "  sample format: 16 bit\n");	}		snd_iprintf(buffer, "\nOutput settings\n");	if (rme96->wcreg & RME96_WCR_SEL) {		snd_iprintf(buffer, "  output signal: normal playback\n");	} else {		snd_iprintf(buffer, "  output signal: same as input\n");	}	snd_iprintf(buffer, "  sample rate: %d Hz\n",		    snd_rme96_playback_getrate(rme96));	if (rme96->wcreg & RME96_WCR_MODE24) {		snd_iprintf(buffer, "  sample format: 24 bit\n");	} else {		snd_iprintf(buffer, "  sample format: 16 bit\n");	}	if (rme96->areg & RME96_AR_WSEL) {		snd_iprintf(buffer, "  sample clock source: word clock\n");	} else if (rme96->wcreg & RME96_WCR_MASTER) {		snd_iprintf(buffer, "  sample clock source: internal\n");	} else if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {		snd_iprintf(buffer, "  sample clock source: autosync (internal anyway due to analog input setting)\n");	} else if (snd_rme96_capture_getrate(rme96, &n) < 0) {		snd_iprintf(buffer, "  sample clock source: autosync (internal anyway due to no valid signal)\n");	} else {		snd_iprintf(buffer, "  sample clock source: autosync\n");	}	if (rme96->wcreg & RME96_WCR_PRO) {		snd_iprintf(buffer, "  format: AES/EBU (professional)\n");	} else {		snd_iprintf(buffer, "  format: IEC958 (consumer)\n");	}	if (rme96->wcreg & RME96_WCR_EMP) {		snd_iprintf(buffer, "  emphasis: on\n");	} else {		snd_iprintf(buffer, "  emphasis: off\n");	}	if (rme96->wcreg & RME96_WCR_DOLBY) {		snd_iprintf(buffer, "  non-audio (dolby): on\n");	} else {		snd_iprintf(buffer, "  non-audio (dolby): off\n");	}	if (RME96_HAS_ANALOG_IN(rme96)) {		snd_iprintf(buffer, "\nAnalog output settings\n");		switch (snd_rme96_getmontracks(rme96)) {		case RME96_MONITOR_TRACKS_1_2:			snd_iprintf(buffer, "  monitored ADAT tracks: 1+2\n");			break;		case RME96_MONITOR_TRACKS_3_4:			snd_iprintf(buffer, "  monitored ADAT tracks: 3+4\n");			break;		case RME96_MONITOR_TRACKS_5_6:			snd_iprintf(buffer, "  monitored ADAT tracks: 5+6\n");			break;		case RME96_MONITOR_TRACKS_7_8:			snd_iprintf(buffer, "  monitored ADAT tracks: 7+8\n");			break;		}		switch (snd_rme96_getattenuation(rme96)) {		case RME96_ATTENUATION_0:			snd_iprintf(buffer, "  attenuation: 0 dB\n");			break;		case RME96_ATTENUATION_6:			snd_iprintf(buffer, "  attenuation: -6 dB\n");			break;		case RME96_ATTENUATION_12:			snd_iprintf(buffer, "  attenuation: -12 dB\n");			break;		case RME96_ATTENUATION_18:			snd_iprintf(buffer, "  attenuation: -18 dB\n");			break;		}		snd_iprintf(buffer, "  volume left: %u\n", rme96->vol[0]);		snd_iprintf(buffer, "  volume right: %u\n", rme96->vol[1]);	}}static void __devinit snd_rme96_proc_init(struct rme96 *rme96){	struct snd_info_entry *entry;	if (! snd_card_proc_new(rme96->card, "rme96", &entry))		snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read);}/* * control interface */#define snd_rme96_info_loopback_control		snd_ctl_boolean_mono_infostatic intsnd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme96->lock);	ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;	spin_unlock_irq(&rme96->lock);	return 0;}static intsnd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;		val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL;	spin_lock_irq(&rme96->lock);	val = (rme96->wcreg & ~RME96_WCR_SEL) | val;	change = val != rme96->wcreg;	rme96->wcreg = val;	writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);	spin_unlock_irq(&rme96->lock);

⌨️ 快捷键说明

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