diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-13 05:56:53 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-13 05:56:53 -0400 |
commit | f0cea79724f03ee55e7b5933b6a6f6a3fd177710 (patch) | |
tree | bc0552e35dd5248d19f8d85f2ad84783371f9e08 | |
parent | bbbe33900d1f3c4402148ccb85234a741a6606a3 (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.c | 26 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2 |
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 | } |
1262 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); | 1262 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); |
1263 | 1263 | ||
1264 | static 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 | */ |
1269 | void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | 1273 | void __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 | } |
1284 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); | 1294 | EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream); |
1285 | 1295 | ||
1286 | static void really_cleanup_stream(struct hda_codec *codec, | 1296 | static 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, | |||
963 | void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 963 | void 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); |
966 | void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); | 966 | void __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) | ||
967 | unsigned int snd_hda_calc_stream_format(unsigned int rate, | 970 | unsigned 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, |