aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2012-09-20 09:41:21 -0400
committerTakashi Iwai <tiwai@suse.de>2012-09-20 10:16:37 -0400
commit739572a545b8ab6faf9e266c3ed83ea202073699 (patch)
tree331eec9b37f9c995b196af0fa9fd8702c130c048 /sound/pci
parentc10514394ef9e8de93a4ad8c8904d71dcd82c122 (diff)
ALSA: hda - use both input paths on Conexant auto parser
On the Thinkpad W520 - and probably several other machines with Conexant 506x chips - the Dock Mic and Mic are connected to the same two selector nodes. This patch will make Dock Mic take one selector node and Mic take the other, when possible. Without the patch, both paths would take the first selector, leading to the normal Mic's volume being controlled by "Dock Mic Boost". (On other machines, this could instead fixup similar problems between Mic and Line In, for example.) BugLink: https://bugs.launchpad.net/bugs/1037642 Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_conexant.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b871b01332de..c03d3b8e42b2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3540,8 +3540,9 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3540 hda_nid_t pin, hda_nid_t *srcp, 3540 hda_nid_t pin, hda_nid_t *srcp,
3541 bool do_select, int depth) 3541 bool do_select, int depth)
3542{ 3542{
3543 struct conexant_spec *spec = codec->spec;
3543 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3544 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3544 int i, nums; 3545 int startidx, i, nums;
3545 3546
3546 switch (get_wcaps_type(get_wcaps(codec, mux))) { 3547 switch (get_wcaps_type(get_wcaps(codec, mux))) {
3547 case AC_WID_AUD_IN: 3548 case AC_WID_AUD_IN:
@@ -3565,14 +3566,25 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3565 depth++; 3566 depth++;
3566 if (depth == 2) 3567 if (depth == 2)
3567 return -1; 3568 return -1;
3569
3570 /* Try to rotate around connections to avoid one boost controlling
3571 another input path as well */
3572 startidx = 0;
3573 for (i = 0; i < spec->private_imux.num_items; i++)
3574 if (spec->imux_info[i].pin == pin) {
3575 startidx = i;
3576 break;
3577 }
3578
3568 for (i = 0; i < nums; i++) { 3579 for (i = 0; i < nums; i++) {
3569 int ret = __select_input_connection(codec, conn[i], pin, srcp, 3580 int j = (i + startidx) % nums;
3581 int ret = __select_input_connection(codec, conn[j], pin, srcp,
3570 do_select, depth); 3582 do_select, depth);
3571 if (ret >= 0) { 3583 if (ret >= 0) {
3572 if (do_select) 3584 if (do_select)
3573 snd_hda_codec_write(codec, mux, 0, 3585 snd_hda_codec_write(codec, mux, 0,
3574 AC_VERB_SET_CONNECT_SEL, i); 3586 AC_VERB_SET_CONNECT_SEL, j);
3575 return i; 3587 return j;
3576 } 3588 }
3577 } 3589 }
3578 return -1; 3590 return -1;