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

📄 ac97_codec.c

📁 Source files for pxa ac97 sound driver The packet contains the files that is listed below driv
💻 C
📖 第 1 页 / 共 3 页
字号:
	id2 = codec->codec_read(codec, AC97_VENDOR_ID2);	for (i = 0; i < ARRAY_SIZE(ac97_codec_ids); i++) {		if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) {			codec->type = ac97_codec_ids[i].id;			codec->name = ac97_codec_ids[i].name;			codec->codec_ops = ac97_codec_ids[i].ops;			break;		}	}	if (codec->name == NULL)		codec->name = "Unknown";	printk(KERN_INFO "ac97_codec: AC97 %s codec, id: 0x%04x:"	       "0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""),	       id1, id2, codec->name);	return ac97_init_mixer(codec);}static int ac97_init_mixer(struct ac97_codec *codec){	u16 cap;	int i;	cap = codec->codec_read(codec, AC97_RESET);	/* mixer masks */	codec->supported_mixers = AC97_SUPPORTED_MASK;	codec->stereo_mixers = AC97_STEREO_MASK;	codec->record_sources = AC97_RECORD_MASK;	if (!(cap & 0x04))		codec->supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);	if (!(cap & 0x10))		codec->supported_mixers &= ~SOUND_MASK_ALTPCM;	/* detect bit resolution */	codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);	if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x1f1f)		codec->bit_resolution = 5;	else		codec->bit_resolution = 6;	/* generic OSS to AC97 wrapper */	codec->read_mixer = ac97_read_mixer;	codec->write_mixer = ac97_write_mixer;	codec->recmask_io = ac97_recmask_io;	codec->mixer_ioctl = ac97_mixer_ioctl;	/* codec specific initialization for 4-6 channel output or secondary codec stuff */	if (codec->codec_ops->init != NULL) {		codec->codec_ops->init(codec);	}	/* initialize mixer channel volumes */	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {		struct mixer_defaults *md = &mixer_defaults[i];		if (md->mixer == -1) 			break;		if (!supported_mixer(codec, md->mixer)) 			continue;		ac97_set_mixer(codec, md->mixer, md->value);	}	return 1;}#define AC97_SIGMATEL_ANALOG    0x6c	/* Analog Special */#define AC97_SIGMATEL_DAC2INVERT 0x6e#define AC97_SIGMATEL_BIAS1     0x70#define AC97_SIGMATEL_BIAS2     0x72#define AC97_SIGMATEL_MULTICHN  0x74	/* Multi-Channel programming */#define AC97_SIGMATEL_CIC1      0x76#define AC97_SIGMATEL_CIC2      0x78static int sigmatel_9708_init(struct ac97_codec * codec){	u16 codec72, codec6c;	codec72 = codec->codec_read(codec, AC97_SIGMATEL_BIAS2) & 0x8000;	codec6c = codec->codec_read(codec, AC97_SIGMATEL_ANALOG);	if ((codec72==0) && (codec6c==0)) {		codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);		codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1000);		codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);		codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0007);	} else if ((codec72==0x8000) && (codec6c==0)) {		codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);		codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1001);		codec->codec_write(codec, AC97_SIGMATEL_DAC2INVERT, 0x0008);	} else if ((codec72==0x8000) && (codec6c==0x0080)) {		/* nothing */	}	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int sigmatel_9721_init(struct ac97_codec * codec){	/* Only set up secondary codec */	if (codec->id == 0)		return 0;	codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);	/* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link	   sloc 3,4 = 0x01, slot 7,8 = 0x00, */	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x00);	/* we don't have the crystal when we are on an AMR card, so use	   BIT_CLK as our clock source. Write the magic word ABBA and read	   back to enable register 0x78 */	codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);	codec->codec_read(codec, AC97_SIGMATEL_CIC1);	/* sync all the clocks*/	codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x3802);	return 0;}static int sigmatel_9744_init(struct ac97_codec * codec){	// patch for SigmaTel	codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);	codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x0000); // is this correct? --jk	codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);	codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0002);	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);	return 0;}static int wolfson_init(struct ac97_codec * codec){	codec->codec_write(codec, 0x72, 0x0808);	codec->codec_write(codec, 0x74, 0x0808);	// patch for DVD noise	codec->codec_write(codec, 0x5a, 0x0200);	// init vol as PCM vol	codec->codec_write(codec, 0x70,		codec->codec_read(codec, AC97_PCMOUT_VOL));	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);	return 0;}static int tritech_init(struct ac97_codec * codec){	codec->codec_write(codec, 0x26, 0x0300);	codec->codec_write(codec, 0x26, 0x0000);	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);	codec->codec_write(codec, AC97_RESERVED_3A, 0x0000);	return 0;}/* copied from drivers/sound/maestro.c */static int tritech_maestro_init(struct ac97_codec * codec){	/* no idea what this does */	codec->codec_write(codec, 0x2A, 0x0001);	codec->codec_write(codec, 0x2C, 0x0000);	codec->codec_write(codec, 0x2C, 0XFFFF);	return 0;}/* *	This is basically standard AC97. It should work as a default for *	almost all modern codecs. Note that some cards wire EAPD *backwards* *	That side of it is up to the card driver not us to cope with. * */static int eapd_control(struct ac97_codec * codec, int on){	if(on)		codec->codec_write(codec, AC97_POWER_CONTROL,			codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000);	else		codec->codec_write(codec, AC97_POWER_CONTROL,			codec->codec_read(codec, AC97_POWER_CONTROL)&~0x8000);	return 0;}/* *	Crystal digital audio control (CS4299 */ static int crystal_digital_control(struct ac97_codec *codec, int mode){	u16 cv;	switch(mode)	{		case 0: cv = 0x0; break;	/* SPEN off */		case 1: cv = 0x8004; break;	/* 48KHz digital */		case 2: cv = 0x8104; break;	/* 44.1KHz digital */		default:			return -1;		/* Not supported yet(eg AC3) */	}	codec->codec_write(codec, 0x68, cv);	return 0;}/* copied from drivers/sound/maestro.c */#if 0  /* there has been 1 person on the planet with a pt101 that we        know of.  If they care, they can put this back in :) */static int pt101_init(struct ac97_codec * codec){	printk(KERN_INFO "ac97_codec: PT101 Codec detected, initializing but _not_ installing mixer device.\n");	/* who knows.. */	codec->codec_write(codec, 0x2A, 0x0001);	codec->codec_write(codec, 0x2C, 0x0000);	codec->codec_write(codec, 0x2C, 0xFFFF);	codec->codec_write(codec, 0x10, 0x9F1F);	codec->codec_write(codec, 0x12, 0x0808);	codec->codec_write(codec, 0x14, 0x9F1F);	codec->codec_write(codec, 0x16, 0x9F1F);	codec->codec_write(codec, 0x18, 0x0404);	codec->codec_write(codec, 0x1A, 0x0000);	codec->codec_write(codec, 0x1C, 0x0000);	codec->codec_write(codec, 0x02, 0x0404);	codec->codec_write(codec, 0x04, 0x0808);	codec->codec_write(codec, 0x0C, 0x801F);	codec->codec_write(codec, 0x0E, 0x801F);	return 0;}#endif	EXPORT_SYMBOL(ac97_read_proc);EXPORT_SYMBOL(ac97_probe_codec);/* *	AC97 library support routines */	 /** *	ac97_set_dac_rate	-	set codec rate adaption *	@codec: ac97 code *	@rate: rate in hertz * *	Set the DAC rate. Assumes the codec supports VRA. The caller is *	expected to have checked this little detail. */ unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate){	unsigned int new_rate = rate;	u32 dacp;	u32 mast_vol, phone_vol, mono_vol, pcm_vol;	u32 mute_vol = 0x8000;	/* The mute volume? */	if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))	{		/* Mute several registers */		mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);		mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);		phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);		pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);		codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);		codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);		codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);		codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);				/* Power down the DAC */		dacp=codec->codec_read(codec, AC97_POWER_CONTROL);		codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);		/* Load the rate and read the effective rate */		codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);		new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);		/* Power it back up */		codec->codec_write(codec, AC97_POWER_CONTROL, dacp);		/* Restore volumes */		codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);		codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);		codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);		codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);	}	return new_rate;}EXPORT_SYMBOL(ac97_set_dac_rate);/** *	ac97_set_adc_rate	-	set codec rate adaption *	@codec: ac97 code *	@rate: rate in hertz * *	Set the ADC rate. Assumes the codec supports VRA. The caller is *	expected to have checked this little detail. */unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate){	unsigned int new_rate = rate;	u32 dacp;	if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))	{		/* Power down the ADC */		dacp=codec->codec_read(codec, AC97_POWER_CONTROL);		codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);		/* Load the rate and read the effective rate */		codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);		new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);		/* Power it back up */		codec->codec_write(codec, AC97_POWER_CONTROL, dacp);	}	return new_rate;}EXPORT_SYMBOL(ac97_set_adc_rate);int ac97_save_state(struct ac97_codec *codec){	return 0;	}EXPORT_SYMBOL(ac97_save_state);int ac97_restore_state(struct ac97_codec *codec){	int i;	unsigned int left, right, val;	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {		if (!supported_mixer(codec, i)) 			continue;		val = codec->mixer_state[i];		right = val >> 8;		left = val  & 0xff;		codec->write_mixer(codec, i, left, right);	}	return 0;}EXPORT_SYMBOL(ac97_restore_state);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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