[alsa-devel] model needed for Clevo P150HM (Realtek ALC892)

Takashi Iwai tiwai at suse.de
Fri Jun 24 11:12:59 CEST 2011


At Fri, 24 Jun 2011 10:34:01 +0200,
Takashi Iwai wrote:
> 
> At Thu, 23 Jun 2011 18:40:47 +0200,
> Julian Sikorski wrote:
> > 
> > On 23/06/2011 14:41, Takashi Iwai wrote:
> > > At Thu, 23 Jun 2011 08:36:55 +0200,
> > > Julian Sikorski wrote:
> > >>
> > >> Hi,
> > >>
> > >> I am coming here from pulseaudio-general mailing list [1]. I recently
> > >> got myself a Clevo P150HM laptop. It has 2.1 speakers, a built-in
> > >> microphone and the following connectors:
> > >> - headphone out
> > >> - microphone in; can be switched to center/lfe out
> > >> - spdif out; can be switched to rear speaker out
> > >> - line in; can be switched to side speaker out
> > >> Alsa does not seem to reflect that the device is capable of 5.1 and 7.1
> > >> sound, and there are two configs showing up in pavucontrol (analog
> > >> output and analog headphones) which seem to be the same. I have uploaded
> > >> the output of alsa-info.sh [2]. Please let me know if more information
> > >> is needed.
> > >
> > > The current parser doesn't allow the multi-io pins when the primary
> > > output is no line-out.  The patch below should fix (change) the
> > > behavior.  It'll count HP out, too.
> > >
> > >
> > > Takashi
> > >
> > > ---
> > > diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> > > index fe56b2b..b0cf726 100644
> > > --- a/sound/pci/hda/patch_realtek.c
> > > +++ b/sound/pci/hda/patch_realtek.c
> > > @@ -18992,6 +18992,7 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
> > >   	hda_nid_t dac;
> > >
> > >   	spec->multiout.dac_nids = spec->private_dac_nids;
> > > +	spec->multiout.num_dacs = 0;
> > >   	for (i = 0; i<  cfg->line_outs; i++) {
> > >   		dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
> > >   		if (!dac)
> > > @@ -19326,8 +19327,20 @@ static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
> > >   	unsigned int location, defcfg;
> > >   	int num_pins;
> > >
> > > +	if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT&&  cfg->hp_outs == 1) {
> > > +		/* use HP as primary out */
> > > +		cfg->speaker_outs = cfg->line_outs;
> > > +		memcpy(cfg->speaker_pins, cfg->line_out_pins,
> > > +		       sizeof(cfg->speaker_pins));
> > > +		cfg->line_outs = cfg->hp_outs;
> > > +		memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
> > > +		cfg->hp_outs = 0;
> > > +		memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
> > > +		cfg->line_out_type = AUTO_PIN_HP_OUT;
> > > +		alc662_auto_fill_dac_nids(codec, cfg);
> > > +	}
> > >   	if (cfg->line_outs != 1 ||
> > > -	    cfg->line_out_type != AUTO_PIN_LINE_OUT)
> > > +	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> > >   		return 0;
> > >
> > >   	defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
> > > @@ -19348,6 +19361,8 @@ static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
> > >   		spec->multi_ios = num_pins;
> > >   		spec->ext_channel_count = 2;
> > >   		spec->multiout.num_dacs = num_pins + 1;
> > > +		/* for avoiding multi HP mixers */
> > > +		cfg->line_out_type = AUTO_PIN_LINE_OUT;
> > >   	}
> > >   	return 0;
> > >   }
> > Would you like me to test this patch? If so, what should I apply it to 
> > and how should I proceed?
> 
> Yes, the test would be appreciated, of course.
> Apply it to the latest 3.0-rc kernel and test.

Also, the additional patch below will give "Headphone" mixer control
back while new "Surround", "Center" and "LFE" will appear.

Note that you'll need to change "Channel Mode" mixer control to "6ch"
for using the surround outputs even with these patches.  As default,
it's set as "2ch".


Takashi

---
Subject: [PATCH] ALSA: hda - Clean up multi-channel mixer name assignment in
 patch_realtek.c

