cs46xx_lib.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,248 行 · 第 1/5 页

C
2,248
字号
	.info =			(SNDRV_PCM_INFO_MMAP |				 SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_RESUME),	.formats =		SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		5500,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	(256 * 1024),	.period_bytes_min =	CS46XX_MIN_PERIOD_SIZE,	.period_bytes_max =	CS46XX_MAX_PERIOD_SIZE,	.periods_min =		CS46XX_FRAGS,	.periods_max =		1024,	.fifo_size =		0,};#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };#define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0])static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {	.count = PERIOD_SIZES,	.list = period_sizes,	.mask = 0};#endifstatic void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime){	cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return);		if (cpcm)		snd_magic_kfree(cpcm);}static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id){	cs46xx_t *chip = snd_pcm_substream_chip(substream);	cs46xx_pcm_t * cpcm;	snd_pcm_runtime_t *runtime = substream->runtime;	cpcm = snd_magic_kcalloc(cs46xx_pcm_t, 0, GFP_KERNEL);	if (cpcm == NULL)		return -ENOMEM;	if (snd_dma_alloc_pages(&chip->dma_dev, PAGE_SIZE, &cpcm->hw_buf) < 0) {		snd_magic_kfree(cpcm);		return -ENOMEM;	}	runtime->hw = snd_cs46xx_playback;	runtime->private_data = cpcm;	runtime->private_free = snd_cs46xx_pcm_free_substream;	cpcm->substream = substream;#ifdef CONFIG_SND_CS46XX_NEW_DSP	down (&chip->spos_mutex);	cpcm->pcm_channel = NULL; 	cpcm->pcm_channel_id = pcm_channel_id;	snd_pcm_hw_constraint_list(runtime, 0,				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 				   &hw_constraints_period_sizes);	up (&chip->spos_mutex);#else	chip->playback_pcm = cpcm; /* HACK */#endif	if (chip->accept_valid)		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;	chip->active_ctrl(chip, 1);	return 0;}static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream){	snd_printdd("open front channel\n");	return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);}#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic int snd_cs46xx_playback_open_rear(snd_pcm_substream_t * substream){	snd_printdd("open rear channel\n");	return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);}static int snd_cs46xx_playback_open_clfe(snd_pcm_substream_t * substream){	snd_printdd("open center - LFE channel\n");	return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);}static int snd_cs46xx_playback_open_iec958(snd_pcm_substream_t * substream){	cs46xx_t *chip = snd_pcm_substream_chip(substream);	snd_printdd("open raw iec958 channel\n");	down (&chip->spos_mutex);	cs46xx_iec958_pre_open (chip);	up (&chip->spos_mutex);	return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);}static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream);static int snd_cs46xx_playback_close_iec958(snd_pcm_substream_t * substream){	int err;	cs46xx_t *chip = snd_pcm_substream_chip(substream);  	snd_printdd("close raw iec958 channel\n");	err = snd_cs46xx_playback_close(substream);	down (&chip->spos_mutex);	cs46xx_iec958_post_close (chip);	up (&chip->spos_mutex);	return err;}#endifstatic int snd_cs46xx_capture_open(snd_pcm_substream_t * substream){	cs46xx_t *chip = snd_pcm_substream_chip(substream);	if (snd_dma_alloc_pages(&chip->dma_dev, PAGE_SIZE, &chip->capt.hw_buf) < 0)		return -ENOMEM;	chip->capt.substream = substream;	substream->runtime->hw = snd_cs46xx_capture;	if (chip->accept_valid)		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;	chip->active_ctrl(chip, 1);#ifdef CONFIG_SND_CS46XX_NEW_DSP	snd_pcm_hw_constraint_list(substream->runtime, 0,				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 				   &hw_constraints_period_sizes);#endif	return 0;}static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream){	cs46xx_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	cs46xx_pcm_t * cpcm;	cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);	/* when playback_open fails, then cpcm can be NULL */	if (!cpcm) return -ENXIO;#ifdef CONFIG_SND_CS46XX_NEW_DSP	down (&chip->spos_mutex);	if (cpcm->pcm_channel) {		cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);		cpcm->pcm_channel = NULL;	}	up (&chip->spos_mutex);#else	chip->playback_pcm = NULL;#endif	cpcm->substream = NULL;	snd_dma_free_pages(&chip->dma_dev, &cpcm->hw_buf);	chip->active_ctrl(chip, -1);	return 0;}static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream){	cs46xx_t *chip = snd_pcm_substream_chip(substream);	chip->capt.substream = NULL;	snd_dma_free_pages(&chip->dma_dev, &chip->capt.hw_buf);	chip->active_ctrl(chip, -1);	return 0;}#ifdef CONFIG_SND_CS46XX_NEW_DSPsnd_pcm_ops_t snd_cs46xx_playback_rear_ops = {	.open =			snd_cs46xx_playback_open_rear,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_direct_pointer,};snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {	.open =			snd_cs46xx_playback_open_rear,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_indirect_pointer,	.ack =			snd_cs46xx_playback_transfer,};snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {	.open =			snd_cs46xx_playback_open_clfe,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_direct_pointer,};snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {	.open =			snd_cs46xx_playback_open_clfe,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_indirect_pointer,	.ack =			snd_cs46xx_playback_transfer,};snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {	.open =			snd_cs46xx_playback_open_iec958,	.close =		snd_cs46xx_playback_close_iec958,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_direct_pointer,};snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {	.open =			snd_cs46xx_playback_open_iec958,	.close =		snd_cs46xx_playback_close_iec958,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_indirect_pointer,	.ack =			snd_cs46xx_playback_transfer,};#endifsnd_pcm_ops_t snd_cs46xx_playback_ops = {	.open =			snd_cs46xx_playback_open,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_direct_pointer,};snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {	.open =			snd_cs46xx_playback_open,	.close =		snd_cs46xx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_playback_hw_params,	.hw_free =		snd_cs46xx_playback_hw_free,	.prepare =		snd_cs46xx_playback_prepare,	.trigger =		snd_cs46xx_playback_trigger,	.pointer =		snd_cs46xx_playback_indirect_pointer,	.ack =			snd_cs46xx_playback_transfer,};snd_pcm_ops_t snd_cs46xx_capture_ops = {	.open =			snd_cs46xx_capture_open,	.close =		snd_cs46xx_capture_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_capture_hw_params,	.hw_free =		snd_cs46xx_capture_hw_free,	.prepare =		snd_cs46xx_capture_prepare,	.trigger =		snd_cs46xx_capture_trigger,	.pointer =		snd_cs46xx_capture_direct_pointer,};snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {	.open =			snd_cs46xx_capture_open,	.close =		snd_cs46xx_capture_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_cs46xx_capture_hw_params,	.hw_free =		snd_cs46xx_capture_hw_free,	.prepare =		snd_cs46xx_capture_prepare,	.trigger =		snd_cs46xx_capture_trigger,	.pointer =		snd_cs46xx_capture_indirect_pointer,	.ack =			snd_cs46xx_capture_transfer,};static void snd_cs46xx_pcm_free(snd_pcm_t *pcm){	cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return);	chip->pcm = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}#ifdef CONFIG_SND_CS46XX_NEW_DSPstatic void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm){	cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return);	chip->pcm_rear = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm){	cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return);	chip->pcm_center_lfe = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm){	cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return);	chip->pcm_iec958 = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}#define MAX_PLAYBACK_CHANNELS	(DSP_MAX_PCM_CHANNELS - 1)#else#define MAX_PLAYBACK_CHANNELS	1#endifint __devinit snd_cs46xx_pcm(cs46xx_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, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)		return err;	pcm->private_data = chip;	pcm->private_free = snd_cs46xx_pcm_free;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);	/* global setup */	pcm->info_flags = 0;	strcpy(pcm->name, "CS46xx");	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;}#ifdef CONFIG_SND_CS46XX_NEW_DSPint __devinit snd_cs46xx_pcm_rear(cs46xx_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, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)		return err;	pcm->private_data = chip;	pcm->private_free = snd_cs46xx_pcm_rear_free;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);	/* global setup */	pcm->info_flags = 0;	strcpy(pcm->name, "CS46xx - Rear");	chip->pcm_rear = 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;}int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_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, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)		return err;	pcm->private_data = chip;	pcm->private_free = snd_cs46xx_pcm_center_lfe_free;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);	/* global setup */	pcm->info_flags = 0;	strcpy(pcm->name, "CS46xx - Center LFE");	chip->pcm_center_lfe = 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;}int __devinit snd_cs46xx_pcm_iec958(cs46xx_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, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)		return err;

⌨️ 快捷键说明

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