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

📄 ac97_patch.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
#define AC97_AD198X_CLDIS	0x0800	/* center/lfe disable */#define AC97_AD198X_LODIS	0x1000	/* LINE_OUT disable */#define AC97_AD198X_MSPLT	0x2000	/* mute split */#define AC97_AD198X_AC97NC	0x4000	/* AC97 no compatible mode */#define AC97_AD198X_DACZ	0x8000	/* DAC zero-fill mode */static int snd_ac97_ad198x_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[2] = { "AC-Link", "A/D Converter" };	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 2;	if (uinfo->value.enumerated.item > 1)		uinfo->value.enumerated.item = 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_ac97_ad198x_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	val = ac97->regs[AC97_AD_SERIAL_CFG];	ucontrol->value.enumerated.item[0] = (val >> 2) & 1;	return 0;}static int snd_ac97_ad198x_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	if (ucontrol->value.enumerated.item[0] > 1)		return -EINVAL;	val = ucontrol->value.enumerated.item[0] << 2;	return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);}static const snd_kcontrol_new_t snd_ac97_ad198x_spdif_source = {	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,	.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",	.info	= snd_ac97_ad198x_spdif_source_info,	.get	= snd_ac97_ad198x_spdif_source_get,	.put	= snd_ac97_ad198x_spdif_source_put,};static int patch_ad198x_post_spdif(ac97_t * ac97){ 	return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);}static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = {	AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),};static int patch_ad1981a_specific(ac97_t * ac97){	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));}static struct snd_ac97_build_ops patch_ad1981a_build_ops = {	.build_post_spdif = patch_ad198x_post_spdif,	.build_specific = patch_ad1981a_specific,#ifdef CONFIG_PM	.resume = ad18xx_resume#endif};static void check_ad1981_hp_jack_sense(ac97_t *ac97){	u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;	switch (subid) {	case 0x103c0890: /* HP nc6000 */	case 0x103c099c: /* HP nx6110 */	case 0x103c006d: /* HP nx9105 */	case 0x17340088: /* FSC Scenic-W */		/* enable headphone jack sense */		snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);		break;	}}int patch_ad1981a(ac97_t *ac97){	patch_ad1881(ac97);	ac97->build_ops = &patch_ad1981a_build_ops;	snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);	ac97->flags |= AC97_STEREO_MUTES;	check_ad1981_hp_jack_sense(ac97);	return 0;}static const snd_kcontrol_new_t snd_ac97_ad198x_2cmic =AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);static int patch_ad1981b_specific(ac97_t *ac97){	int err;	if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)		return err;	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));}static struct snd_ac97_build_ops patch_ad1981b_build_ops = {	.build_post_spdif = patch_ad198x_post_spdif,	.build_specific = patch_ad1981b_specific,#ifdef CONFIG_PM	.resume = ad18xx_resume#endif};int patch_ad1981b(ac97_t *ac97){	patch_ad1881(ac97);	ac97->build_ops = &patch_ad1981b_build_ops;	snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);	ac97->flags |= AC97_STEREO_MUTES;	check_ad1981_hp_jack_sense(ac97);	return 0;}static int snd_ac97_ad1888_lohpsel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}static int snd_ac97_ad1888_lohpsel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	val = ac97->regs[AC97_AD_MISC];	ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);	return 0;}static int snd_ac97_ad1888_lohpsel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	val = !ucontrol->value.integer.value[0]		? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;	return snd_ac97_update_bits(ac97, AC97_AD_MISC,				    AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);}static int snd_ac97_ad1888_downmix_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 3;	if (uinfo->value.enumerated.item > 2)		uinfo->value.enumerated.item = 2;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_ac97_ad1888_downmix_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	val = ac97->regs[AC97_AD_MISC];	if (!(val & AC97_AD198X_DMIX1))		ucontrol->value.enumerated.item[0] = 0;	else		ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1);	return 0;}static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);	unsigned short val;	if (ucontrol->value.enumerated.item[0] > 2)		return -EINVAL;	if (ucontrol->value.enumerated.item[0] == 0)		val = 0;	else		val = AC97_AD198X_DMIX1 |			((ucontrol->value.enumerated.item[0] - 1) << 8);	return snd_ac97_update_bits(ac97, AC97_AD_MISC,				    AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);}static void ad1888_update_jacks(ac97_t *ac97){	unsigned short val = 0;	if (! is_shared_linein(ac97))		val |= (1 << 12);	if (! is_shared_micin(ac97))		val |= (1 << 11);	/* shared Line-In */	snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);}static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Exchange Front/Surround",		.info = snd_ac97_ad1888_lohpsel_info,		.get = snd_ac97_ad1888_lohpsel_get,		.put = snd_ac97_ad1888_lohpsel_put	},	AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Downmix",		.info = snd_ac97_ad1888_downmix_info,		.get = snd_ac97_ad1888_downmix_get,		.put = snd_ac97_ad1888_downmix_put	},	AC97_SURROUND_JACK_MODE_CTL,	AC97_CHANNEL_MODE_CTL,	AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),};static int patch_ad1888_specific(ac97_t *ac97){	/* rename 0x04 as "Master" and 0x02 as "Master Surround" */	snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback");	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");	return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));}static struct snd_ac97_build_ops patch_ad1888_build_ops = {	.build_post_spdif = patch_ad198x_post_spdif,	.build_specific = patch_ad1888_specific,#ifdef CONFIG_PM	.resume = ad18xx_resume,#endif	.update_jacks = ad1888_update_jacks,};int patch_ad1888(ac97_t * ac97){	unsigned short misc;		patch_ad1881(ac97);	ac97->build_ops = &patch_ad1888_build_ops;	/* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */	/* it seems that most vendors connect line-out connector to headphone out of AC'97 */	/* AD-compatible mode */	/* Stereo mutes enabled */	misc = snd_ac97_read(ac97, AC97_AD_MISC);	snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |			     AC97_AD198X_LOSEL |			     AC97_AD198X_HPSEL |			     AC97_AD198X_MSPLT |			     AC97_AD198X_AC97NC);	ac97->flags |= AC97_STEREO_MUTES;	return 0;}static int patch_ad1980_specific(ac97_t *ac97){	int err;	if ((err = patch_ad1888_specific(ac97)) < 0)		return err;	return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);}static struct snd_ac97_build_ops patch_ad1980_build_ops = {	.build_post_spdif = patch_ad198x_post_spdif,	.build_specific = patch_ad1980_specific,#ifdef CONFIG_PM	.resume = ad18xx_resume,#endif	.update_jacks = ad1888_update_jacks,};int patch_ad1980(ac97_t * ac97){	patch_ad1888(ac97);	ac97->build_ops = &patch_ad1980_build_ops;	return 0;}static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {	AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)};static void ad1985_update_jacks(ac97_t *ac97){	ad1888_update_jacks(ac97);	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,			     is_shared_micin(ac97) ? 0 : 1 << 9);}static int patch_ad1985_specific(ac97_t *ac97){	int err;	if ((err = patch_ad1980_specific(ac97)) < 0)		return err;	return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls));}static struct snd_ac97_build_ops patch_ad1985_build_ops = {	.build_post_spdif = patch_ad198x_post_spdif,	.build_specific = patch_ad1985_specific,#ifdef CONFIG_PM	.resume = ad18xx_resume,#endif	.update_jacks = ad1985_update_jacks,};int patch_ad1985(ac97_t * ac97){	unsigned short misc;		patch_ad1881(ac97);	ac97->build_ops = &patch_ad1985_build_ops;	misc = snd_ac97_read(ac97, AC97_AD_MISC);	/* switch front/surround line-out/hp-out */	/* center/LFE, mic in 3.75V mode */	/* AD-compatible mode */	/* Stereo mutes enabled */	/* in accordance with ADI driver: misc | 0x5c28 */	snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |			     AC97_AD198X_VREFH |			     AC97_AD198X_LOSEL |			     AC97_AD198X_HPSEL |			     AC97_AD198X_CLDIS |			     AC97_AD198X_LODIS |			     AC97_AD198X_MSPLT |			     AC97_AD198X_AC97NC);	ac97->flags |= AC97_STEREO_MUTES;	/* on AD1985 rev. 3, AC'97 revision bits are zero */	ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;	return 0;}/* * realtek ALC65x/850 codecs */static void alc650_update_jacks(ac97_t *ac97){	int shared;		/* shared Line-In */	shared = is_shared_linein(ac97);	snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,			     shared ? (1 << 9) : 0);	/* update shared Mic */	shared = is_shared_micin(ac97);	/* disable/enable vref */	snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,			     shared ? (1 << 12) : 0);	/* turn on/off center-on-mic */	snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,			     shared ? (1 << 10) : 0);	/* GPIO0 high for mic */	snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,			     shared ? 0 : 0x100);}static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = {	AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),	AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),	AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),	AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),	/* 4: Analog Input To Surround */	/* 5: Analog Input To Center/LFE */	/* 6: Independent Master Volume Right */	/* 7: Independent Master Volume Left */	/* 8: reserved */	/* 9: Line-In/Surround share */	/* 10: Mic/CLFE share */	/* 11-13: in IEC958 controls */	AC97_SINGLE("Swap Surround Slot", AC97_AL

⌨️ 快捷键说明

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