Change alc_get_line_out_pfx() in patch_realtek.c to provide the channel
specific name and assign the index so that each caller doesn't have to
set the channel name by itself.

Also, check the multi-io case with the primary hp-out; for the multi-io
channels, assign the channel name instead of "Headphone" with indices.
This makes the mixer names more intuitive and reduces confusion.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/pci/hda/patch_realtek.c |   92 ++++++++++++++++-------------------------
 1 files changed, 36 insertions(+), 56 deletions(-)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b0cf726..7858da5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5359,11 +5359,15 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
 	return 0;
 }
 
-static const char *alc_get_line_out_pfx(struct alc_spec *spec,
-					bool can_be_master)
+static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
+					bool can_be_master, int *index)
 {
 	struct auto_pin_cfg *cfg = &spec->autocfg;
+	static const char * const chname[4] = {
+		"Front", "Surround", NULL /*CLFE*/, "Side"
+	};
 
+	*index = 0;
 	if (cfg->line_outs == 1 && !spec->multi_ios &&
 	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
 		return "Master";
@@ -5374,23 +5378,23 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec,
 			return "Speaker";
 		break;
 	case AUTO_PIN_HP_OUT:
+		/* for multi-io case, only the primary out */
+		if (ch && spec->multi_ios)
+			break;
+		*index = ch;
 		return "Headphone";
 	default:
 		if (cfg->line_outs == 1 && !spec->multi_ios)
 			return "PCM";
 		break;
 	}
-	return NULL;
+	return chname[ch];
 }
 
 /* add playback controls from the parsed DAC table */
 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
 					     const struct auto_pin_cfg *cfg)
 {
-	static const char * const chname[4] = {
-		"Front", "Surround", NULL /*CLFE*/, "Side"
-	};
-	const char *pfx = alc_get_line_out_pfx(spec, false);
 	hda_nid_t nid;
 	int i, err, noutputs;
 
@@ -5399,10 +5403,13 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
 		noutputs += spec->multi_ios;
 
 	for (i = 0; i < noutputs; i++) {
+		const char *name;
+		int index;
 		if (!spec->multiout.dac_nids[i])
 			continue;
 		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
-		if (!pfx && i == 2) {
+		name = alc_get_line_out_pfx(spec, i, false, &index);
+		if (!name) {
 			/* Center/LFE */
 			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
 					      "Center",
@@ -5429,12 +5436,6 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
 			if (err < 0)
 				return err;
 		} else {
-			const char *name = pfx;
-			int index = i;
-			if (!name) {
-				name = chname[i];
-				index = 0;
-			}
 			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
 						name, index,
 					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
@@ -12257,17 +12258,18 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
 {
 	const char *pfx;
 	int vbits;
-	int i, err;
+	int i, index, err;
 
 	spec->multiout.num_dacs = 1;	/* only use one dac */
 	spec->multiout.dac_nids = spec->private_dac_nids;
 	spec->private_dac_nids[0] = 2;
 
-	pfx = alc_get_line_out_pfx(spec, true);
-	if (!pfx)
-		pfx = "Front";
 	for (i = 0; i < 2; i++) {
-		err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
+		pfx = alc_get_line_out_pfx(spec, i, true, &index);
+		if (!pfx)
+			pfx = "PCM";
+		err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
+					    index);
 		if (err < 0)
 			return err;
 		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
@@ -12287,10 +12289,11 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
 	vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
 		alc262_check_volbit(cfg->speaker_pins[0]) |
 		alc262_check_volbit(cfg->hp_pins[0]);
-	if (vbits == 1 || vbits == 2)
-		pfx = "Master"; /* only one mixer is used */
 	vbits = 0;
 	for (i = 0; i < 2; i++) {
+		pfx = alc_get_line_out_pfx(spec, i, true, &index);
+		if (!pfx)
+			pfx = "PCM";
 		err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
 					     &vbits, i);
 		if (err < 0)
@@ -16035,10 +16038,6 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
 					     const struct auto_pin_cfg *cfg)
 {
 	struct alc_spec *spec = codec->spec;
-	static const char * const chname[4] = {
-		"Front", "Surround", NULL /*CLFE*/, "Side"
-	};
-	const char *pfx = alc_get_line_out_pfx(spec, true);
 	hda_nid_t nid;
 	int i, err, noutputs;
 
@@ -16047,10 +16046,13 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
 		noutputs += spec->multi_ios;
 
 	for (i = 0; i < noutputs; i++) {
+		const char *name;
+		int index;
 		nid = spec->multiout.dac_nids[i];
 		if (!nid)
 			continue;
-		if (!pfx && i == 2) {
+		name = alc_get_line_out_pfx(spec, i, true, &index);
+		if (!name) {
 			/* Center/LFE */
 			err = alc861_create_out_sw(codec, "Center", nid, 1);
 			if (err < 0)
@@ -16059,12 +16061,6 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
 			if (err < 0)
 				return err;
 		} else {
-			const char *name = pfx;
-			int index = i;
-			if (!name) {
-				name = chname[i];
-				index = 0;
-			}
 			err = __alc861_create_out_sw(codec, name, nid, index, 3);
 			if (err < 0)
 				return err;
@@ -17178,10 +17174,6 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 					     const struct auto_pin_cfg *cfg)
 {
-	static const char * const chname[4] = {
-		"Front", "Surround", "CLFE", "Side"
-	};
-	const char *pfx = alc_get_line_out_pfx(spec, true);
 	hda_nid_t nid_v, nid_s;
 	int i, err, noutputs;
 
@@ -17190,6 +17182,8 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 		noutputs += spec->multi_ios;
 
 	for (i = 0; i < noutputs; i++) {
+		const char *name;
+		int index;
 		if (!spec->multiout.dac_nids[i])
 			continue;
 		nid_v = alc861vd_idx_to_mixer_vol(
@@ -17199,7 +17193,8 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 				alc880_dac_to_idx(
 					spec->multiout.dac_nids[i]));
 
-		if (!pfx && i == 2) {
+		name = alc_get_line_out_pfx(spec, i, true, &index);
+		if (!name) {
 			/* Center/LFE */
 			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
 					      "Center",
@@ -17226,12 +17221,6 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 			if (err < 0)
 				return err;
 		} else {
-			const char *name = pfx;
-			int index = i;
-			if (!name) {
-				name = chname[i];
-				index = 0;
-			}
 			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
 						name, index,
 					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
@@ -19030,10 +19019,6 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
 					     const struct auto_pin_cfg *cfg)
 {
 	struct alc_spec *spec = codec->spec;
-	static const char * const chname[4] = {
-		"Front", "Surround", NULL /*CLFE*/, "Side"
-	};
-	const char *pfx = alc_get_line_out_pfx(spec, true);
 	hda_nid_t nid, mix, pin;
 	int i, err, noutputs;
 
@@ -19042,6 +19027,8 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
 		noutputs += spec->multi_ios;
 
 	for (i = 0; i < noutputs; i++) {
+		const char *name;
+		int index;
 		nid = spec->multiout.dac_nids[i];
 		if (!nid)
 			continue;
@@ -19052,7 +19039,8 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
 		mix = alc_auto_dac_to_mix(codec, pin, nid);
 		if (!mix)
 			continue;
-		if (!pfx && i == 2) {
+		name = alc_get_line_out_pfx(spec, i, true, &index);
+		if (!name) {
 			/* Center/LFE */
 			err = alc662_add_vol_ctl(spec, "Center", nid, 1);
 			if (err < 0)
@@ -19067,12 +19055,6 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
 			if (err < 0)
 				return err;
 		} else {
-			const char *name = pfx;
-			int index = i;
-			if (!name) {
-				name = chname[i];
-				index = 0;
-			}
 			err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
 			if (err < 0)
 				return err;
@@ -19361,8 +19343,6 @@ static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
 		spec->multi_ios = num_pins;
 		spec->ext_channel_count = 2;
 		spec->multiout.num_dacs = num_pins + 1;
-		/* for avoiding multi HP mixers */
-		cfg->line_out_type = AUTO_PIN_LINE_OUT;
 	}
 	return 0;
 }
-- 
1.7.5.4



More information about the Alsa-devel mailing list