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

📄 patch_via.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		.open = via_playback_pcm_open,		.prepare = via_playback_pcm_prepare,		.cleanup = via_playback_pcm_cleanup	},};static struct hda_pcm_stream vt1709_pcm_analog_capture = {	.substreams = 2,	.channels_min = 2,	.channels_max = 2,	.nid = 0x14, /* NID to query formats and rates */	.ops = {		.prepare = via_capture_pcm_prepare,		.cleanup = via_capture_pcm_cleanup	},};static struct hda_pcm_stream vt1709_pcm_digital_playback = {	.substreams = 1,	.channels_min = 2,	.channels_max = 2,	/* NID is set in via_build_pcms */	.ops = {		.open = via_dig_playback_pcm_open,		.close = via_dig_playback_pcm_close	},};static struct hda_pcm_stream vt1709_pcm_digital_capture = {	.substreams = 1,	.channels_min = 2,	.channels_max = 2,};static int vt1709_auto_fill_dac_nids(struct via_spec *spec,				     const struct auto_pin_cfg *cfg){	int i;	hda_nid_t nid;	if (cfg->line_outs == 4)  /* 10 channels */		spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */	else if (cfg->line_outs == 3) /* 6 channels */		spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */	spec->multiout.dac_nids = spec->private_dac_nids;	if (cfg->line_outs == 4) { /* 10 channels */		for (i = 0; i < cfg->line_outs; i++) {			nid = cfg->line_out_pins[i];			if (nid) {				/* config dac list */				switch (i) {				case AUTO_SEQ_FRONT:					/* AOW0 */					spec->multiout.dac_nids[i] = 0x10;					break;				case AUTO_SEQ_CENLFE:					/* AOW2 */					spec->multiout.dac_nids[i] = 0x12;					break;				case AUTO_SEQ_SURROUND:					/* AOW3 */					spec->multiout.dac_nids[i] = 0x27;					break;				case AUTO_SEQ_SIDE:					/* AOW1 */					spec->multiout.dac_nids[i] = 0x11;					break;				default:					break;				}			}		}		spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */	} else if (cfg->line_outs == 3) { /* 6 channels */		for(i = 0; i < cfg->line_outs; i++) {			nid = cfg->line_out_pins[i];			if (nid) {				/* config dac list */				switch(i) {				case AUTO_SEQ_FRONT:					/* AOW0 */					spec->multiout.dac_nids[i] = 0x10;					break;				case AUTO_SEQ_CENLFE:					/* AOW2 */					spec->multiout.dac_nids[i] = 0x12;					break;				case AUTO_SEQ_SURROUND:					/* AOW1 */					spec->multiout.dac_nids[i] = 0x11;					break;				default:					break;				}			}		}	}	return 0;}/* add playback controls from the parsed DAC table */static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,					     const struct auto_pin_cfg *cfg){	char name[32];	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };	hda_nid_t nid = 0;	int i, err;	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {		nid = cfg->line_out_pins[i];		if (!nid)				continue;		if (i == AUTO_SEQ_CENLFE) {			/* Center/LFE */			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,					      "Center Playback Volume",					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));			if (err < 0)				return err;			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,					      "LFE Playback Volume",					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));			if (err < 0)				return err;			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,					      "Center Playback Switch",					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));			if (err < 0)				return err;			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,					      "LFE Playback Switch",					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));			if (err < 0)				return err;		} else if (i == AUTO_SEQ_FRONT){			/* add control to mixer index 0 */			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,					      "Master Front Playback Volume",					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));			if (err < 0)				return err;			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,					      "Master Front Playback Switch",					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));			if (err < 0)				return err;						/* add control to PW3 */			sprintf(name, "%s Playback Volume", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;			sprintf(name, "%s Playback Switch", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;		} else if (i == AUTO_SEQ_SURROUND) {			sprintf(name, "%s Playback Volume", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;			sprintf(name, "%s Playback Switch", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;		} else if (i == AUTO_SEQ_SIDE) {			sprintf(name, "%s Playback Volume", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;			sprintf(name, "%s Playback Switch", chname[i]);			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));			if (err < 0)				return err;		}	}	return 0;}static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin){	int err;	if (!pin)		return 0;	if (spec->multiout.num_dacs == 5) /* 10 channels */		spec->multiout.hp_nid = VT1709_HP_DAC_NID;	else if (spec->multiout.num_dacs == 3) /* 6 channels */		spec->multiout.hp_nid = 0;	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,			      "Headphone Playback Volume",			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));	if (err < 0)		return err;	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,			      "Headphone Playback Switch",			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));	if (err < 0)		return err;	return 0;}/* create playback/capture controls for input pins */static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,						const struct auto_pin_cfg *cfg){	static char *labels[] = {		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL	};	struct hda_input_mux *imux = &spec->private_imux;	int i, err, idx = 0;	/* for internal loopback recording select */	imux->items[imux->num_items].label = "Stereo Mixer";	imux->items[imux->num_items].index = idx;	imux->num_items++;	for (i = 0; i < AUTO_PIN_LAST; i++) {		if (!cfg->input_pins[i])			continue;		switch (cfg->input_pins[i]) {		case 0x1d: /* Mic */			idx = 2;			break;						case 0x1e: /* Line In */			idx = 3;			break;		case 0x21: /* Front Mic */			idx = 4;			break;		case 0x23: /* CD */			idx = 1;			break;		}		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],					   idx, 0x18);		if (err < 0)			return err;		imux->items[imux->num_items].label = labels[i];		imux->items[imux->num_items].index = idx;		imux->num_items++;	}	return 0;}static int vt1709_parse_auto_config(struct hda_codec *codec){	struct via_spec *spec = codec->spec;	int err;	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);	if (err < 0)		return err;	err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);	if (err < 0)		return err;	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])		return 0; /* can't find valid BIOS pin config */	err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);	if (err < 0)		return err;	err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);	if (err < 0)		return err;	err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);	if (err < 0)		return err;	spec->multiout.max_channels = spec->multiout.num_dacs * 2;	if (spec->autocfg.dig_out_pin)		spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;	if (spec->autocfg.dig_in_pin)		spec->dig_in_nid = VT1709_DIGIN_NID;	if (spec->kctl_alloc)		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;	spec->input_mux = &spec->private_imux;	return 1;}#ifdef CONFIG_SND_HDA_POWER_SAVEstatic struct hda_amp_list vt1709_loopbacks[] = {	{ 0x18, HDA_INPUT, 1 },	{ 0x18, HDA_INPUT, 2 },	{ 0x18, HDA_INPUT, 3 },	{ 0x18, HDA_INPUT, 4 },	{ } /* end */};#endifstatic int patch_vt1709_10ch(struct hda_codec *codec){	struct via_spec *spec;	int err;	/* create a codec specific record */	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	err = vt1709_parse_auto_config(codec);	if (err < 0) {		via_free(codec);		return err;	} else if (!err) {		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "		       "Using genenic mode...\n");	}	spec->init_verbs = vt1709_10ch_volume_init_verbs;		spec->stream_name_analog = "VT1709 Analog";	spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;	spec->stream_analog_capture = &vt1709_pcm_analog_capture;	spec->stream_name_digital = "VT1709 Digital";	spec->stream_digital_playback = &vt1709_pcm_digital_playback;	spec->stream_digital_capture = &vt1709_pcm_digital_capture;		if (!spec->adc_nids && spec->input_mux) {		spec->adc_nids = vt1709_adc_nids;		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;		spec->num_mixers++;	}	codec->patch_ops = via_patch_ops;	codec->patch_ops.init = via_auto_init;#ifdef CONFIG_SND_HDA_POWER_SAVE	spec->loopback.amplist = vt1709_loopbacks;#endif	return 0;}/* * generic initialization of ADC, input mixers and output mixers */static struct hda_verb vt1709_6ch_volume_init_verbs[] = {	/*	 * Unmute ADC0-2 and set the default input to mic-in	 */	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback	 * mixer widget	 */	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},	/*	 * Set up output selector (0x1a, 0x1b, 0x29)	 */	/* set vol=0 to output mixers */	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},	/*	 *  Unmute PW3 and PW4	 */	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},	/* Set input of PW4 as MW0 */	{0x20, AC_VERB_SET_CONNECT_SEL, 0},	/* Set mic as default input of sw0 */	{0x19, AC_VERB_SET_CONNECT_SEL, 0x2},	/* PW9 Output enable */	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},	{ }};static int patch_vt1709_6ch(struct hda_codec *codec){	struct via_spec *spec;	int err;	/* create a codec specific record */	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);	if (spec == NULL)		return -ENOMEM;	codec->spec = spec;	err = vt1709_parse_auto_config(codec);	if (err < 0) {		via_free(codec);		return err;	} else if (!err) {		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "		       "Using genenic mode...\n");	}	spec->init_verbs = vt1709_6ch_volume_init_verbs;		spec->stream_name_analog = "VT1709 Analog";	spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;	spec->stream_analog_capture = &vt1709_pcm_analog_capture;	spec->stream_name_digital = "VT1709 Digital";	spec->stream_digital_playback = &vt1709_pcm_digital_playback;	spec->stream_digital_capture = &vt1709_pcm_digital_capture;		if (!spec->adc_nids && spec->input_mux) {		spec->adc_nids = vt1709_adc_nids;		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;		spec->num_mixers++;	}	codec->patch_ops = via_patch_ops;	codec->patch_ops.init = via_auto_init;#ifdef CONFIG_SND_HDA_POWER_SAVE	spec->loopback.amplist = vt1709_loopbacks;#endif	return 0;}/* * patch entries */struct hda_codec_preset snd_hda_preset_via[] = {	{ .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},	{ .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},	{ .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},	{ .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},	{ .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},	{ .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},	{ .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},	{ .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},	{ .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},	{ .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},	{ .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},	{ .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},	{} /* terminator */};

⌨️ 快捷键说明

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