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

📄 ac97_codec.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    val & 0x4000 ? "on" : "off",		    val & 0x2000 ? "on" : "off",		    val & 0x1000 ? "on" : "off",		    val & 0x0200 ? "Mic" : "MIX",		    val & 0x0100 ? "Mic2" : "Mic1",		    val & 0x0080 ? "on" : "off");	ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);	if (ext == 0)		return;	snd_iprintf(buffer, "Extended ID      : codec=%i rev=%i%s%s%s%s DSA=%i%s%s%s%s\n",			(ext >> 14) & 3,			(ext >> 10) & 3,			ext & 0x0200 ? " AMAP" : "",			ext & 0x0100 ? " LDAC" : "",			ext & 0x0080 ? " SDAC" : "",			ext & 0x0040 ? " CDAC" : "",			(ext >> 4) & 3,			ext & 0x0008 ? " VRM" : "",			ext & 0x0004 ? " SPDIF" : "",			ext & 0x0002 ? " DRA" : "",			ext & 0x0001 ? " VRA" : "");	val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);	snd_iprintf(buffer, "Extended status  :%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",			val & 0x4000 ? " PRL" : "",			val & 0x2000 ? " PRK" : "",			val & 0x1000 ? " PRJ" : "",			val & 0x0800 ? " PRI" : "",			val & 0x0400 ? " SPCV" : "",			val & 0x0200 ? " MADC" : "",			val & 0x0100 ? " LDAC" : "",			val & 0x0080 ? " SDAC" : "",			val & 0x0040 ? " CDAC" : "",			ext & 0x0004 ? spdif_slots[(val & 0x0030) >> 4] : "",			val & 0x0008 ? " VRM" : "",			val & 0x0004 ? " SPDIF" : "",			val & 0x0002 ? " DRA" : "",			val & 0x0001 ? " VRA" : "");	if (ext & 1) {	/* VRA */		val = snd_ac97_read(ac97, AC97_PCM_FRONT_DAC_RATE);		snd_iprintf(buffer, "PCM front DAC    : %iHz\n", val);		if (ext & 0x0080) {			val = snd_ac97_read(ac97, AC97_PCM_SURR_DAC_RATE);			snd_iprintf(buffer, "PCM Surr DAC     : %iHz\n", val);		}		if (ext & 0x0100) {			val = snd_ac97_read(ac97, AC97_PCM_LFE_DAC_RATE);			snd_iprintf(buffer, "PCM LFE DAC      : %iHz\n", val);		}		val = snd_ac97_read(ac97, AC97_PCM_LR_ADC_RATE);		snd_iprintf(buffer, "PCM ADC          : %iHz\n", val);	}	if (ext & 0x0008) {		val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);		snd_iprintf(buffer, "PCM MIC ADC      : %iHz\n", val);	}	if (ext & 0x0004) {		val = snd_ac97_read(ac97, AC97_SPDIF);		snd_iprintf(buffer, "SPDIF Control    :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",			val & 0x0001 ? " PRO" : " Consumer",			val & 0x0002 ? " Non-audio" : " PCM",			val & 0x0004 ? " Copyright" : "",			val & 0x0008 ? " Preemph50/15" : "",			(val & 0x07f0) >> 4,			(val & 0x0800) >> 11,			spdif_rates[(val & 0x3000) >> 12],			val & 0x4000 ? " DRS" : "",			val & 0x8000 ? " Validity" : "");	}}static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer){	ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);		if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86		int idx;		down(&ac97->spec.ad18xx.mutex);		for (idx = 0; idx < 3; idx++)			if (ac97->spec.ad18xx.id[idx]) {				/* select single codec */				snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);				snd_ac97_proc_read_main(ac97, buffer, idx);				snd_iprintf(buffer, "\n\n");			}		/* select all codecs */		snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, 0x7000);		up(&ac97->spec.ad18xx.mutex);				snd_iprintf(buffer, "\nAD18XX configuration\n");		snd_iprintf(buffer, "Unchained        : 0x%04x,0x%04x,0x%04x\n",			ac97->spec.ad18xx.unchained[0],			ac97->spec.ad18xx.unchained[1],			ac97->spec.ad18xx.unchained[2]);		snd_iprintf(buffer, "Chained          : 0x%04x,0x%04x,0x%04x\n",			ac97->spec.ad18xx.chained[0],			ac97->spec.ad18xx.chained[1],			ac97->spec.ad18xx.chained[2]);	} else {		snd_ac97_proc_read_main(ac97, buffer, 0);	}}static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx){	int reg, val;	for (reg = 0; reg < 0x80; reg += 2) {		val = snd_ac97_read(ac97, reg);		snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);	}}static void snd_ac97_proc_regs_read(snd_info_entry_t *entry, 				    snd_info_buffer_t * buffer){	ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86		int idx;		down(&ac97->spec.ad18xx.mutex);		for (idx = 0; idx < 3; idx++)			if (ac97->spec.ad18xx.id[idx]) {				/* select single codec */				snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);				snd_ac97_proc_regs_read_main(ac97, buffer, idx);			}		/* select all codecs */		snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, 0x7000);		up(&ac97->spec.ad18xx.mutex);	} else {		snd_ac97_proc_regs_read_main(ac97, buffer, 0);	}	}static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97){	snd_info_entry_t *entry;	char name[12];	sprintf(name, "ac97#%d", ac97->addr);	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {		entry->content = SNDRV_INFO_CONTENT_TEXT;		entry->private_data = ac97;		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;		entry->c.text.read_size = 512;		entry->c.text.read = snd_ac97_proc_read;		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	ac97->proc_entry = entry;	sprintf(name, "ac97#%dregs", ac97->addr);	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {		entry->content = SNDRV_INFO_CONTENT_TEXT;		entry->private_data = ac97;		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;		entry->c.text.read_size = 1024;		entry->c.text.read = snd_ac97_proc_regs_read;		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	ac97->proc_regs_entry = entry;}static void snd_ac97_proc_done(ac97_t * ac97){	if (ac97->proc_regs_entry) {		snd_info_unregister(ac97->proc_regs_entry);		ac97->proc_regs_entry = NULL;	}	if (ac97->proc_entry) {		snd_info_unregister(ac97->proc_entry);		ac97->proc_entry = NULL;	}}/* *  Chip specific initialization */static int patch_wolfson(ac97_t * ac97){	// for all wolfson codecs (is this correct? --jk)	snd_ac97_write_cache(ac97, 0x72, 0x0808);	snd_ac97_write_cache(ac97, 0x74, 0x0808);	// patch for DVD noise	snd_ac97_write_cache(ac97, 0x5a, 0x0200);	// init vol	snd_ac97_write_cache(ac97, 0x70, 0x0808);	snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);	return 0;}static int patch_tritech_tr28028(ac97_t * ac97){	snd_ac97_write_cache(ac97, 0x26, 0x0300);	snd_ac97_write_cache(ac97, 0x26, 0x0000);	snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);	snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000);	return 0;}static int patch_sigmatel_stac9708(ac97_t * ac97){	unsigned int codec72, codec6c;	codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000;	codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG);	if ((codec72==0) && (codec6c==0)) {		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007);	} else if ((codec72==0x8000) && (codec6c==0)) {		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008);	} else if ((codec72==0x8000) && (codec6c==0x0080)) {		/* nothing */	}	snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int patch_sigmatel_stac9721(ac97_t * ac97){	if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {		// patch for SigmaTel		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);		snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);	}	snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int patch_sigmatel_stac9744(ac97_t * ac97){	// patch for SigmaTel	snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);	/* is this correct? --jk */	snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int patch_sigmatel_stac9756(ac97_t * ac97){	// patch for SigmaTel	snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);	/* is this correct? --jk */	snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);	snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int patch_cirrus_cs4299(ac97_t * ac97){	ac97->flags |= AC97_HAS_PC_BEEP;	/* force the detection of PC Beep */	return 0;}static int patch_ad1819(ac97_t * ac97){	// patch for Analog Devices	snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, 0x7000); /* select all codecs */	return 0;}static unsigned short patch_ad1881_unchained(ac97_t * ac97, int idx, unsigned short mask){	unsigned short val;	// test for unchained codec	snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, mask);	snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);	/* ID0C, ID1C, SDIE = off */	val = snd_ac97_read(ac97, AC97_VENDOR_ID2);	if ((val & 0xff40) != 0x5340)		return 0;	ac97->spec.ad18xx.unchained[idx] = mask;	ac97->spec.ad18xx.id[idx] = val;	return mask;}static int patch_ad1881_chained1(ac97_t * ac97, int idx, unsigned short codec_bits){	static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };	unsigned short val;		snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, cfg_bits[idx]);	snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004);	// SDIE	val = snd_ac97_read(ac97, AC97_VENDOR_ID2);	if ((val & 0xff40) != 0x5340)		return 0;	if (codec_bits)		snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits);	ac97->spec.ad18xx.chained[idx] = cfg_bits[idx];	ac97->spec.ad18xx.id[idx] = val;	return 1;}static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, int cidx2){	// already detected?	if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])		cidx1 = -1;	if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2])		cidx2 = -1;	if (cidx1 < 0 && cidx2 < 0)		return;	// test for chained codecs	snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, ac97->spec.ad18xx.unchained[unchained_idx]);	snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002);		// ID1C	if (cidx1 >= 0) {		if (patch_ad1881_chained1(ac97, cidx1, 0x0006))		// SDIE | ID1C			patch_ad1881_chained1(ac97, cidx2, 0);		else if (patch_ad1881_chained1(ac97, cidx2, 0x0006))	// SDIE | ID1C			patch_ad1881_chained1(ac97, cidx1, 0);	} else if (cidx2 >= 0) {		patch_ad1881_chained1(ac97, cidx2, 0);	}}static int patch_ad1881(ac97_t * ac97){	static const char cfg_idxs[3][2] = {		{2, 1},		{0, 2},		{0, 1}	};		// patch for Analog Devices	unsigned short codecs[3];	int idx, num;	init_MUTEX(&ac97->spec.ad18xx.mutex);	codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));	codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));	codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));	snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);	for (idx = 0; idx < 3; idx++)		if (ac97->spec.ad18xx.unchained[idx])			patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]);	if (ac97->spec.ad18xx.id[1]) {		ac97->flags |= AC97_AD_MULTI;		ac97->scaps |= AC97_SCAP_SURROUND_DAC;	}	if (ac97->spec.ad18xx.id[2]) {		ac97->flags |= AC97_AD_MULTI;		ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;	}      __end:	/* select all codecs */	snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, 0x7000);	/* check if only one codec is present */	for (idx = num = 0; idx < 3; idx++)		if (ac97->spec.ad18xx.id[idx])			num++;	if (num == 1) {		/* ok, deselect all ID bits */		snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);	}	/* required for AD1886/AD1885 combination */	ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);	if (ac97->spec.ad18xx.id[0]) {		ac97->id &= 0xffff0000;		ac97->id |= ac97->spec.ad18xx.id[0];	}	return 0;}/

⌨️ 快捷键说明

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