diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-13 09:56:53 (GMT) |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-13 09:56:53 (GMT) |
commit | f0cea79724f03ee55e7b5933b6a6f6a3fd177710 (patch) | |
tree | bc0552e35dd5248d19f8d85f2ad84783371f9e08 | |
parent | bbbe33900d1f3c4402148ccb85234a741a6606a3 (diff) | |
download | linux-f0cea79724f03ee55e7b5933b6a6f6a3fd177710.tar.xz |
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 720a81d..dd8fb86 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, } EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); +static void really_cleanup_stream(struct hda_codec *codec, + struct hda_cvt_setup *q); + /** - * snd_hda_codec_cleanup_stream - clean up the codec for closing + * __snd_hda_codec_cleanup_stream - clean up the codec for closing * @codec: the CODEC to clean up * @nid: the NID to clean up + * @do_now: really clean up the stream instead of clearing the active flag */ -void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) +void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, + int do_now) { struct hda_cvt_setup *p; @@ -1274,14 +1279,19 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) return; snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); - /* here we just clear the active flag; actual clean-ups will be done - * in purify_inactive_streams() - */ p = get_hda_cvt_setup(codec, nid); - if (p) - p->active = 0; + if (p) { + /* here we just clear the active flag when do_now isn't set; + * actual clean-ups will be done later in + * purify_inactive_streams() called from snd_hda_codec_prpapre() + */ + if (do_now) + really_cleanup_stream(codec, p); + else + p->active = 0; + } } -EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); +EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream); static void really_cleanup_stream(struct hda_codec *codec, struct hda_cvt_setup *q) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 3f7a479..4303353 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, void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format); -void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); +void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, + int do_now); +#define snd_hda_codec_cleanup_stream(codec, nid) \ + __snd_hda_codec_cleanup_stream(codec, nid, 0) unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 350ee8a..4ef5efa 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, return 0; if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) { /* stream is running, let's swap the current ADC */ - snd_hda_codec_cleanup_stream(codec, spec->cur_adc); + __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); spec->cur_adc = spec->adc_nid[idx]; snd_hda_codec_setup_stream(codec, spec->cur_adc, spec->cur_adc_stream_tag, 0, diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f7e234e..31b5d9e 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) new_adc = spec->adc_nids[spec->cur_adc_idx]; if (spec->cur_adc && spec->cur_adc != new_adc) { /* stream is running, let's swap the current ADC */ - snd_hda_codec_cleanup_stream(codec, spec->cur_adc); + __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); spec->cur_adc = new_adc; snd_hda_codec_setup_stream(codec, new_adc, spec->cur_adc_stream_tag, 0, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 55d6e5b..2cd1ae8 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) new_adc = spec->adc_nids[spec->cur_adc_idx]; if (spec->cur_adc && spec->cur_adc != new_adc) { /* stream is running, let's swap the current ADC */ - snd_hda_codec_cleanup_stream(codec, spec->cur_adc); + __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); spec->cur_adc = new_adc; snd_hda_codec_setup_stream(codec, new_adc, spec->cur_adc_stream_tag, 0, |