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

📄 patch_sigmatel.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int err;	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)		return err;	if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)		return err;	if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)		return err;	if (spec->autocfg.dig_out_pin)		spec->multiout.dig_out_nid = 0x05;	if (spec->autocfg.dig_in_pin)		spec->dig_in_nid = 0x04;	if (spec->kctl_alloc)		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;	spec->input_mux = &spec->private_imux;	return 1;}static int stac92xx_init(struct hda_codec *codec){	struct sigmatel_spec *spec = codec->spec;	struct auto_pin_cfg *cfg = &spec->autocfg;	int i;	snd_hda_sequence_write(codec, spec->init);	/* set up pins */	if (spec->hp_detect) {		/* Enable unsolicited responses on the HP widget */		snd_hda_codec_write(codec, cfg->hp_pin, 0,				AC_VERB_SET_UNSOLICITED_ENABLE,				STAC_UNSOL_ENABLE);		/* fake event to set up pins */		codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);	} else {		stac92xx_auto_init_multi_out(codec);		stac92xx_auto_init_hp_out(codec);	}	for (i = 0; i < AUTO_PIN_LAST; i++) {		hda_nid_t nid = cfg->input_pins[i];		if (nid) {			unsigned int pinctl = AC_PINCTL_IN_EN;			if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)				pinctl |= stac92xx_get_vref(codec, nid);			stac92xx_auto_set_pinctl(codec, nid, pinctl);		}	}	if (cfg->dig_out_pin)		stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,					 AC_PINCTL_OUT_EN);	if (cfg->dig_in_pin)		stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,					 AC_PINCTL_IN_EN);	return 0;}static void stac92xx_free(struct hda_codec *codec){	struct sigmatel_spec *spec = codec->spec;	int i;	if (! spec)		return;	if (spec->kctl_alloc) {		for (i = 0; i < spec->num_kctl_used; i++)			kfree(spec->kctl_alloc[i].name);		kfree(spec->kctl_alloc);	}	kfree(spec);}static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,				unsigned int flag){	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);	snd_hda_codec_write(codec, nid, 0,			AC_VERB_SET_PIN_WIDGET_CONTROL,			pin_ctl | flag);}static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,				  unsigned int flag){	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);	snd_hda_codec_write(codec, nid, 0,			AC_VERB_SET_PIN_WIDGET_CONTROL,			pin_ctl & ~flag);}static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res){	struct sigmatel_spec *spec = codec->spec;	struct auto_pin_cfg *cfg = &spec->autocfg;	int i, presence;	if ((res >> 26) != STAC_HP_EVENT)		return;	presence = snd_hda_codec_read(codec, cfg->hp_pin, 0,			AC_VERB_GET_PIN_SENSE, 0x00) >> 31;	if (presence) {		/* disable lineouts, enable hp */		for (i = 0; i < cfg->line_outs; i++)			stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],						AC_PINCTL_OUT_EN);		stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);	} else {		/* enable lineouts, disable hp */		for (i = 0; i < cfg->line_outs; i++)			stac92xx_set_pinctl(codec, cfg->line_out_pins[i],						AC_PINCTL_OUT_EN);		stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);	}} #ifdef CONFIG_PMstatic int stac92xx_resume(struct hda_codec *codec){	struct sigmatel_spec *spec = codec->spec;	int i;	stac92xx_init(codec);	for (i = 0; i < spec->num_mixers; i++)		snd_hda_resume_ctls(codec, spec->mixers[i]);	if (spec->multiout.dig_out_nid)		snd_hda_resume_spdif_out(codec);	if (spec->dig_in_nid)		snd_hda_resume_spdif_in(codec);	return 0;}#endifstatic struct hda_codec_ops stac92xx_patch_ops = {	.build_controls = stac92xx_build_controls,	.build_pcms = stac92xx_build_pcms,	.init = stac92xx_init,	.free = stac92xx_free,	.unsol_event = stac92xx_unsol_event,#ifdef CONFIG_PM	.resume = stac92xx_resume,#endif};static int patch_stac9200(struct hda_codec *codec){	struct sigmatel_spec *spec;	int err;	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl);	if (spec->board_config < 0)                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");	else {		spec->num_pins = 8;		spec->pin_nids = stac9200_pin_nids;		spec->pin_configs = stac9200_brd_tbl[spec->board_config];		stac92xx_set_config_regs(codec);	}	spec->multiout.max_channels = 2;	spec->multiout.num_dacs = 1;	spec->multiout.dac_nids = stac9200_dac_nids;	spec->adc_nids = stac9200_adc_nids;	spec->mux_nids = stac9200_mux_nids;	spec->num_muxes = 1;	spec->init = stac9200_core_init;	spec->mixer = stac9200_mixer;	err = stac9200_parse_auto_config(codec);	if (err < 0) {		stac92xx_free(codec);		return err;	}	codec->patch_ops = stac92xx_patch_ops;	return 0;}static int patch_stac922x(struct hda_codec *codec){	struct sigmatel_spec *spec;	int err;	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);	if (spec->board_config < 0)                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");	else {		spec->num_pins = 10;		spec->pin_nids = stac922x_pin_nids;		spec->pin_configs = stac922x_brd_tbl[spec->board_config];		stac92xx_set_config_regs(codec);	}	spec->adc_nids = stac922x_adc_nids;	spec->mux_nids = stac922x_mux_nids;	spec->num_muxes = 2;	spec->init = stac922x_core_init;	spec->mixer = stac922x_mixer;	spec->multiout.dac_nids = spec->dac_nids;	err = stac92xx_parse_auto_config(codec, 0x08, 0x09);	if (err < 0) {		stac92xx_free(codec);		return err;	}	codec->patch_ops = stac92xx_patch_ops;	return 0;}static int patch_stac927x(struct hda_codec *codec){	struct sigmatel_spec *spec;	int err;	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl);	if (spec->board_config < 0)                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");	else {		spec->num_pins = 14;		spec->pin_nids = stac927x_pin_nids;		spec->pin_configs = stac927x_brd_tbl[spec->board_config];		stac92xx_set_config_regs(codec);	}	spec->adc_nids = stac927x_adc_nids;	spec->mux_nids = stac927x_mux_nids;	spec->num_muxes = 3;	spec->init = stac927x_core_init;	spec->mixer = stac927x_mixer;	spec->multiout.dac_nids = spec->dac_nids;	err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);	if (err < 0) {		stac92xx_free(codec);		return err;	}	codec->patch_ops = stac92xx_patch_ops;	return 0;}/* * STAC 7661(?) hack *//* static config for Sony VAIO FE550G */static hda_nid_t vaio_dacs[] = { 0x2 };#define VAIO_HP_DAC	0x5static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };static hda_nid_t vaio_mux_nids[] = { 0x15 };static struct hda_input_mux vaio_mux = {	.num_items = 2,	.items = {		/* { "HP", 0x0 }, */		{ "Line", 0x1 },		{ "Mic", 0x2 },		{ "PCM", 0x3 },	}};static struct hda_verb vaio_init[] = {	{0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */	{0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */	{0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */	{0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */	{}};/* bind volumes of both NID 0x02 and 0x05 */static int vaio_master_vol_put(struct snd_kcontrol *kcontrol,			       struct snd_ctl_elem_value *ucontrol){	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);	long *valp = ucontrol->value.integer.value;	int change;	change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,					  0x7f, valp[0] & 0x7f);	change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,					   0x7f, valp[1] & 0x7f);	snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,				 0x7f, valp[0] & 0x7f);	snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,				 0x7f, valp[1] & 0x7f);	return change;}/* bind volumes of both NID 0x02 and 0x05 */static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,			      struct snd_ctl_elem_value *ucontrol){	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);	long *valp = ucontrol->value.integer.value;	int change;	change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,					  0x80, (valp[0] ? 0 : 0x80));	change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,					   0x80, (valp[1] ? 0 : 0x80));	snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,				 0x80, (valp[0] ? 0 : 0x80));	snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,				 0x80, (valp[1] ? 0 : 0x80));	return change;}static struct snd_kcontrol_new vaio_mixer[] = {	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Master Playback Volume",		.info = snd_hda_mixer_amp_volume_info,		.get = snd_hda_mixer_amp_volume_get,		.put = vaio_master_vol_put,		.private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Master Playback Switch",		.info = snd_hda_mixer_amp_switch_info,		.get = snd_hda_mixer_amp_switch_get,		.put = vaio_master_sw_put,		.private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),	},	/* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),	HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Capture Source",		.count = 1,		.info = stac92xx_mux_enum_info,		.get = stac92xx_mux_enum_get,		.put = stac92xx_mux_enum_put,	},	{}};static struct hda_codec_ops stac7661_patch_ops = {	.build_controls = stac92xx_build_controls,	.build_pcms = stac92xx_build_pcms,	.init = stac92xx_init,	.free = stac92xx_free,#ifdef CONFIG_PM	.resume = stac92xx_resume,#endif};enum { STAC7661_VAIO };static struct hda_board_config stac7661_cfg_tbl[] = {	{ .modelname = "vaio", .config = STAC7661_VAIO },	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6,	  .config = STAC7661_VAIO },	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef,	  .config = STAC7661_VAIO },	{}};static int patch_stac7661(struct hda_codec *codec){	struct sigmatel_spec *spec;	int board_config;	board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl);	if (board_config < 0)		/* unknown config, let generic-parser do its job... */		return snd_hda_parse_generic_codec(codec);		spec  = kzalloc(sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	switch (board_config) {	case STAC7661_VAIO:		spec->mixer = vaio_mixer;		spec->init = vaio_init;		spec->multiout.max_channels = 2;		spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);		spec->multiout.dac_nids = vaio_dacs;		spec->multiout.hp_nid = VAIO_HP_DAC;		spec->num_adcs = ARRAY_SIZE(vaio_adcs);		spec->adc_nids = vaio_adcs;		spec->input_mux = &vaio_mux;		spec->mux_nids = vaio_mux_nids;		break;	}	codec->patch_ops = stac7661_patch_ops;	return 0;}/* * patch entries */struct hda_codec_preset snd_hda_preset_sigmatel[] = { 	{ .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 	{ .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 	{ .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 	{ .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, 	{ .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, 	{ .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, 	{ .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, 	{ .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, 	{ .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, 	{ .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, 	{ .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x }, 	{ .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x }, 	{ .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x }, 	{ .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x }, 	{ .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, 	{ .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, 	{ .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, 	{ .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 },	{} /* terminator */};

⌨️ 快捷键说明

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