[PATCH] [UBUNTU:sound/pci/hda/] Really merge patch_realtek.c from upstream alsa-driver 1.0.11

crimsun at fungus.sh.nu crimsun at fungus.sh.nu
Tue May 16 17:49:26 UTC 2006


Subject: [PATCH] [UBUNTU:sound/pci/hda/] Really merge patch_realtek.c from upstream alsa-driver 1.0.11

UpstreamStatus: Already in upstream alsa-driver 1.0.11

This commit actually contains all the merges from upstream alsa-driver
1.0.11 against our Linux source with the xxx_t typedefs. (I was wonder-
ing why the changes were so minimal after that first merge, and lo and
behold, the PEBKAC of grep gone awry...)

This commit closes Malone #44814. Really.

Signed-off-by: Daniel T Chen <crimsun at ubuntu.com>

---

 sound/pci/hda/patch_realtek.c |  302 +++++++++++++++++++++++++++++++++--------
 1 files changed, 245 insertions(+), 57 deletions(-)

7b70006b04c3ea2537b538af46a6a405912ff8c3
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d0e92e5..0401353 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -52,6 +52,7 @@ enum {
 	ALC880_CLEVO,
 	ALC880_TCL_S700,
 	ALC880_LG,
+	ALC880_LG_LW,
 #ifdef CONFIG_SND_DEBUG
 	ALC880_TEST,
 #endif
@@ -131,6 +132,7 @@ struct alc_spec {
 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
 
 	/* capture source */
+	unsigned int num_mux_defs;
 	const struct hda_input_mux *input_mux;
 	unsigned int cur_mux[3];
 
@@ -172,6 +174,7 @@ struct alc_config_preset {
 	hda_nid_t dig_in_nid;
 	unsigned int num_channel_mode;
 	const struct hda_channel_mode *channel_mode;
+	unsigned int num_mux_defs;
 	const struct hda_input_mux *input_mux;
 	void (*unsol_event)(struct hda_codec *, unsigned int);
 	void (*init_hook)(struct hda_codec *);
@@ -185,7 +188,10 @@ static int alc_mux_enum_info(snd_kcontro
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
-	return snd_hda_input_mux_info(spec->input_mux, uinfo);
+	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
+	if (mux_idx >= spec->num_mux_defs)
+		mux_idx = 0;
+	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
 }
 
 static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
@@ -203,7 +209,8 @@ static int alc_mux_enum_put(snd_kcontrol
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
+	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
 				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
 }
 
@@ -245,7 +252,8 @@ static int alc_ch_mode_put(snd_kcontrol_
  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
  * are requested.  Therefore order this list so that this behaviour will not
  * cause problems when mixer clients move through the enum sequentially.
- * NIDs 0x0f and 0x10 have been observed to have this behaviour.
+ * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
+ * March 2006.
  */
 static char *alc_pin_mode_names[] = {
 	"Mic 50pc bias", "Mic 80pc bias",
@@ -255,19 +263,27 @@ static unsigned char alc_pin_mode_values
 	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
 };
 /* The control can present all 5 options, or it can limit the options based
- * in the pin being assumed to be exclusively an input or an output pin.
- */
-#define ALC_PIN_DIR_IN    0x00
-#define ALC_PIN_DIR_OUT   0x01
-#define ALC_PIN_DIR_INOUT 0x02
+ * in the pin being assumed to be exclusively an input or an output pin.  In
+ * addition, "input" pins may or may not process the mic bias option
+ * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
+ * accept requests for bias as of chip versions up to March 2006) and/or
+ * wiring in the computer.
+ */
+#define ALC_PIN_DIR_IN              0x00
+#define ALC_PIN_DIR_OUT             0x01
+#define ALC_PIN_DIR_INOUT           0x02
+#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
+#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
 
-/* Info about the pin modes supported by the three different pin directions. 
+/* Info about the pin modes supported by the different pin direction modes. 
  * For each direction the minimum and maximum values are given.
  */
-static signed char alc_pin_mode_dir_info[3][2] = {
+static signed char alc_pin_mode_dir_info[5][2] = {
 	{ 0, 2 },    /* ALC_PIN_DIR_IN */
 	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
 	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
+	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
+	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
 };
 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
@@ -329,9 +345,10 @@ static int alc_pin_mode_put(snd_kcontrol
 		 * input modes.
 		 *
 		 * Dynamically switching the input/output buffers probably
-		 * reduces noise slightly, particularly on input.  However,
-		 * havingboth input and output buffers enabled
-		 * simultaneously doesn't seem to be problematic.
+		 * reduces noise slightly (particularly on input) so we'll
+		 * do it.  However, having both input and output buffers
+		 * enabled simultaneously doesn't seem to be problematic if
+		 * this turns out to be necessary in the future.
 		 */
 		if (val <= 2) {
 			snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
@@ -483,6 +500,9 @@ static void setup_preset(struct alc_spec
 	spec->multiout.dig_out_nid = preset->dig_out_nid;
 	spec->multiout.hp_nid = preset->hp_nid;
 	
+	spec->num_mux_defs = preset->num_mux_defs;
+	if (! spec->num_mux_defs)
+		spec->num_mux_defs = 1;
 	spec->input_mux = preset->input_mux;
 
 	spec->num_adc_nids = preset->num_adc_nids;
@@ -1427,6 +1447,82 @@ static void alc880_lg_unsol_event(struct
 }
 
 /*
+ * LG LW20
+ *
+ * Pin assignment:
+ *   Speaker-out: 0x14
+ *   Mic-In: 0x18
+ *   Built-in Mic-In: 0x19 (?)
+ *   HP-Out: 0x1b
+ *   SPDIF-Out: 0x1e
+ */
+
+/* seems analog CD is not working */
+static struct hda_input_mux alc880_lg_lw_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Internal Mic", 0x1 },
+	},
+};
+
+static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
+	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+	{ } /* end */
+};
+
+static struct hda_verb alc880_lg_lw_init_verbs[] = {
+	/* set capture source to mic-in */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
+	/* speaker-out */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* HP-out */
+	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* mic-in to input */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* built-in mic */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* jack sense */
+	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
+	{ }
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc880_lg_lw_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x1b, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+}
+
+static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	/* Looks like the unsol event is incompatible with the standard
+	 * definition.  4bit tag is placed at 28 bit!
+	 */
+	if ((res >> 28) == 0x01)
+		alc880_lg_lw_automute(codec);
+}
+
+/*
  * Common callbacks
  */
 
@@ -2052,6 +2148,7 @@ static struct hda_board_config alc880_cf
 	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
 	{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
 	{ .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
+	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
 
 	{ .modelname = "asus", .config = ALC880_ASUS },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
@@ -2065,6 +2162,7 @@ static struct hda_board_config alc880_cf
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */
 	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
 
 	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
@@ -2077,6 +2175,9 @@ static struct hda_board_config alc880_cf
 	{ .modelname = "lg", .config = ALC880_LG },
 	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
 
+	{ .modelname = "lg-lw", .config = ALC880_LG_LW },
+	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
+
 #ifdef CONFIG_SND_DEBUG
 	{ .modelname = "test", .config = ALC880_TEST },
 #endif
@@ -2267,6 +2368,19 @@ static struct alc_config_preset alc880_p
 		.unsol_event = alc880_lg_unsol_event,
 		.init_hook = alc880_lg_automute,
 	},
+	[ALC880_LG_LW] = {
+		.mixers = { alc880_lg_lw_mixer },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_lg_lw_init_verbs },
+		.num_dacs = 1, 
+		.dac_nids = alc880_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
+		.channel_mode = alc880_2_jack_modes,
+		.input_mux = &alc880_lg_lw_capture_source,
+		.unsol_event = alc880_lg_lw_unsol_event,
+		.init_hook = alc880_lg_lw_automute,
+	},
 #ifdef CONFIG_SND_DEBUG
 	[ALC880_TEST] = {
 		.mixers = { alc880_test_mixer },
@@ -2592,6 +2706,7 @@ static int alc880_parse_auto_config(stru
 
 	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
 
+	spec->num_mux_defs = 1;
 	spec->input_mux = &spec->private_imux;
 
 	return 1;
@@ -2721,30 +2836,56 @@ static struct hda_input_mux alc260_captu
 };
 
 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
- * headphone jack and the internal CD lines.
+ * headphone jack and the internal CD lines since these are the only pins at
+ * which audio can appear.  For flexibility, also allow the option of
+ * recording the mixer output on the second ADC (ADC0 doesn't have a
+ * connection to the mixer output).
  */
-static struct hda_input_mux alc260_fujitsu_capture_source = {
-	.num_items = 3,
-	.items = {
-		{ "Mic/Line", 0x0 },
-		{ "CD", 0x4 },
-		{ "Headphone", 0x2 },
+static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
+	{
+		.num_items = 3,
+		.items = {
+			{ "Mic/Line", 0x0 },
+			{ "CD", 0x4 },
+			{ "Headphone", 0x2 },
+		},
 	},
+	{
+		.num_items = 4,
+		.items = {
+			{ "Mic/Line", 0x0 },
+			{ "CD", 0x4 },
+			{ "Headphone", 0x2 },
+			{ "Mixer", 0x5 },
+		},
+	},
+
 };
 
-/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configutation to
- * the Fujitsu S702x, but jacks are marked differently. We won't allow
- * retasking the Headphone jack, so it won't be available here.
+/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
+ * the Fujitsu S702x, but jacks are marked differently.
  */
-static struct hda_input_mux alc260_acer_capture_source = {
-	.num_items = 3,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
+static struct hda_input_mux alc260_acer_capture_sources[2] = {
+	{
+		.num_items = 4,
+		.items = {
+			{ "Mic", 0x0 },
+			{ "Line", 0x2 },
+			{ "CD", 0x4 },
+			{ "Headphone", 0x5 },
+		},
+	},
+	{
+		.num_items = 5,
+		.items = {
+			{ "Mic", 0x0 },
+			{ "Line", 0x2 },
+			{ "CD", 0x4 },
+			{ "Headphone", 0x6 },
+			{ "Mixer", 0x5 },
+		},
 	},
 };
-
 /*
  * This is just place-holder, so there's something for alc_build_pcms to look
  * at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2805,6 +2946,9 @@ static snd_kcontrol_new_t alc260_hp_3013
 	{ } /* end */
 };
 
+/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
+ * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
+ */
 static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
@@ -2821,9 +2965,28 @@ static snd_kcontrol_new_t alc260_fujitsu
 	{ } /* end */
 };
 
+/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
+ * versions of the ALC260 don't act on requests to enable mic bias from NID
+ * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
+ * datasheet doesn't mention this restriction.  At this stage it's not clear
+ * whether this behaviour is intentional or is a hardware bug in chip
+ * revisions available in early 2006.  Therefore for now allow the
+ * "Headphone Jack Mode" control to span all choices, but if it turns out
+ * that the lack of mic bias for this NID is intentional we could change the
+ * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
+ *
+ * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
+ * don't appear to make the mic bias available from the "line" jack, even
+ * though the NID used for this jack (0x14) can supply it.  The theory is
+ * that perhaps Acer have included blocking capacitors between the ALC260
+ * and the output jack.  If this turns out to be the case for all such
+ * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
+ * to ALC_PIN_DIR_INOUT_NOMICBIAS.
+ */
 static snd_kcontrol_new_t alc260_acer_mixer[] = {
 	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
+	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -3037,7 +3200,8 @@ static struct hda_verb alc260_hp_3013_in
 };
 
 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
- * laptops.
+ * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
+ * audio = 0x16, internal speaker = 0x10.
  */
 static struct hda_verb alc260_fujitsu_init_verbs[] = {
 	/* Disable all GPIOs */
@@ -3184,10 +3348,10 @@ static struct hda_verb alc260_acer_init_
 	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
 
 	/* Do similar with the second ADC: mute capture input amp and
-	 * set ADC connection to line (on line1 pin)
+	 * set ADC connection to mic to match ALSA's default state.
 	 */
 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
+	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
 
 	/* Mute all inputs to mixer widget (even unconnected ones) */
 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
@@ -3212,26 +3376,35 @@ static hda_nid_t alc260_test_dac_nids[1]
 static hda_nid_t alc260_test_adc_nids[2] = {
 	0x04, 0x05,
 };
-/* This is a bit messy since the two input muxes in the ALC260 have slight
- * variations in their signal assignments.  The ideal way to deal with this
- * is to extend alc_spec.input_mux to allow a different input MUX for each
- * ADC.  For the purposes of the test model it's sufficient to just list
- * both options for affected signal indices.  The separate input mux
- * functionality only needs to be considered if a model comes along which
- * actually uses signals 0x5, 0x6 and 0x7 for something which makes sense to
- * record.
+/* For testing the ALC260, each input MUX needs its own definition since
+ * the signal assignments are different.  This assumes that the first ADC 
+ * is NID 0x04.
  */
-static struct hda_input_mux alc260_test_capture_source = {
-	.num_items = 8,
-	.items = {
-		{ "MIC1 pin", 0x0 },
-		{ "MIC2 pin", 0x1 },
-		{ "LINE1 pin", 0x2 },
-		{ "LINE2 pin", 0x3 },
-		{ "CD pin", 0x4 },
-		{ "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 },
-		{ "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 },
-		{ "HP-OUT pin (cap2 only)", 0x7 },
+static struct hda_input_mux alc260_test_capture_sources[2] = {
+	{
+		.num_items = 7,
+		.items = {
+			{ "MIC1 pin", 0x0 },
+			{ "MIC2 pin", 0x1 },
+			{ "LINE1 pin", 0x2 },
+			{ "LINE2 pin", 0x3 },
+			{ "CD pin", 0x4 },
+			{ "LINE-OUT pin", 0x5 },
+			{ "HP-OUT pin", 0x6 },
+		},
+        },
+	{
+		.num_items = 8,
+		.items = {
+			{ "MIC1 pin", 0x0 },
+			{ "MIC2 pin", 0x1 },
+			{ "LINE1 pin", 0x2 },
+			{ "LINE2 pin", 0x3 },
+			{ "CD pin", 0x4 },
+			{ "Mixer", 0x5 },
+			{ "LINE-OUT pin", 0x6 },
+			{ "HP-OUT pin", 0x7 },
+		},
         },
 };
 static snd_kcontrol_new_t alc260_test_mixer[] = {
@@ -3243,7 +3416,17 @@ static snd_kcontrol_new_t alc260_test_mi
 	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
 
-	/* Modes for retasking pin widgets */
+	/* Modes for retasking pin widgets
+	 * Note: the ALC260 doesn't seem to act on requests to enable mic
+         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
+         * mention this restriction.  At this stage it's not clear whether
+         * this behaviour is intentional or is a hardware bug in chip
+         * revisions available at least up until early 2006.  Therefore for
+         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
+         * choices, but if it turns out that the lack of mic bias for these
+         * NIDs is intentional we could change their modes from
+         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
+	 */
 	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
 	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
 	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
@@ -3605,6 +3788,7 @@ static int alc260_parse_auto_config(stru
 
 	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
 
+	spec->num_mux_defs = 1;
 	spec->input_mux = &spec->private_imux;
 
 	/* check whether NID 0x04 is valid */
@@ -3710,7 +3894,8 @@ static struct alc_config_preset alc260_p
 		.adc_nids = alc260_dual_adc_nids,
 		.num_channel_mode = ARRAY_SIZE(alc260_modes),
 		.channel_mode = alc260_modes,
-		.input_mux = &alc260_fujitsu_capture_source,
+		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
+		.input_mux = alc260_fujitsu_capture_sources,
 	},
 	[ALC260_ACER] = {
 		.mixers = { alc260_acer_mixer,
@@ -3722,7 +3907,8 @@ static struct alc_config_preset alc260_p
 		.adc_nids = alc260_dual_adc_nids,
 		.num_channel_mode = ARRAY_SIZE(alc260_modes),
 		.channel_mode = alc260_modes,
-		.input_mux = &alc260_acer_capture_source,
+		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
+		.input_mux = alc260_acer_capture_sources,
 	},
 #ifdef CONFIG_SND_DEBUG
 	[ALC260_TEST] = {
@@ -3735,7 +3921,8 @@ static struct alc_config_preset alc260_p
 		.adc_nids = alc260_test_adc_nids,
 		.num_channel_mode = ARRAY_SIZE(alc260_modes),
 		.channel_mode = alc260_modes,
-		.input_mux = &alc260_test_capture_source,
+		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
+		.input_mux = alc260_test_capture_sources,
 	},
 #endif
 };
@@ -3827,7 +4014,6 @@ static struct hda_input_mux alc882_captu
 		{ "CD", 0x4 },
 	},
 };
-
 #define alc882_mux_enum_info alc_mux_enum_info
 #define alc882_mux_enum_get alc_mux_enum_get
 
@@ -4729,6 +4915,7 @@ static int alc262_parse_auto_config(stru
 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
 
 	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
+	spec->num_mux_defs = 1;
 	spec->input_mux = &spec->private_imux;
 
 	return 1;
@@ -5405,6 +5592,7 @@ static int alc861_parse_auto_config(stru
 
 	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
 
+	spec->num_mux_defs = 1;
 	spec->input_mux = &spec->private_imux;
 
 	spec->adc_nids = alc861_adc_nids;
-- 
1.1.3


-- 
Daniel T. Chen            crimsun at ubuntu.com
GPG key:   www.sh.nu/~crimsun/pubkey.gpg.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20060516/5fa7813d/attachment.sig>


More information about the kernel-team mailing list