lkml.org 
[lkml]   [2011]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[02/53] ALSA: hda - Fix the connection selection of ADCs on Cirrus codecs
3.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <tiwai@suse.de>

commit 05ee7964a470d29889ac48cc8274c1b5a1904a11 upstream.

spec->cur_adc isn't set until cs_capture_pcm_prepare() is called although
the driver tries to select the connection at init time and at auto-mic
switch. This results in the access to the widget NID 0, which is
obviously invalid, also a wrong capture source.

This patch fixes the issue by issuing the connect-select verb conditionally
at appropriate places.

Reported-and-tested-by: Dylan Reid <dgreid@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
sound/pci/hda/patch_cirrus.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)

--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -236,6 +236,15 @@ static int cs_dig_playback_pcm_cleanup(s
return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
}

+static void cs_update_input_select(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ if (spec->cur_adc)
+ snd_hda_codec_write(codec, spec->cur_adc, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ spec->adc_idx[spec->cur_input]);
+}
+
/*
* Analog capture
*/
@@ -249,6 +258,7 @@ static int cs_capture_pcm_prepare(struct
spec->cur_adc = spec->adc_nid[spec->cur_input];
spec->cur_adc_stream_tag = stream_tag;
spec->cur_adc_format = format;
+ cs_update_input_select(codec);
snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
return 0;
}
@@ -688,10 +698,8 @@ static int change_cur_input(struct hda_c
spec->cur_adc_stream_tag, 0,
spec->cur_adc_format);
}
- snd_hda_codec_write(codec, spec->cur_adc, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->adc_idx[idx]);
spec->cur_input = idx;
+ cs_update_input_select(codec);
return 1;
}

@@ -972,10 +980,7 @@ static void cs_automic(struct hda_codec
} else {
spec->cur_input = spec->last_input;
}
-
- snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->adc_idx[spec->cur_input]);
+ cs_update_input_select(codec);
} else {
if (present)
change_cur_input(codec, spec->automic_idx, 0);
@@ -1072,9 +1077,7 @@ static void init_input(struct hda_codec
cs_automic(codec);
else {
spec->cur_adc = spec->adc_nid[spec->cur_input];
- snd_hda_codec_write(codec, spec->cur_adc, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->adc_idx[spec->cur_input]);
+ cs_update_input_select(codec);
}
} else {
change_cur_input(codec, spec->cur_input, 1);



\
 
 \ /
  Last update: 2011-11-23 02:03    [W:0.131 / U:3.420 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site