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

📄 cmipci.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);	snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);	spin_unlock(&cm->reg_lock);	if (cm->rmidi && (status & CM_UARTINT))		snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data, regs);	if (cm->pcm) {		if ((status & CM_CHINT0) && cm->channel[0].running)			snd_pcm_period_elapsed(cm->channel[0].substream);		if ((status & CM_CHINT1) && cm->channel[1].running)			snd_pcm_period_elapsed(cm->channel[1].substream);	}	return IRQ_HANDLED;}/* * h/w infos *//* playback on channel A */static snd_pcm_hardware_t snd_cmipci_playback ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,	.rate_min =		5512,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* capture on channel B */static snd_pcm_hardware_t snd_cmipci_capture ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,	.rate_min =		5512,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* playback on channel B - stereo 16bit only? */static snd_pcm_hardware_t snd_cmipci_playback2 ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,	.rate_min =		5512,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* spdif playback on channel A */static snd_pcm_hardware_t snd_cmipci_playback_spdif ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,	.rate_min =		44100,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* spdif playback on channel A (32bit, IEC958 subframes) */static snd_pcm_hardware_t snd_cmipci_playback_iec958_subframe ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,	.rate_min =		44100,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* spdif capture on channel B */static snd_pcm_hardware_t snd_cmipci_capture_spdif ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =	        SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,	.rate_min =		44100,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		2,	.periods_max =		1024,	.fifo_size =		0,};/* * check device open/close */static int open_device_check(cmipci_t *cm, int mode, snd_pcm_substream_t *subs){	int ch = mode & CM_OPEN_CH_MASK;	/* FIXME: a file should wait until the device becomes free	 * when it's opened on blocking mode.  however, since the current	 * pcm framework doesn't pass file pointer before actually opened,	 * we can't know whether blocking mode or not in open callback..	 */	down(&cm->open_mutex);	if (cm->opened[ch]) {		up(&cm->open_mutex);		return -EBUSY;	}	cm->opened[ch] = mode;	cm->channel[ch].substream = subs;	if (! (mode & CM_OPEN_DAC)) {		/* disable dual DAC mode */		cm->channel[ch].is_dac = 0;		spin_lock_irq(&cm->reg_lock);		snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);		spin_unlock_irq(&cm->reg_lock);	}	up(&cm->open_mutex);	return 0;}static void close_device_check(cmipci_t *cm, int mode){	int ch = mode & CM_OPEN_CH_MASK;	down(&cm->open_mutex);	if (cm->opened[ch] == mode) {		if (cm->channel[ch].substream) {			snd_cmipci_ch_reset(cm, ch);			cm->channel[ch].running = 0;			cm->channel[ch].substream = NULL;		}		cm->opened[ch] = 0;		if (! cm->channel[ch].is_dac) {			/* enable dual DAC mode again */			cm->channel[ch].is_dac = 1;			spin_lock_irq(&cm->reg_lock);			snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);			spin_unlock_irq(&cm->reg_lock);		}	}	up(&cm->open_mutex);}/* */static int snd_cmipci_playback_open(snd_pcm_substream_t *substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	int err;	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)		return err;	runtime->hw = snd_cmipci_playback;	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);	cm->dig_pcm_status = cm->dig_status;	return 0;}static int snd_cmipci_capture_open(snd_pcm_substream_t *substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	int err;	if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)		return err;	runtime->hw = snd_cmipci_capture;	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);	return 0;}static int snd_cmipci_playback2_open(snd_pcm_substream_t *substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	int err;	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */		return err;	runtime->hw = snd_cmipci_playback2;	down(&cm->open_mutex);	if (! cm->opened[CM_CH_PLAY]) {		if (cm->can_multi_ch) {			runtime->hw.channels_max = cm->max_channels;			if (cm->max_channels == 4)				snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);			else				snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);		}		snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);	}	up(&cm->open_mutex);	return 0;}static int snd_cmipci_playback_spdif_open(snd_pcm_substream_t *substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	int err;	if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */		return err;	if (cm->can_ac3_hw) {		runtime->hw = snd_cmipci_playback_spdif;		if (cm->chip_version >= 37)			runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;	} else {		runtime->hw = snd_cmipci_playback_iec958_subframe;	}	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);	cm->dig_pcm_status = cm->dig_status;	return 0;}static int snd_cmipci_capture_spdif_open(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	int err;	if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */		return err;	runtime->hw = snd_cmipci_capture_spdif;	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);	return 0;}/* */static int snd_cmipci_playback_close(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	close_device_check(cm, CM_OPEN_PLAYBACK);	return 0;}static int snd_cmipci_capture_close(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	close_device_check(cm, CM_OPEN_CAPTURE);	return 0;}static int snd_cmipci_playback2_close(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	close_device_check(cm, CM_OPEN_PLAYBACK2);	close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);	return 0;}static int snd_cmipci_playback_spdif_close(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	close_device_check(cm, CM_OPEN_SPDIF_PLAYBACK);	return 0;}static int snd_cmipci_capture_spdif_close(snd_pcm_substream_t * substream){	cmipci_t *cm = snd_pcm_substream_chip(substream);	close_device_check(cm, CM_OPEN_SPDIF_CAPTURE);	return 0;}/* */static snd_pcm_ops_t snd_cmipci_playback_ops = {	.open =		snd_cmipci_playback_open,	.close =	snd_cmipci_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_cmipci_hw_params,	.hw_free =	snd_cmipci_playback_hw_free,	.prepare =	snd_cmipci_playback_prepare,	.trigger =	snd_cmipci_playback_trigger,	.pointer =	snd_cmipci_playback_pointer,};static snd_pcm_ops_t snd_cmipci_capture_ops = {	.open =		snd_cmipci_capture_open,	.close =	snd_cmipci_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_cmipci_hw_params,	.hw_free =	snd_cmipci_hw_free,	.prepare =	snd_cmipci_capture_prepare,	.trigger =	snd_cmipci_capture_trigger,	.pointer =	snd_cmipci_capture_pointer,};static snd_pcm_ops_t snd_cmipci_playback2_ops = {	.open =		snd_cmipci_playback2_open,	.close =	snd_cmipci_playback2_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_cmipci_playback2_hw_params,	.hw_free =	snd_cmipci_hw_free,	.prepare =	snd_cmipci_capture_prepare,	/* channel B */	.trigger =	snd_cmipci_capture_trigger,	/* channel B */	.pointer =	snd_cmipci_capture_pointer,	/* channel B */};static snd_pcm_ops_t snd_cmipci_playback_spdif_ops = {	.open =		snd_cmipci_playback_spdif_open,	.close =	snd_cmipci_playback_spdif_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_cmipci_hw_params,	.hw_free =	snd_cmipci_playback_hw_free,	.prepare =	snd_cmipci_playback_spdif_prepare,	/* set up rate */	.trigger =	snd_cmipci_playback_trigger,	.pointer =	snd_cmipci_playback_pointer,};static snd_pcm_ops_t snd_cmipci_capture_spdif_ops = {	.open =		snd_cmipci_capture_spdif_open,	.close =	snd_cmipci_capture_spdif_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_cmipci_hw_params,	.hw_free =	snd_cmipci_capture_spdif_hw_free,	.prepare =	snd_cmipci_capture_spdif_prepare,	.trigger =	snd_cmipci_capture_trigger,	.pointer =	snd_cmipci_capture_pointer,};/* */static void snd_cmipci_pcm_free(snd_pcm_t *pcm){	snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_cmipci_pcm_new(cmipci_t *cm, int device){	snd_pcm_t *pcm;	int err;	err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);	if (err < 0)		return err;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_ops);	pcm->private_data = cm;	pcm->private_free = snd_cmipci_pcm_free;	pcm->info_flags = 0;	strcpy(pcm->name, "C-Media PCI DAC/ADC");	cm->pcm = pcm;	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(cm->pci), 64*1024, 128*1024);	return 0;}static int __devinit snd_cmipci_pcm2_new(cmipci_t *cm, int device){	snd_pcm_t *pcm;	int err;	err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 0, &pcm);	if (err < 0)		return err;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback2_ops);	pcm->private_data = cm;	pcm->private_free = snd_cmipci_pcm_free;	pcm->info_flags = 0;	strcpy(pcm->name, "C-Media PCI 2nd DAC");	cm->pcm2 = pcm;	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(cm->pci), 64*1024, 128*1024);	return 0;}

⌨️ 快捷键说明

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