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

📄 rme96.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:		if (!RME96_ISPLAYING(rme96)) {			if (substream != rme96->playback_substream) {				return -EBUSY;			}			snd_rme96_playback_start(rme96, 0);		}		break;	case SNDRV_PCM_TRIGGER_STOP:		if (RME96_ISPLAYING(rme96)) {			if (substream != rme96->playback_substream) {				return -EBUSY;			}			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(snd_pcm_substream_t *substream, 			  int cmd){	rme96_t *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(snd_pcm_substream_t *substream){	rme96_t *rme96 = snd_pcm_substream_chip(substream);	return snd_rme96_playback_ptr(rme96);}static snd_pcm_uframes_tsnd_rme96_capture_pointer(snd_pcm_substream_t *substream){	rme96_t *rme96 = snd_pcm_substream_chip(substream);	return snd_rme96_capture_ptr(rme96);}static snd_pcm_ops_t 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 snd_pcm_ops_t 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 snd_pcm_ops_t 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 snd_pcm_ops_t 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){	rme96_t *rme96 = (rme96_t *)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((void *)rme96->iobase);		rme96->iobase = 0;	}	if (rme96->port) {		pci_release_regions(rme96->pci);		rme96->port = 0;	}}static voidsnd_rme96_free_spdif_pcm(snd_pcm_t *pcm){	rme96_t *rme96 = (rme96_t *) pcm->private_data;	rme96->spdif_pcm = NULL;}static voidsnd_rme96_free_adat_pcm(snd_pcm_t *pcm){	rme96_t *rme96 = (rme96_t *) pcm->private_data;	rme96->adat_pcm = NULL;}static int __devinitsnd_rme96_create(rme96_t *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 (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {		snd_printk("unable to grab IRQ %d\n", pci->irq);		return -EBUSY;	}	rme96->irq = pci->irq;	if ((rme96->iobase = (unsigned long) ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {		snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);		return -ENOMEM;	}	/* 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_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(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	int n;	rme96_t *rme96 = (rme96_t *)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(rme96_t *rme96){	snd_info_entry_t *entry;	if (! snd_card_proc_new(rme96->card, "rme96", &entry))		snd_info_set_text_ops(entry, rme96, 1024, snd_rme96_proc_read);}/* * control interface */static intsnd_rme96_info_loopback_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}static intsnd_rme96_get_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme96_t *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);

⌨️ 快捷键说明

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