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

📄 ice1712.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);	pcm->private_data = ice;	pcm->private_free = snd_ice1712_pcm_free;	pcm->info_flags = 0;	strcpy(pcm->name, "ICE1712 consumer");	ice->pcm = pcm;	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(ice->pci), 64*1024, 64*1024);	if (rpcm)		*rpcm = pcm;	printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n");	return 0;}static void snd_ice1712_pcm_free_ds(snd_pcm_t *pcm){	ice1712_t *ice = pcm->private_data;	ice->pcm_ds = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_ice1712_pcm_ds(ice1712_t * ice, int device, snd_pcm_t ** rpcm){	snd_pcm_t *pcm;	int err;	if (rpcm)		*rpcm = NULL;	err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);	if (err < 0)		return err;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);	pcm->private_data = ice;	pcm->private_free = snd_ice1712_pcm_free_ds;	pcm->info_flags = 0;	strcpy(pcm->name, "ICE1712 consumer (DS)");	ice->pcm_ds = pcm;	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(ice->pci), 64*1024, 128*1024);	if (rpcm)		*rpcm = pcm;	return 0;}/* *  PCM code - professional part (multitrack) */static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,				32000, 44100, 48000, 64000, 88200, 96000 };static snd_pcm_hw_constraint_list_t hw_constraints_rates = {	.count = ARRAY_SIZE(rates),	.list = rates,	.mask = 0,};static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,				   int cmd){	ice1712_t *ice = snd_pcm_substream_chip(substream);	switch (cmd) {	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:	{		unsigned int what;		unsigned int old;		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)			return -EINVAL;		what = ICE1712_PLAYBACK_PAUSE;		snd_pcm_trigger_done(substream, substream);		spin_lock(&ice->reg_lock);		old = inl(ICEMT(ice, PLAYBACK_CONTROL));		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)			old |= what;		else			old &= ~what;		outl(old, ICEMT(ice, PLAYBACK_CONTROL));		spin_unlock(&ice->reg_lock);		break;	}	case SNDRV_PCM_TRIGGER_START:	case SNDRV_PCM_TRIGGER_STOP:	{		unsigned int what = 0;		unsigned int old;		struct list_head *pos;		snd_pcm_substream_t *s;		snd_pcm_group_for_each(pos, substream) {			s = snd_pcm_group_substream_entry(pos);			if (s == ice->playback_pro_substream) {				what |= ICE1712_PLAYBACK_START;				snd_pcm_trigger_done(s, substream);			} else if (s == ice->capture_pro_substream) {				what |= ICE1712_CAPTURE_START_SHADOW;				snd_pcm_trigger_done(s, substream);			}		}		spin_lock(&ice->reg_lock);		old = inl(ICEMT(ice, PLAYBACK_CONTROL));		if (cmd == SNDRV_PCM_TRIGGER_START)			old |= what;		else			old &= ~what;		outl(old, ICEMT(ice, PLAYBACK_CONTROL));		spin_unlock(&ice->reg_lock);		break;	}	default:		return -EINVAL;	}	return 0;}/* */static void snd_ice1712_set_pro_rate(ice1712_t *ice, unsigned int rate, int force){	unsigned long flags;	unsigned char val, old;	unsigned int i;	switch (rate) {	case 8000: val = 6; break;	case 9600: val = 3; break;	case 11025: val = 10; break;	case 12000: val = 2; break;	case 16000: val = 5; break;	case 22050: val = 9; break;	case 24000: val = 1; break;	case 32000: val = 4; break;	case 44100: val = 8; break;	case 48000: val = 0; break;	case 64000: val = 15; break;	case 88200: val = 11; break;	case 96000: val = 7; break;	default:		snd_BUG();		val = 0;		rate = 48000;		break;	}	spin_lock_irqsave(&ice->reg_lock, flags);	if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|						 ICE1712_PLAYBACK_PAUSE|						 ICE1712_PLAYBACK_START)) {	      __out:		spin_unlock_irqrestore(&ice->reg_lock, flags);		return;	}	if (!force && is_pro_rate_locked(ice))		goto __out;        old = inb(ICEMT(ice, RATE));	if (!force && old == val)		goto __out;	outb(val, ICEMT(ice, RATE));	spin_unlock_irqrestore(&ice->reg_lock, flags);	if (ice->gpio.set_pro_rate)		ice->gpio.set_pro_rate(ice, rate);	for (i = 0; i < ice->akm_codecs; i++) {		if (ice->akm[i].ops.set_rate_val)			ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);	}	if (ice->spdif.ops.setup_rate)		ice->spdif.ops.setup_rate(ice, rate);}static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);	spin_lock_irq(&ice->reg_lock);	outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));	outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));	spin_unlock_irq(&ice->reg_lock);	return 0;}static int snd_ice1712_playback_pro_hw_params(snd_pcm_substream_t * substream,					      snd_pcm_hw_params_t * hw_params){	ice1712_t *ice = snd_pcm_substream_chip(substream);	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));}static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);	spin_lock_irq(&ice->reg_lock);	outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));	outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));	spin_unlock_irq(&ice->reg_lock);	return 0;}static int snd_ice1712_capture_pro_hw_params(snd_pcm_substream_t * substream,					     snd_pcm_hw_params_t * hw_params){	ice1712_t *ice = snd_pcm_substream_chip(substream);	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));}static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	size_t ptr;	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))		return 0;	ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);	if (ptr == substream->runtime->buffer_size)		ptr = 0;	return bytes_to_frames(substream->runtime, ptr);}static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	size_t ptr;	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))		return 0;	ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2);	if (ptr == substream->runtime->buffer_size)		ptr = 0;	return bytes_to_frames(substream->runtime, ptr);}static snd_pcm_hardware_t snd_ice1712_playback_pro ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID |				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),	.formats =		SNDRV_PCM_FMTBIT_S32_LE,	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,	.rate_min =		4000,	.rate_max =		96000,	.channels_min =		10,	.channels_max =		10,	.buffer_bytes_max =	(256*1024),	.period_bytes_min =	10 * 4 * 2,	.period_bytes_max =	131040,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static snd_pcm_hardware_t snd_ice1712_capture_pro ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID |				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),	.formats =		SNDRV_PCM_FMTBIT_S32_LE,	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,	.rate_min =		4000,	.rate_max =		96000,	.channels_min =		12,	.channels_max =		12,	.buffer_bytes_max =	(256*1024),	.period_bytes_min =	12 * 4 * 2,	.period_bytes_max =	131040,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream){	snd_pcm_runtime_t *runtime = substream->runtime;	ice1712_t *ice = snd_pcm_substream_chip(substream);	ice->playback_pro_substream = substream;	runtime->hw = snd_ice1712_playback_pro;	snd_pcm_set_sync(substream);	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);	if (ice->spdif.ops.open)		ice->spdif.ops.open(ice, substream);	return 0;}static int snd_ice1712_capture_pro_open(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	ice->capture_pro_substream = substream;	runtime->hw = snd_ice1712_capture_pro;	snd_pcm_set_sync(substream);	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);	return 0;}static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	if (PRO_RATE_RESET)		snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);	ice->playback_pro_substream = NULL;	if (ice->spdif.ops.close)		ice->spdif.ops.close(ice, substream);	return 0;}static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream){	ice1712_t *ice = snd_pcm_substream_chip(substream);	if (PRO_RATE_RESET)		snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);	ice->capture_pro_substream = NULL;	return 0;}static void snd_ice1712_pcm_profi_free(snd_pcm_t *pcm){	ice1712_t *ice = pcm->private_data;	ice->pcm_pro = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}static snd_pcm_ops_t snd_ice1712_playback_pro_ops = {	.open =		snd_ice1712_playback_pro_open,	.close =	snd_ice1712_playback_pro_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_ice1712_playback_pro_hw_params,	.hw_free =	snd_ice1712_hw_free,	.prepare =	snd_ice1712_playback_pro_prepare,	.trigger =	snd_ice1712_pro_trigger,	.pointer =	snd_ice1712_playback_pro_pointer,};static snd_pcm_ops_t snd_ice1712_capture_pro_ops = {	.open =		snd_ice1712_capture_pro_open,	.close =	snd_ice1712_capture_pro_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_ice1712_capture_pro_hw_params,	.hw_free =	snd_ice1712_hw_free,	.prepare =	snd_ice1712_capture_pro_prepare,	.trigger =	snd_ice1712_pro_trigger,	.pointer =	snd_ice1712_capture_pro_pointer,};static int __devinit snd_ice1712_pcm_profi(ice1712_t * ice, int device, snd_pcm_t ** rpcm){	snd_pcm_t *pcm;	int err;	if (rpcm)		*rpcm = NULL;	err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);	if (err < 0)		return err;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);	pcm->private_data = ice;	pcm->private_free = snd_ice1712_pcm_profi_free;	pcm->info_flags = 0;	strcpy(pcm->name, "ICE1712 multi");	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(ice->pci), 256*1024, 256*1024);	ice->pcm_pro = pcm;	if (rpcm)		*rpcm = pcm;		if (ice->cs8427) {		/* assign channels to iec958 */		err = snd_cs8427_iec958_build(ice->cs8427,					      pcm->streams[0].substream,					      pcm->streams[1].substream);		if (err < 0)			return err;	}	if ((err = snd_ice1712_build_pro_mixer(ice)) < 0)		return err;	return 0;}/* *  Mixer section */static void snd_ice1712_update_volume(ice1712_t *ice, int index){	unsigned int vol = ice->pro_volumes[index];	unsigned short val = 0;	val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f;	val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8;	outb(index, ICEMT(ice, MONITOR_INDEX));	outw(val, ICEMT(ice, MONITOR_VOLUME));}static int snd_ice1712_pro_mixer_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = 2;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}static int snd_ice1712_pro_mixer_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){

⌨️ 快捷键说明

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