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

📄 intel8x0.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int dbl = params_rate(hw_params) > 48000;	int err;	if (chip->fix_nocache && ichdev->page_attr_changed) {		fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */		ichdev->page_attr_changed = 0;	}	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));	if (err < 0)		return err;	if (chip->fix_nocache) {		if (runtime->dma_area && ! ichdev->page_attr_changed) {			fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);			ichdev->page_attr_changed = 1;		}	}	if (ichdev->pcm_open_flag) {		snd_ac97_pcm_close(ichdev->pcm);		ichdev->pcm_open_flag = 0;	}	err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params),				params_channels(hw_params),				ichdev->pcm->r[dbl].slots);	if (err >= 0) {		ichdev->pcm_open_flag = 1;		/* Force SPDIF setting */		if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)			snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF,					  params_rate(hw_params));	}	return err;}static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	struct ichdev *ichdev = get_ichdev(substream);	if (ichdev->pcm_open_flag) {		snd_ac97_pcm_close(ichdev->pcm);		ichdev->pcm_open_flag = 0;	}	if (chip->fix_nocache && ichdev->page_attr_changed) {		fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);		ichdev->page_attr_changed = 0;	}	return snd_pcm_lib_free_pages(substream);}static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,				       struct snd_pcm_runtime *runtime){	unsigned int cnt;	int dbl = runtime->rate > 48000;	spin_lock_irq(&chip->reg_lock);	switch (chip->device_type) {	case DEVICE_ALI:		cnt = igetdword(chip, ICHREG(ALI_SCR));		cnt &= ~ICH_ALI_SC_PCM_246_MASK;		if (runtime->channels == 4 || dbl)			cnt |= ICH_ALI_SC_PCM_4;		else if (runtime->channels == 6)			cnt |= ICH_ALI_SC_PCM_6;		iputdword(chip, ICHREG(ALI_SCR), cnt);		break;	case DEVICE_SIS:		cnt = igetdword(chip, ICHREG(GLOB_CNT));		cnt &= ~ICH_SIS_PCM_246_MASK;		if (runtime->channels == 4 || dbl)			cnt |= ICH_SIS_PCM_4;		else if (runtime->channels == 6)			cnt |= ICH_SIS_PCM_6;		iputdword(chip, ICHREG(GLOB_CNT), cnt);		break;	default:		cnt = igetdword(chip, ICHREG(GLOB_CNT));		cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);		if (runtime->channels == 4 || dbl)			cnt |= ICH_PCM_4;		else if (runtime->channels == 6)			cnt |= ICH_PCM_6;		if (chip->device_type == DEVICE_NFORCE) {			/* reset to 2ch once to keep the 6 channel data in alignment,			 * to start from Front Left always			 */			if (cnt & ICH_PCM_246_MASK) {				iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_PCM_246_MASK);				spin_unlock_irq(&chip->reg_lock);				msleep(50); /* grrr... */				spin_lock_irq(&chip->reg_lock);			}		} else if (chip->device_type == DEVICE_INTEL_ICH4) {			if (runtime->sample_bits > 16)				cnt |= ICH_PCM_20BIT;		}		iputdword(chip, ICHREG(GLOB_CNT), cnt);		break;	}	spin_unlock_irq(&chip->reg_lock);}static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	struct ichdev *ichdev = get_ichdev(substream);	ichdev->physbuf = runtime->dma_addr;	ichdev->size = snd_pcm_lib_buffer_bytes(substream);	ichdev->fragsize = snd_pcm_lib_period_bytes(substream);	if (ichdev->ichd == ICHD_PCMOUT) {		snd_intel8x0_setup_pcm_out(chip, runtime);		if (chip->device_type == DEVICE_INTEL_ICH4)			ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;	}	snd_intel8x0_setup_periods(chip, ichdev);	return 0;}static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	struct ichdev *ichdev = get_ichdev(substream);	size_t ptr1, ptr;	int civ, timeout = 100;	unsigned int position;	spin_lock(&chip->reg_lock);	do {		civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);		ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);		position = ichdev->position;		if (ptr1 == 0) {			udelay(10);			continue;		}		if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&		    ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))			break;	} while (timeout--);	ptr1 <<= ichdev->pos_shift;	ptr = ichdev->fragsize1 - ptr1;	ptr += position;	spin_unlock(&chip->reg_lock);	if (ptr >= ichdev->size)		return 0;	return bytes_to_frames(substream->runtime, ptr);}static struct snd_pcm_hardware snd_intel8x0_stream ={	.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_RESUME),	.formats =		SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_48000,	.rate_min =		48000,	.rate_max =		48000,	.channels_min =		2,	.channels_max =		2,	.buffer_bytes_max =	128 * 1024,	.period_bytes_min =	32,	.period_bytes_max =	128 * 1024,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static unsigned int channels4[] = {	2, 4,};static struct snd_pcm_hw_constraint_list hw_constraints_channels4 = {	.count = ARRAY_SIZE(channels4),	.list = channels4,	.mask = 0,};static unsigned int channels6[] = {	2, 4, 6,};static struct snd_pcm_hw_constraint_list hw_constraints_channels6 = {	.count = ARRAY_SIZE(channels6),	.list = channels6,	.mask = 0,};static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	int err;	ichdev->substream = substream;	runtime->hw = snd_intel8x0_stream;	runtime->hw.rates = ichdev->pcm->rates;	snd_pcm_limit_hw_rates(runtime);	if (chip->device_type == DEVICE_SIS) {		runtime->hw.buffer_bytes_max = 64*1024;		runtime->hw.period_bytes_max = 64*1024;	}	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)		return err;	runtime->private_data = ichdev;	return 0;}static int snd_intel8x0_playback_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	int err;	err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);	if (err < 0)		return err;	if (chip->multi6) {		runtime->hw.channels_max = 6;		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,					   &hw_constraints_channels6);	} else if (chip->multi4) {		runtime->hw.channels_max = 4;		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,					   &hw_constraints_channels4);	}	if (chip->dra) {		snd_ac97_pcm_double_rate_rules(runtime);	}	if (chip->smp20bit) {		runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;		snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);	}	return 0;}static int snd_intel8x0_playback_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ICHD_PCMOUT].substream = NULL;	return 0;}static int snd_intel8x0_capture_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMIN]);}static int snd_intel8x0_capture_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ICHD_PCMIN].substream = NULL;	return 0;}static int snd_intel8x0_mic_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC]);}static int snd_intel8x0_mic_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ICHD_MIC].substream = NULL;	return 0;}static int snd_intel8x0_mic2_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]);}static int snd_intel8x0_mic2_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ICHD_MIC2].substream = NULL;	return 0;}static int snd_intel8x0_capture2_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]);}static int snd_intel8x0_capture2_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ICHD_PCM2IN].substream = NULL;	return 0;}static int snd_intel8x0_spdif_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;	return snd_intel8x0_pcm_open(substream, &chip->ichd[idx]);}static int snd_intel8x0_spdif_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;	chip->ichd[idx].substream = NULL;	return 0;}static int snd_intel8x0_ali_ac97spdifout_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	unsigned int val;	spin_lock_irq(&chip->reg_lock);	val = igetdword(chip, ICHREG(ALI_INTERFACECR));	val |= ICH_ALI_IF_AC97SP;	iputdword(chip, ICHREG(ALI_INTERFACECR), val);	/* also needs to set ALI_SC_CODEC_SPDF correctly */	spin_unlock_irq(&chip->reg_lock);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);}static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	unsigned int val;	chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;	spin_lock_irq(&chip->reg_lock);	val = igetdword(chip, ICHREG(ALI_INTERFACECR));	val &= ~ICH_ALI_IF_AC97SP;	iputdword(chip, ICHREG(ALI_INTERFACECR), val);	spin_unlock_irq(&chip->reg_lock);	return 0;}#if 0 // NYIstatic int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFIN]);}static int snd_intel8x0_ali_spdifin_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ALID_SPDIFIN].substream = NULL;	return 0;}static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFOUT]);}static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream){	struct intel8x0 *chip = snd_pcm_substream_chip(substream);	chip->ichd[ALID_SPDIFOUT].substream = NULL;	return 0;}#endifstatic struct snd_pcm_ops snd_intel8x0_playback_ops = {	.open =		snd_intel8x0_playback_open,	.close =	snd_intel8x0_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_capture_ops = {	.open =		snd_intel8x0_capture_open,	.close =	snd_intel8x0_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {	.open =		snd_intel8x0_mic_open,	.close =	snd_intel8x0_mic_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {	.open =		snd_intel8x0_mic2_open,	.close =	snd_intel8x0_mic2_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_capture2_ops = {	.open =		snd_intel8x0_capture2_open,	.close =	snd_intel8x0_capture2_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_spdif_ops = {	.open =		snd_intel8x0_spdif_open,	.close =	snd_intel8x0_spdif_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,	.hw_free =	snd_intel8x0_hw_free,	.prepare =	snd_intel8x0_pcm_prepare,	.trigger =	snd_intel8x0_pcm_trigger,	.pointer =	snd_intel8x0_pcm_pointer,};static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {	.open =		snd_intel8x0_playback_open,	.close =	snd_intel8x0_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_intel8x0_hw_params,

⌨️ 快捷键说明

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