aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-08-13 05:56:53 -0400
committerTakashi Iwai <tiwai@suse.de>2010-08-13 05:56:53 -0400
commitf0cea79724f03ee55e7b5933b6a6f6a3fd177710 (patch)
treebc0552e35dd5248d19f8d85f2ad84783371f9e08
parentbbbe33900d1f3c4402148ccb85234a741a6606a3 (diff)
ALSA: hda - Fix dynamic ADC change working again
The commit eb541337b7a43822fce7d0c9d967ee149b2d9a96 ALSA: hda - Make converter setups sticky changes the semantics of snd_hda_codec_cleanup_stream() not to clean up the stream at that moment but delay the action. This broke the codes expecting that the clean-up is done immediately, such as dynamic ADC changes in some codec drivers. This patch fixes the issue by introducing a lower helper, __snd_hda_codec_cleanup_stream(), to allow the immediate clean up. The original snd_hda_codec_cleanup_stream() is kept as is now. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c26
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/patch_cirrus.c2
-rw-r--r--sound/pci/hda/patch_conexant.c2
-rw-r--r--sound/pci/hda/patch_realtek.c2
5 files changed, 25 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 720a81d711e3..dd8fb86c842b 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1261,12 +1261,17 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1261} 1261}
1262EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); 1262EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
1263 1263
1264static void really_cleanup_stream(struct hda_codec *codec,
1265 struct hda_cvt_setup *q);
1266
1264/** 1267/**
1265 * snd_hda_codec_cleanup_stream - clean up the codec for closing 1268 * __snd_hda_codec_cleanup_stream - clean up the codec for closing
1266 * @codec: the CODEC to clean up 1269 * @codec: the CODEC to clean up
1267 * @nid: the NID to clean up 1270 * @nid: the NID to clean up
1271 * @do_now: really clean up the stream instead of clearing the active flag
1268 */ 1272 */
1269void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) 1273void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
1274 int do_now)
1270{ 1275{
1271 struct hda_cvt_setup *p; 1276 struct hda_cvt_setup *p;
1272 1277
@@ -1274,14 +1279,19 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
1274 return; 1279 return;
1275 1280
1276 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); 1281 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
1277 /* here we just clear the active flag; actual clean-ups will be done
1278 * in purify_inactive_streams()
1279 */
1280 p = get_hda_cvt_setup(codec, nid); 1282 p = get_hda_cvt_setup(codec, nid);
1281 if (p) 1283 if (p) {
1282 p->active = 0; 1284 /* here we just clear the active flag when do_now isn't set;
1285 * actual clean-ups will be done later in
1286 * purify_inactive_streams() called from snd_hda_codec_prpapre()
1287 */
1288 if (do_now)
1289 really_cleanup_stream(codec, p);
1290 else
1291 p->active = 0;
1292 }
1283} 1293}
1284EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); 1294EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream);
1285 1295
1286static void really_cleanup_stream(struct hda_codec *codec, 1296static void really_cleanup_stream(struct hda_codec *codec,
1287 struct hda_cvt_setup *q) 1297 struct hda_cvt_setup *q)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 3f7a479881e5..4303353feda9 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -963,7 +963,10 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
963void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, 963void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
964 u32 stream_tag, 964 u32 stream_tag,
965 int channel_id, int format); 965 int channel_id, int format);
966void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); 966void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
967 int do_now);
968#define snd_hda_codec_cleanup_stream(codec, nid) \
969 __snd_hda_codec_cleanup_stream(codec, nid, 0)
967unsigned int snd_hda_calc_stream_format(unsigned int rate, 970unsigned int snd_hda_calc_stream_format(unsigned int rate,
968 unsigned int channels, 971 unsigned int channels,
969 unsigned int format, 972 unsigned int format,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 350ee8ac4153..4ef5efaaaef1 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -656,7 +656,7 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
656 return 0; 656 return 0;
657 if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) { 657 if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) {
658 /* stream is running, let's swap the current ADC */ 658 /* stream is running, let's swap the current ADC */
659 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 659 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
660 spec->cur_adc = spec->adc_nid[idx]; 660 spec->cur_adc = spec->adc_nid[idx];
661 snd_hda_codec_setup_stream(codec, spec->cur_adc, 661 snd_hda_codec_setup_stream(codec, spec->cur_adc,
662 spec->cur_adc_stream_tag, 0, 662 spec->cur_adc_stream_tag, 0,
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index f7e234e5ee96..31b5d9eeba68 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1733,7 +1733,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1733 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1733 new_adc = spec->adc_nids[spec->cur_adc_idx];
1734 if (spec->cur_adc && spec->cur_adc != new_adc) { 1734 if (spec->cur_adc && spec->cur_adc != new_adc) {
1735 /* stream is running, let's swap the current ADC */ 1735 /* stream is running, let's swap the current ADC */
1736 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 1736 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1737 spec->cur_adc = new_adc; 1737 spec->cur_adc = new_adc;
1738 snd_hda_codec_setup_stream(codec, new_adc, 1738 snd_hda_codec_setup_stream(codec, new_adc,
1739 spec->cur_adc_stream_tag, 0, 1739 spec->cur_adc_stream_tag, 0,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 55d6e5b6bb7d..2cd1ae809e46 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1037,7 +1037,7 @@ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1037 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1037 new_adc = spec->adc_nids[spec->cur_adc_idx];
1038 if (spec->cur_adc && spec->cur_adc != new_adc) { 1038 if (spec->cur_adc && spec->cur_adc != new_adc) {
1039 /* stream is running, let's swap the current ADC */ 1039 /* stream is running, let's swap the current ADC */
1040 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 1040 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1041 spec->cur_adc = new_adc; 1041 spec->cur_adc = new_adc;
1042 snd_hda_codec_setup_stream(codec, new_adc, 1042 snd_hda_codec_setup_stream(codec, new_adc,
1043 spec->cur_adc_stream_tag, 0, 1043 spec->cur_adc_stream_tag, 0,