ALSA: hda - stop setup_dig_out_stream() causing clicks
authorLaurence Darby <ldarby@tuffmail.com>
Sat, 3 Nov 2012 17:00:06 +0000 (17:00 +0000)
committerTakashi Iwai <tiwai@suse.de>
Sun, 4 Nov 2012 08:17:28 +0000 (09:17 +0100)
Starting audio or seeking in various music players causes
setup_dig_out_stream() to be called, which resets the SPDIF stream,
which caused one DAC (but not another) to make a clicking noise every
time.

This patch ensures the reset only happens when it needs to, which is
when the format changes, and makes the code a little more readable.

Signed-off-by: Laurence Darby <ldarby@tuffmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_codec.c

index 2da78751951305957bc5e3f761248ab1906abf87..569bc05aad6c5d75ded1269b67927c1a66fbd2a8 100644 (file)
@@ -4816,10 +4816,20 @@ EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
 static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
                                 unsigned int stream_tag, unsigned int format)
 {
-       struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
-
-       /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
-       if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
+       struct hda_spdif_out *spdif;
+       unsigned int curr_fmt;
+       bool reset;
+
+       spdif = snd_hda_spdif_out_of_nid(codec, nid);
+       curr_fmt = snd_hda_codec_read(codec, nid, 0,
+                                     AC_VERB_GET_STREAM_FORMAT, 0);
+       reset = codec->spdif_status_reset &&
+               (spdif->ctls & AC_DIG1_ENABLE) &&
+               curr_fmt != format;
+
+       /* turn off SPDIF if needed; otherwise the IEC958 bits won't be
+          updated */
+       if (reset)
                set_dig_out_convert(codec, nid,
                                    spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
                                    -1);
@@ -4831,7 +4841,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
                                                   format);
        }
        /* turn on again (if needed) */
-       if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
+       if (reset)
                set_dig_out_convert(codec, nid,
                                    spdif->ctls & 0xff, -1);
 }