aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_analog.c139
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_realtek.c333
-rw-r--r--sound/pci/hda/patch_sigmatel.c20
5 files changed, 389 insertions, 116 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 20a66f85f0a4..c9ad182e1b4b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2303 * white-list for enable_msi 2303 * white-list for enable_msi
2304 */ 2304 */
2305static struct snd_pci_quirk msi_white_list[] __devinitdata = { 2305static struct snd_pci_quirk msi_white_list[] __devinitdata = {
2306 SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
2306 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), 2307 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
2307 {} 2308 {}
2308}; 2309};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 215e72a87113..2d603f6aba63 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -4032,6 +4032,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
4032} 4032}
4033 4033
4034/* 4034/*
4035 * HP Touchsmart
4036 * port-A (0x11) - front hp-out
4037 * port-B (0x14) - unused
4038 * port-C (0x15) - unused
4039 * port-D (0x12) - rear line out
4040 * port-E (0x1c) - front mic-in
4041 * port-F (0x16) - Internal speakers
4042 * digital-mic (0x17) - Internal mic
4043 */
4044
4045static struct hda_verb ad1984a_touchsmart_verbs[] = {
4046 /* DACs; unmute as default */
4047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4048 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4049 /* Port-A (HP) mixer - route only from analog mixer */
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4052 /* Port-A pin */
4053 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4054 /* Port-A (HP) pin - always unmuted */
4055 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4056 /* Port-E (int speaker) mixer - route only from analog mixer */
4057 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4058 /* Port-E pin */
4059 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4060 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4061 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4062 /* Port-F (int speaker) mixer - route only from analog mixer */
4063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4065 /* Port-F pin */
4066 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4068 /* Analog mixer; mute as default */
4069 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4070 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4071 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4072 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4073 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4074 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4075 /* Analog Mix output amp */
4076 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4077 /* capture sources */
4078 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4080 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4081 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082 /* unsolicited event for pin-sense */
4083 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4084 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4085 /* allow to touch GPIO1 (for mute control) */
4086 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4087 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4088 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4089 /* internal mic - dmic */
4090 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4091 /* set magic COEFs for dmic */
4092 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4093 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4094 { } /* end */
4095};
4096
4097static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4098 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4099/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4100 {
4101 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4102 .name = "Master Playback Switch",
4103 .info = snd_hda_mixer_amp_switch_info,
4104 .get = snd_hda_mixer_amp_switch_get,
4105 .put = ad1884a_mobile_master_sw_put,
4106 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4107 },
4108 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4109 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4110 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4111 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4112 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
4113 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4114 { } /* end */
4115};
4116
4117/* switch to external mic if plugged */
4118static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4119{
4120 if (snd_hda_codec_read(codec, 0x1c, 0,
4121 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
4122 snd_hda_codec_write(codec, 0x0c, 0,
4123 AC_VERB_SET_CONNECT_SEL, 0x4);
4124 } else {
4125 snd_hda_codec_write(codec, 0x0c, 0,
4126 AC_VERB_SET_CONNECT_SEL, 0x5);
4127 }
4128}
4129
4130
4131/* unsolicited event for HP jack sensing */
4132static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4133 unsigned int res)
4134{
4135 switch (res >> 26) {
4136 case AD1884A_HP_EVENT:
4137 ad1884a_hp_automute(codec);
4138 break;
4139 case AD1884A_MIC_EVENT:
4140 ad1984a_touchsmart_automic(codec);
4141 break;
4142 }
4143}
4144
4145/* initialize jack-sensing, too */
4146static int ad1984a_touchsmart_init(struct hda_codec *codec)
4147{
4148 ad198x_init(codec);
4149 ad1884a_hp_automute(codec);
4150 ad1984a_touchsmart_automic(codec);
4151 return 0;
4152}
4153
4154
4155/*
4035 */ 4156 */
4036 4157
4037enum { 4158enum {
@@ -4039,6 +4160,7 @@ enum {
4039 AD1884A_LAPTOP, 4160 AD1884A_LAPTOP,
4040 AD1884A_MOBILE, 4161 AD1884A_MOBILE,
4041 AD1884A_THINKPAD, 4162 AD1884A_THINKPAD,
4163 AD1984A_TOUCHSMART,
4042 AD1884A_MODELS 4164 AD1884A_MODELS
4043}; 4165};
4044 4166
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
4047 [AD1884A_LAPTOP] = "laptop", 4169 [AD1884A_LAPTOP] = "laptop",
4048 [AD1884A_MOBILE] = "mobile", 4170 [AD1884A_MOBILE] = "mobile",
4049 [AD1884A_THINKPAD] = "thinkpad", 4171 [AD1884A_THINKPAD] = "thinkpad",
4172 [AD1984A_TOUCHSMART] = "touchsmart",
4050}; 4173};
4051 4174
4052static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 4175static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4059 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), 4182 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4060 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE), 4183 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4061 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 4184 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4185 SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4062 {} 4186 {}
4063}; 4187};
4064 4188
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
4142 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; 4266 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4143 codec->patch_ops.init = ad1984a_thinkpad_init; 4267 codec->patch_ops.init = ad1984a_thinkpad_init;
4144 break; 4268 break;
4269 case AD1984A_TOUCHSMART:
4270 spec->mixers[0] = ad1984a_touchsmart_mixers;
4271 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4272 spec->multiout.dig_out_nid = 0;
4273 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4274 codec->patch_ops.init = ad1984a_touchsmart_init;
4275 /* set the upper-limit for mixer amp to 0dB for avoiding the
4276 * possible damage by overloading
4277 */
4278 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4279 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4280 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4281 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4282 (1 << AC_AMPCAP_MUTE_SHIFT));
4283 break;
4145 } 4284 }
4146 4285
4147 return 0; 4286 return 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 9d899eda44d7..3fbbc8c01e70 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
682}; 682};
683 683
684static struct hda_input_mux cxt5045_capture_source_benq = { 684static struct hda_input_mux cxt5045_capture_source_benq = {
685 .num_items = 3, 685 .num_items = 5,
686 .items = { 686 .items = {
687 { "IntMic", 0x1 }, 687 { "IntMic", 0x1 },
688 { "ExtMic", 0x2 }, 688 { "ExtMic", 0x2 },
689 { "LineIn", 0x3 }, 689 { "LineIn", 0x3 },
690 { "CD", 0x4 },
691 { "Mixer", 0x0 },
690 } 692 }
691}; 693};
692 694
@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
811}; 813};
812 814
813static struct snd_kcontrol_new cxt5045_benq_mixers[] = { 815static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
816 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
817 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
818 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
819 HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
820
814 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), 821 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
815 HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), 822 HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
816 HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), 823 HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
817 HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), 824 HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
818 825
826 HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
827 HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
828
819 {} 829 {}
820}; 830};
821 831
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 129605819560..470fd74a0a1a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1332,15 +1332,20 @@ do_sku:
1332 * when the external headphone out jack is plugged" 1332 * when the external headphone out jack is plugged"
1333 */ 1333 */
1334 if (!spec->autocfg.hp_pins[0]) { 1334 if (!spec->autocfg.hp_pins[0]) {
1335 hda_nid_t nid;
1335 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1336 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1336 if (tmp == 0) 1337 if (tmp == 0)
1337 spec->autocfg.hp_pins[0] = porta; 1338 nid = porta;
1338 else if (tmp == 1) 1339 else if (tmp == 1)
1339 spec->autocfg.hp_pins[0] = porte; 1340 nid = porte;
1340 else if (tmp == 2) 1341 else if (tmp == 2)
1341 spec->autocfg.hp_pins[0] = portd; 1342 nid = portd;
1342 else 1343 else
1343 return 1; 1344 return 1;
1345 for (i = 0; i < spec->autocfg.line_outs; i++)
1346 if (spec->autocfg.line_out_pins[i] == nid)
1347 return 1;
1348 spec->autocfg.hp_pins[0] = nid;
1344 } 1349 }
1345 1350
1346 alc_init_auto_hp(codec); 1351 alc_init_auto_hp(codec);
@@ -1362,7 +1367,7 @@ static void alc_ssid_check(struct hda_codec *codec,
1362} 1367}
1363 1368
1364/* 1369/*
1365 * Fix-up pin default configurations 1370 * Fix-up pin default configurations and add default verbs
1366 */ 1371 */
1367 1372
1368struct alc_pincfg { 1373struct alc_pincfg {
@@ -1370,9 +1375,14 @@ struct alc_pincfg {
1370 u32 val; 1375 u32 val;
1371}; 1376};
1372 1377
1373static void alc_fix_pincfg(struct hda_codec *codec, 1378struct alc_fixup {
1379 const struct alc_pincfg *pins;
1380 const struct hda_verb *verbs;
1381};
1382
1383static void alc_pick_fixup(struct hda_codec *codec,
1374 const struct snd_pci_quirk *quirk, 1384 const struct snd_pci_quirk *quirk,
1375 const struct alc_pincfg **pinfix) 1385 const struct alc_fixup *fix)
1376{ 1386{
1377 const struct alc_pincfg *cfg; 1387 const struct alc_pincfg *cfg;
1378 1388
@@ -1380,9 +1390,14 @@ static void alc_fix_pincfg(struct hda_codec *codec,
1380 if (!quirk) 1390 if (!quirk)
1381 return; 1391 return;
1382 1392
1383 cfg = pinfix[quirk->value]; 1393 fix += quirk->value;
1384 for (; cfg->nid; cfg++) 1394 cfg = fix->pins;
1385 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1395 if (cfg) {
1396 for (; cfg->nid; cfg++)
1397 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1398 }
1399 if (fix->verbs)
1400 add_verb(codec->spec, fix->verbs);
1386} 1401}
1387 1402
1388/* 1403/*
@@ -9593,11 +9608,13 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9593 { } 9608 { }
9594}; 9609};
9595 9610
9596static const struct alc_pincfg *alc882_pin_fixes[] = { 9611static const struct alc_fixup alc882_fixups[] = {
9597 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 9612 [PINFIX_ABIT_AW9D_MAX] = {
9613 .pins = alc882_abit_aw9d_pinfix
9614 },
9598}; 9615};
9599 9616
9600static struct snd_pci_quirk alc882_pinfix_tbl[] = { 9617static struct snd_pci_quirk alc882_fixup_tbl[] = {
9601 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 9618 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9602 {} 9619 {}
9603}; 9620};
@@ -9869,7 +9886,7 @@ static int patch_alc882(struct hda_codec *codec)
9869 board_config = ALC882_AUTO; 9886 board_config = ALC882_AUTO;
9870 } 9887 }
9871 9888
9872 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 9889 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9873 9890
9874 if (board_config == ALC882_AUTO) { 9891 if (board_config == ALC882_AUTO) {
9875 /* automatic parse from the BIOS config */ 9892 /* automatic parse from the BIOS config */
@@ -12660,7 +12677,7 @@ static struct alc_config_preset alc268_presets[] = {
12660 .init_hook = alc268_toshiba_automute, 12677 .init_hook = alc268_toshiba_automute,
12661 }, 12678 },
12662 [ALC268_ACER] = { 12679 [ALC268_ACER] = {
12663 .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer, 12680 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12664 alc268_beep_mixer }, 12681 alc268_beep_mixer },
12665 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12682 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12666 alc268_acer_verbs }, 12683 alc268_acer_verbs },
@@ -12842,12 +12859,15 @@ static int patch_alc268(struct hda_codec *codec)
12842 unsigned int wcap = get_wcaps(codec, 0x07); 12859 unsigned int wcap = get_wcaps(codec, 0x07);
12843 int i; 12860 int i;
12844 12861
12862 spec->capsrc_nids = alc268_capsrc_nids;
12845 /* get type */ 12863 /* get type */
12846 wcap = get_wcaps_type(wcap); 12864 wcap = get_wcaps_type(wcap);
12847 if (spec->auto_mic || 12865 if (spec->auto_mic ||
12848 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 12866 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12849 spec->adc_nids = alc268_adc_nids_alt; 12867 spec->adc_nids = alc268_adc_nids_alt;
12850 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 12868 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12869 if (spec->auto_mic)
12870 fixup_automic_adc(codec);
12851 if (spec->auto_mic || spec->input_mux->num_items == 1) 12871 if (spec->auto_mic || spec->input_mux->num_items == 1)
12852 add_mixer(spec, alc268_capture_nosrc_mixer); 12872 add_mixer(spec, alc268_capture_nosrc_mixer);
12853 else 12873 else
@@ -12857,7 +12877,6 @@ static int patch_alc268(struct hda_codec *codec)
12857 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 12877 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12858 add_mixer(spec, alc268_capture_mixer); 12878 add_mixer(spec, alc268_capture_mixer);
12859 } 12879 }
12860 spec->capsrc_nids = alc268_capsrc_nids;
12861 /* set default input source */ 12880 /* set default input source */
12862 for (i = 0; i < spec->num_adc_nids; i++) 12881 for (i = 0; i < spec->num_adc_nids; i++)
12863 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 12882 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
@@ -14357,15 +14376,16 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
14357static void alc861_auto_init_hp_out(struct hda_codec *codec) 14376static void alc861_auto_init_hp_out(struct hda_codec *codec)
14358{ 14377{
14359 struct alc_spec *spec = codec->spec; 14378 struct alc_spec *spec = codec->spec;
14360 hda_nid_t pin;
14361 14379
14362 pin = spec->autocfg.hp_pins[0]; 14380 if (spec->autocfg.hp_outs)
14363 if (pin) 14381 alc861_auto_set_output_and_unmute(codec,
14364 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 14382 spec->autocfg.hp_pins[0],
14383 PIN_HP,
14365 spec->multiout.hp_nid); 14384 spec->multiout.hp_nid);
14366 pin = spec->autocfg.speaker_pins[0]; 14385 if (spec->autocfg.speaker_outs)
14367 if (pin) 14386 alc861_auto_set_output_and_unmute(codec,
14368 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 14387 spec->autocfg.speaker_pins[0],
14388 PIN_OUT,
14369 spec->multiout.dac_nids[0]); 14389 spec->multiout.dac_nids[0]);
14370} 14390}
14371 14391
@@ -15158,7 +15178,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15158 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 15178 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15159 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 15179 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15160 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 15180 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15161 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 15181 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15162 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 15182 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15163 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 15183 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15164 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 15184 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
@@ -15551,6 +15571,29 @@ static void alc861vd_auto_init(struct hda_codec *codec)
15551 alc_inithook(codec); 15571 alc_inithook(codec);
15552} 15572}
15553 15573
15574enum {
15575 ALC660VD_FIX_ASUS_GPIO1
15576};
15577
15578/* reset GPIO1 */
15579static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15580 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15581 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15582 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15583 { }
15584};
15585
15586static const struct alc_fixup alc861vd_fixups[] = {
15587 [ALC660VD_FIX_ASUS_GPIO1] = {
15588 .verbs = alc660vd_fix_asus_gpio1_verbs,
15589 },
15590};
15591
15592static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15593 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15594 {}
15595};
15596
15554static int patch_alc861vd(struct hda_codec *codec) 15597static int patch_alc861vd(struct hda_codec *codec)
15555{ 15598{
15556 struct alc_spec *spec; 15599 struct alc_spec *spec;
@@ -15572,6 +15615,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15572 board_config = ALC861VD_AUTO; 15615 board_config = ALC861VD_AUTO;
15573 } 15616 }
15574 15617
15618 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15619
15575 if (board_config == ALC861VD_AUTO) { 15620 if (board_config == ALC861VD_AUTO) {
15576 /* automatic parse from the BIOS config */ 15621 /* automatic parse from the BIOS config */
15577 err = alc861vd_parse_auto_config(codec); 15622 err = alc861vd_parse_auto_config(codec);
@@ -16852,6 +16897,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16852 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 16897 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16853 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 16898 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16854 ALC662_3ST_6ch_DIG), 16899 ALC662_3ST_6ch_DIG),
16900 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16855 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 16901 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16856 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 16902 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16857 ALC662_3ST_6ch_DIG), 16903 ALC662_3ST_6ch_DIG),
@@ -17145,70 +17191,145 @@ static struct alc_config_preset alc662_presets[] = {
17145 * BIOS auto configuration 17191 * BIOS auto configuration
17146 */ 17192 */
17147 17193
17194/* convert from MIX nid to DAC */
17195static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17196{
17197 if (nid == 0x0f)
17198 return 0x02;
17199 else if (nid >= 0x0c && nid <= 0x0e)
17200 return nid - 0x0c + 0x02;
17201 else
17202 return 0;
17203}
17204
17205/* get MIX nid connected to the given pin targeted to DAC */
17206static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17207 hda_nid_t dac)
17208{
17209 hda_nid_t mix[4];
17210 int i, num;
17211
17212 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17213 for (i = 0; i < num; i++) {
17214 if (alc662_mix_to_dac(mix[i]) == dac)
17215 return mix[i];
17216 }
17217 return 0;
17218}
17219
17220/* look for an empty DAC slot */
17221static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17222{
17223 struct alc_spec *spec = codec->spec;
17224 hda_nid_t srcs[5];
17225 int i, j, num;
17226
17227 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17228 if (num < 0)
17229 return 0;
17230 for (i = 0; i < num; i++) {
17231 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17232 if (!nid)
17233 continue;
17234 for (j = 0; j < spec->multiout.num_dacs; j++)
17235 if (spec->multiout.dac_nids[j] == nid)
17236 break;
17237 if (j >= spec->multiout.num_dacs)
17238 return nid;
17239 }
17240 return 0;
17241}
17242
17243/* fill in the dac_nids table from the parsed pin configuration */
17244static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17245 const struct auto_pin_cfg *cfg)
17246{
17247 struct alc_spec *spec = codec->spec;
17248 int i;
17249 hda_nid_t dac;
17250
17251 spec->multiout.dac_nids = spec->private_dac_nids;
17252 for (i = 0; i < cfg->line_outs; i++) {
17253 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17254 if (!dac)
17255 continue;
17256 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17257 }
17258 return 0;
17259}
17260
17261static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17262 hda_nid_t nid, unsigned int chs)
17263{
17264 char name[32];
17265 sprintf(name, "%s Playback Volume", pfx);
17266 return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17267 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17268}
17269
17270static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17271 hda_nid_t nid, unsigned int chs)
17272{
17273 char name[32];
17274 sprintf(name, "%s Playback Switch", pfx);
17275 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17276 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17277}
17278
17279#define alc662_add_stereo_vol(spec, pfx, nid) \
17280 alc662_add_vol_ctl(spec, pfx, nid, 3)
17281#define alc662_add_stereo_sw(spec, pfx, nid) \
17282 alc662_add_sw_ctl(spec, pfx, nid, 3)
17283
17148/* add playback controls from the parsed DAC table */ 17284/* add playback controls from the parsed DAC table */
17149static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 17285static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17150 const struct auto_pin_cfg *cfg) 17286 const struct auto_pin_cfg *cfg)
17151{ 17287{
17152 char name[32]; 17288 struct alc_spec *spec = codec->spec;
17153 static const char *chname[4] = { 17289 static const char *chname[4] = {
17154 "Front", "Surround", NULL /*CLFE*/, "Side" 17290 "Front", "Surround", NULL /*CLFE*/, "Side"
17155 }; 17291 };
17156 hda_nid_t nid; 17292 hda_nid_t nid, mix;
17157 int i, err; 17293 int i, err;
17158 17294
17159 for (i = 0; i < cfg->line_outs; i++) { 17295 for (i = 0; i < cfg->line_outs; i++) {
17160 if (!spec->multiout.dac_nids[i]) 17296 nid = spec->multiout.dac_nids[i];
17297 if (!nid)
17298 continue;
17299 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17300 if (!mix)
17161 continue; 17301 continue;
17162 nid = alc880_idx_to_dac(i);
17163 if (i == 2) { 17302 if (i == 2) {
17164 /* Center/LFE */ 17303 /* Center/LFE */
17165 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17304 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17166 "Center Playback Volume",
17167 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
17168 HDA_OUTPUT));
17169 if (err < 0) 17305 if (err < 0)
17170 return err; 17306 return err;
17171 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17307 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17172 "LFE Playback Volume",
17173 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
17174 HDA_OUTPUT));
17175 if (err < 0) 17308 if (err < 0)
17176 return err; 17309 return err;
17177 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17310 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17178 "Center Playback Switch",
17179 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
17180 HDA_INPUT));
17181 if (err < 0) 17311 if (err < 0)
17182 return err; 17312 return err;
17183 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17313 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17184 "LFE Playback Switch",
17185 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
17186 HDA_INPUT));
17187 if (err < 0) 17314 if (err < 0)
17188 return err; 17315 return err;
17189 } else { 17316 } else {
17190 const char *pfx; 17317 const char *pfx;
17191 if (cfg->line_outs == 1 && 17318 if (cfg->line_outs == 1 &&
17192 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17319 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17193 if (!cfg->hp_pins) 17320 if (cfg->hp_outs)
17194 pfx = "Speaker"; 17321 pfx = "Speaker";
17195 else 17322 else
17196 pfx = "PCM"; 17323 pfx = "PCM";
17197 } else 17324 } else
17198 pfx = chname[i]; 17325 pfx = chname[i];
17199 sprintf(name, "%s Playback Volume", pfx); 17326 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17200 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17201 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17202 HDA_OUTPUT));
17203 if (err < 0) 17327 if (err < 0)
17204 return err; 17328 return err;
17205 if (cfg->line_outs == 1 && 17329 if (cfg->line_outs == 1 &&
17206 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17330 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17207 pfx = "Speaker"; 17331 pfx = "Speaker";
17208 sprintf(name, "%s Playback Switch", pfx); 17332 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17209 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17210 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
17211 3, 0, HDA_INPUT));
17212 if (err < 0) 17333 if (err < 0)
17213 return err; 17334 return err;
17214 } 17335 }
@@ -17217,54 +17338,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
17217} 17338}
17218 17339
17219/* add playback controls for speaker and HP outputs */ 17340/* add playback controls for speaker and HP outputs */
17220static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 17341/* return DAC nid if any new DAC is assigned */
17342static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17221 const char *pfx) 17343 const char *pfx)
17222{ 17344{
17223 hda_nid_t nid; 17345 struct alc_spec *spec = codec->spec;
17346 hda_nid_t nid, mix;
17224 int err; 17347 int err;
17225 char name[32];
17226 17348
17227 if (!pin) 17349 if (!pin)
17228 return 0; 17350 return 0;
17229 17351 nid = alc662_look_for_dac(codec, pin);
17230 if (pin == 0x17) { 17352 if (!nid) {
17231 /* ALC663 has a mono output pin on 0x17 */ 17353 char name[32];
17354 /* the corresponding DAC is already occupied */
17355 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17356 return 0; /* no way */
17357 /* create a switch only */
17232 sprintf(name, "%s Playback Switch", pfx); 17358 sprintf(name, "%s Playback Switch", pfx);
17233 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 17359 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17234 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); 17360 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17235 return err;
17236 } 17361 }
17237 17362
17238 if (alc880_is_fixed_pin(pin)) { 17363 mix = alc662_dac_to_mix(codec, pin, nid);
17239 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17364 if (!mix)
17240 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */ 17365 return 0;
17241 /* specify the DAC as the extra output */ 17366 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17242 if (!spec->multiout.hp_nid) 17367 if (err < 0)
17243 spec->multiout.hp_nid = nid; 17368 return err;
17244 else 17369 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17245 spec->multiout.extra_out_nid[0] = nid; 17370 if (err < 0)
17246 /* control HP volume/switch on the output mixer amp */ 17371 return err;
17247 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17372 return nid;
17248 sprintf(name, "%s Playback Volume", pfx);
17249 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17250 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
17251 if (err < 0)
17252 return err;
17253 sprintf(name, "%s Playback Switch", pfx);
17254 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
17255 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
17256 if (err < 0)
17257 return err;
17258 } else if (alc880_is_multi_pin(pin)) {
17259 /* set manual connection */
17260 /* we have only a switch on HP-out PIN */
17261 sprintf(name, "%s Playback Switch", pfx);
17262 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17263 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17264 if (err < 0)
17265 return err;
17266 }
17267 return 0;
17268} 17373}
17269 17374
17270/* create playback/capture controls for input pins */ 17375/* create playback/capture controls for input pins */
@@ -17273,30 +17378,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
17273 17378
17274static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 17379static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17275 hda_nid_t nid, int pin_type, 17380 hda_nid_t nid, int pin_type,
17276 int dac_idx) 17381 hda_nid_t dac)
17277{ 17382{
17383 int i, num;
17384 hda_nid_t srcs[4];
17385
17278 alc_set_pin_output(codec, nid, pin_type); 17386 alc_set_pin_output(codec, nid, pin_type);
17279 /* need the manual connection? */ 17387 /* need the manual connection? */
17280 if (alc880_is_multi_pin(nid)) { 17388 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17281 struct alc_spec *spec = codec->spec; 17389 if (num <= 1)
17282 int idx = alc880_multi_pin_idx(nid); 17390 return;
17283 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 17391 for (i = 0; i < num; i++) {
17284 AC_VERB_SET_CONNECT_SEL, 17392 if (alc662_mix_to_dac(srcs[i]) != dac)
17285 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 17393 continue;
17394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17395 return;
17286 } 17396 }
17287} 17397}
17288 17398
17289static void alc662_auto_init_multi_out(struct hda_codec *codec) 17399static void alc662_auto_init_multi_out(struct hda_codec *codec)
17290{ 17400{
17291 struct alc_spec *spec = codec->spec; 17401 struct alc_spec *spec = codec->spec;
17402 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17292 int i; 17403 int i;
17293 17404
17294 for (i = 0; i <= HDA_SIDE; i++) { 17405 for (i = 0; i <= HDA_SIDE; i++) {
17295 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17406 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17296 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17297 if (nid) 17407 if (nid)
17298 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 17408 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17299 i); 17409 spec->multiout.dac_nids[i]);
17300 } 17410 }
17301} 17411}
17302 17412
@@ -17306,12 +17416,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
17306 hda_nid_t pin; 17416 hda_nid_t pin;
17307 17417
17308 pin = spec->autocfg.hp_pins[0]; 17418 pin = spec->autocfg.hp_pins[0];
17309 if (pin) /* connect to front */ 17419 if (pin)
17310 /* use dac 0 */ 17420 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17311 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 17421 spec->multiout.hp_nid);
17312 pin = spec->autocfg.speaker_pins[0]; 17422 pin = spec->autocfg.speaker_pins[0];
17313 if (pin) 17423 if (pin)
17314 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 17424 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17425 spec->multiout.extra_out_nid[0]);
17315} 17426}
17316 17427
17317#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 17428#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
@@ -17349,21 +17460,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17349 if (!spec->autocfg.line_outs) 17460 if (!spec->autocfg.line_outs)
17350 return 0; /* can't find valid BIOS pin config */ 17461 return 0; /* can't find valid BIOS pin config */
17351 17462
17352 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17463 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17353 if (err < 0) 17464 if (err < 0)
17354 return err; 17465 return err;
17355 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 17466 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17356 if (err < 0) 17467 if (err < 0)
17357 return err; 17468 return err;
17358 err = alc662_auto_create_extra_out(spec, 17469 err = alc662_auto_create_extra_out(codec,
17359 spec->autocfg.speaker_pins[0], 17470 spec->autocfg.speaker_pins[0],
17360 "Speaker"); 17471 "Speaker");
17361 if (err < 0) 17472 if (err < 0)
17362 return err; 17473 return err;
17363 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 17474 if (err)
17475 spec->multiout.extra_out_nid[0] = err;
17476 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17364 "Headphone"); 17477 "Headphone");
17365 if (err < 0) 17478 if (err < 0)
17366 return err; 17479 return err;
17480 if (err)
17481 spec->multiout.hp_nid = err;
17367 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 17482 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17368 if (err < 0) 17483 if (err < 0)
17369 return err; 17484 return err;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 826137ec3002..a9b26828a651 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -182,8 +182,8 @@ struct sigmatel_jack {
182 182
183struct sigmatel_mic_route { 183struct sigmatel_mic_route {
184 hda_nid_t pin; 184 hda_nid_t pin;
185 unsigned char mux_idx; 185 signed char mux_idx;
186 unsigned char dmux_idx; 186 signed char dmux_idx;
187}; 187};
188 188
189struct sigmatel_spec { 189struct sigmatel_spec {
@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
3469 break; 3469 break;
3470 if (i <= AUTO_PIN_FRONT_MIC) { 3470 if (i <= AUTO_PIN_FRONT_MIC) {
3471 /* analog pin */ 3471 /* analog pin */
3472 mic->dmux_idx = 0;
3473 i = get_connection_index(codec, spec->mux_nids[0], pin); 3472 i = get_connection_index(codec, spec->mux_nids[0], pin);
3474 if (i < 0) 3473 if (i < 0)
3475 return -1; 3474 return -1;
3476 mic->mux_idx = i; 3475 mic->mux_idx = i;
3476 mic->dmux_idx = -1;
3477 if (spec->dmux_nids)
3478 mic->dmux_idx = get_connection_index(codec,
3479 spec->dmux_nids[0],
3480 spec->mux_nids[0]);
3477 } else if (spec->dmux_nids) { 3481 } else if (spec->dmux_nids) {
3478 /* digital pin */ 3482 /* digital pin */
3479 mic->mux_idx = 0;
3480 i = get_connection_index(codec, spec->dmux_nids[0], pin); 3483 i = get_connection_index(codec, spec->dmux_nids[0], pin);
3481 if (i < 0) 3484 if (i < 0)
3482 return -1; 3485 return -1;
3483 mic->dmux_idx = i; 3486 mic->dmux_idx = i;
3487 mic->mux_idx = -1;
3488 if (spec->mux_nids)
3489 mic->mux_idx = get_connection_index(codec,
3490 spec->mux_nids[0],
3491 spec->dmux_nids[0]);
3484 } 3492 }
3485 return 0; 3493 return 0;
3486} 3494}
@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
4557 mic = &spec->ext_mic; 4565 mic = &spec->ext_mic;
4558 else 4566 else
4559 mic = &spec->int_mic; 4567 mic = &spec->int_mic;
4560 if (mic->dmux_idx) 4568 if (mic->dmux_idx >= 0)
4561 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, 4569 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4562 AC_VERB_SET_CONNECT_SEL, 4570 AC_VERB_SET_CONNECT_SEL,
4563 mic->dmux_idx); 4571 mic->dmux_idx);
4564 else 4572 if (mic->mux_idx >= 0)
4565 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, 4573 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
4566 AC_VERB_SET_CONNECT_SEL, 4574 AC_VERB_SET_CONNECT_SEL,
4567 mic->mux_idx); 4575 mic->mux_idx);