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

📄 intel8x0.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		.name = "HP nc8000",		.type = AC97_TUNE_HP_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x0890,		.name = "HP nc6000",		.type = AC97_TUNE_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x0934,		.name = "HP nx8220",		.type = AC97_TUNE_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x129d,		.name = "HP xw8000",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x103c,		.subdevice = 0x0938,		.name = "HP nc4200",		.type = AC97_TUNE_HP_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x099c,		.name = "HP nx6110/nc6120",		.type = AC97_TUNE_HP_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x0944,		.name = "HP nc6220",		.type = AC97_TUNE_HP_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x0934,		.name = "HP nc8220",		.type = AC97_TUNE_HP_MUTE_LED	},	{		.subvendor = 0x103c,		.subdevice = 0x12f1,		.name = "HP xw8200",	/* AD1981B*/		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x103c,		.subdevice = 0x12f2,		.name = "HP xw6200",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x103c,		.subdevice = 0x3008,		.name = "HP xw4200",	/* AD1981B*/		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x104d,		.subdevice = 0x8197,		.name = "Sony S1XP",		.type = AC97_TUNE_INV_EAPD	}, 	{		.subvendor = 0x1043,		.subdevice = 0x80f3,		.name = "ASUS ICH5/AD1985",		.type = AC97_TUNE_AD_SHARING	},	{		.subvendor = 0x10cf,		.subdevice = 0x11c3,		.name = "Fujitsu-Siemens E4010",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10cf,		.subdevice = 0x1225,		.name = "Fujitsu-Siemens T3010",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10cf,		.subdevice = 0x1253,		.name = "Fujitsu S6210",	/* STAC9750/51 */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10cf,		.subdevice = 0x127e,		.name = "Fujitsu Lifebook C1211D",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10cf,		.subdevice = 0x12ec,		.name = "Fujitsu-Siemens 4010",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10cf,		.subdevice = 0x12f2,		.name = "Fujitsu-Siemens Celsius H320",		.type = AC97_TUNE_SWAP_HP	},	{		.subvendor = 0x10f1,		.subdevice = 0x2665,		.name = "Fujitsu-Siemens Celsius",	/* AD1981? */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10f1,		.subdevice = 0x2885,		.name = "AMD64 Mobo",	/* ALC650 */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10f1,		.subdevice = 0x2895,		.name = "Tyan Thunder K8WE",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x10f7,		.subdevice = 0x834c,		.name = "Panasonic CF-R4",		.type = AC97_TUNE_HP_ONLY,	},	{		.subvendor = 0x110a,		.subdevice = 0x0056,		.name = "Fujitsu-Siemens Scenic",	/* AD1981? */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x11d4,		.subdevice = 0x5375,		.name = "ADI AD1985 (discrete)",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x1462,		.subdevice = 0x5470,		.name = "MSI P4 ATX 645 Ultra",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x1734,		.subdevice = 0x0088,		.name = "Fujitsu-Siemens D1522",	/* AD1981 */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x8086,		.subdevice = 0x2000,		.mask = 0xfff0,		.name = "Intel ICH5/AD1985",		.type = AC97_TUNE_AD_SHARING	},	{		.subvendor = 0x8086,		.subdevice = 0x4000,		.mask = 0xfff0,		.name = "Intel ICH5/AD1985",		.type = AC97_TUNE_AD_SHARING	},	{		.subvendor = 0x8086,		.subdevice = 0x4856,		.name = "Intel D845WN (82801BA)",		.type = AC97_TUNE_SWAP_HP	},	{		.subvendor = 0x8086,		.subdevice = 0x4d44,		.name = "Intel D850EMV2",	/* AD1885 */		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x8086,		.subdevice = 0x4d56,		.name = "Intel ICH/AD1885",		.type = AC97_TUNE_HP_ONLY	},	{		.subvendor = 0x8086,		.subdevice = 0x6000,		.mask = 0xfff0,		.name = "Intel ICH5/AD1985",		.type = AC97_TUNE_AD_SHARING	},	{		.subvendor = 0x8086,		.subdevice = 0xe000,		.mask = 0xfff0,		.name = "Intel ICH5/AD1985",		.type = AC97_TUNE_AD_SHARING	},#if 0 /* FIXME: this seems wrong on most boards */	{		.subvendor = 0x8086,		.subdevice = 0xa000,		.mask = 0xfff0,		.name = "Intel ICH5/AD1985",		.type = AC97_TUNE_HP_ONLY	},#endif	{ } /* terminator */};static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,					const char *quirk_override){	struct snd_ac97_bus *pbus;	struct snd_ac97_template ac97;	int err;	unsigned int i, codecs;	unsigned int glob_sta = 0;	struct snd_ac97_bus_ops *ops;	static struct snd_ac97_bus_ops standard_bus_ops = {		.write = snd_intel8x0_codec_write,		.read = snd_intel8x0_codec_read,	};	static struct snd_ac97_bus_ops ali_bus_ops = {		.write = snd_intel8x0_ali_codec_write,		.read = snd_intel8x0_ali_codec_read,	};	chip->spdif_idx = -1; /* use PCMOUT (or disabled) */	if (!spdif_aclink) {		switch (chip->device_type) {		case DEVICE_NFORCE:			chip->spdif_idx = NVD_SPBAR;			break;		case DEVICE_ALI:			chip->spdif_idx = ALID_AC97SPDIFOUT;			break;		case DEVICE_INTEL_ICH4:			chip->spdif_idx = ICHD_SPBAR;			break;		};	}	chip->in_ac97_init = 1;		memset(&ac97, 0, sizeof(ac97));	ac97.private_data = chip;	ac97.private_free = snd_intel8x0_mixer_free_ac97;	ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;	if (chip->xbox)		ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;	if (chip->device_type != DEVICE_ALI) {		glob_sta = igetdword(chip, ICHREG(GLOB_STA));		ops = &standard_bus_ops;		chip->in_sdin_init = 1;		codecs = 0;		for (i = 0; i < chip->max_codecs; i++) {			if (! (glob_sta & chip->codec_bit[i]))				continue;			if (chip->device_type == DEVICE_INTEL_ICH4) {				snd_intel8x0_codec_read_test(chip, codecs);				chip->ac97_sdin[codecs] =					igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;				snd_assert(chip->ac97_sdin[codecs] < 3,					   chip->ac97_sdin[codecs] = 0);			} else				chip->ac97_sdin[codecs] = i;			codecs++;		}		chip->in_sdin_init = 0;		if (! codecs)			codecs = 1;	} else {		ops = &ali_bus_ops;		codecs = 1;		/* detect the secondary codec */		for (i = 0; i < 100; i++) {			unsigned int reg = igetdword(chip, ICHREG(ALI_RTSR));			if (reg & 0x40) {				codecs = 2;				break;			}			iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40);			udelay(1);		}	}	if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)		goto __err;	pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;	if (ac97_clock >= 8000 && ac97_clock <= 48000)		pbus->clock = ac97_clock;	/* FIXME: my test board doesn't work well with VRA... */	if (chip->device_type == DEVICE_ALI)		pbus->no_vra = 1;	else		pbus->dra = 1;	chip->ac97_bus = pbus;	chip->ncodecs = codecs;	ac97.pci = chip->pci;	for (i = 0; i < codecs; i++) {		ac97.num = i;		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {			if (err != -EACCES)				snd_printk(KERN_ERR "Unable to initialize codec #%d\n", i);			if (i == 0)				goto __err;			continue;		}	}	/* tune up the primary codec */	snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);	/* enable separate SDINs for ICH4 */	if (chip->device_type == DEVICE_INTEL_ICH4)		pbus->isdin = 1;	/* find the available PCM streams */	i = ARRAY_SIZE(ac97_pcm_defs);	if (chip->device_type != DEVICE_INTEL_ICH4)		i -= 2;		/* do not allocate PCM2IN and MIC2 */	if (chip->spdif_idx < 0)		i--;		/* do not allocate S/PDIF */	err = snd_ac97_pcm_assign(pbus, i, ac97_pcm_defs);	if (err < 0)		goto __err;	chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0];	chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1];	chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2];	if (chip->spdif_idx >= 0)		chip->ichd[chip->spdif_idx].pcm = &pbus->pcms[3];	if (chip->device_type == DEVICE_INTEL_ICH4) {		chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4];		chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5];	}	/* enable separate SDINs for ICH4 */	if (chip->device_type == DEVICE_INTEL_ICH4) {		struct ac97_pcm *pcm = chip->ichd[ICHD_PCM2IN].pcm;		u8 tmp = igetbyte(chip, ICHREG(SDM));		tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK);		if (pcm) {			tmp |= ICH_SE;	/* steer enable for multiple SDINs */			tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT;			for (i = 1; i < 4; i++) {				if (pcm->r[0].codec[i]) {					tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT;					break;				}			}		} else {			tmp &= ~ICH_SE; /* steer disable */		}		iputbyte(chip, ICHREG(SDM), tmp);	}	if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {		chip->multi4 = 1;		if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE))			chip->multi6 = 1;	}	if (pbus->pcms[0].r[1].rslots[0]) {		chip->dra = 1;	}	if (chip->device_type == DEVICE_INTEL_ICH4) {		if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)			chip->smp20bit = 1;	}	if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {		/* 48kHz only */		chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;	}	if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {		/* use slot 10/11 for SPDIF */		u32 val;		val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;		val |= ICH_PCM_SPDIF_1011;		iputdword(chip, ICHREG(GLOB_CNT), val);		snd_ac97_update_bits(chip->ac97[0], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);	}	chip->in_ac97_init = 0;	return 0; __err:	/* clear the cold-reset bit for the next chance */	if (chip->device_type != DEVICE_ALI)		iputdword(chip, ICHREG(GLOB_CNT),			  igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);	return err;}/* * */static void do_ali_reset(struct intel8x0 *chip){	iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);	iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);	iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);	iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);	iputdword(chip, ICHREG(ALI_INTERFACECR),		  ICH_ALI_IF_PI|ICH_ALI_IF_PO);	iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);	iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);}static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing){	unsigned long end_time;	unsigned int cnt, status, nstatus;		/* put logic to right state */	/* first clear status bits */	status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;	if (chip->device_type == DEVICE_NFORCE)		status |= ICH_NVSPINT;	cnt = igetdword(chip, ICHREG(GLOB_STA));	iputdword(chip, ICHREG(GLOB_STA), cnt & status);	/* ACLink on, 2 channels */	cnt = igetdword(chip, ICHREG(GLOB_CNT));	cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);#ifdef CONFIG_SND_AC97_POWER_SAVE	/* do cold reset - the full ac97 powerdown may leave the controller	 * in a warm state but actually it cannot communicate with the codec.	 */	iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_AC97COLD);	cnt = igetdword(chip, ICHREG(GLOB_CNT));	udelay(10);	iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD);	msleep(1);#else	/* finish cold or do warm reset */	cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;	iputdword(chip, ICHREG(GLOB_CNT), cnt);	end_time = (jiffies + (HZ / 4)) + 1;	do {		if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)			goto __ok;		schedule_timeout_uninterruptible(1);	} while (time_after_eq(end_time, jiffies));	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",		   igetdword(chip, ICHREG(GLOB_CNT)));	return -EIO;      __ok:#endif	if (probing) {		/* wait for any codec read

⌨️ 快捷键说明

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