Explorar o código

ALSA: hda - Don't reset SPDIF in each status change

The SPDIF output is toggled at each time any SPDIF status bits are changed
because of the known problems on some codecs.  But, this also results in
loosing the sync, and the problem is more obvious on HDMI output over
SPDIF.  Since the toggle is necessary only for some codecs, we should
check whether this workaround is needed and skip if unnecessary.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Takashi Iwai %!s(int64=17) %!d(string=hai) anos
pai
achega
963f803fb1
Modificáronse 3 ficheiros con 9 adicións e 2 borrados
  1. 2 2
      sound/pci/hda/hda_codec.c
  2. 5 0
      sound/pci/hda/hda_codec.h
  3. 2 0
      sound/pci/hda/patch_realtek.c

+ 2 - 2
sound/pci/hda/hda_codec.c

@@ -2590,12 +2590,12 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
 				 unsigned int stream_tag, unsigned int format)
 				 unsigned int stream_tag, unsigned int format)
 {
 {
 	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
 	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
-	if (codec->spdif_ctls & AC_DIG1_ENABLE)
+	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 				    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
 				    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
 	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
 	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
 	/* turn on again (if needed) */
 	/* turn on again (if needed) */
-	if (codec->spdif_ctls & AC_DIG1_ENABLE)
+	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 				    codec->spdif_ctls & 0xff);
 				    codec->spdif_ctls & 0xff);
 }
 }

+ 5 - 0
sound/pci/hda/hda_codec.h

@@ -654,6 +654,11 @@ struct hda_codec {
 
 
 	struct snd_hwdep *hwdep;	/* assigned hwdep device */
 	struct snd_hwdep *hwdep;	/* assigned hwdep device */
 
 
+	/* misc flags */
+	unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
+					     * status change
+					     * (e.g. Realtek codecs)
+					     */
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	unsigned int power_on :1;	/* current (global) power-state */
 	unsigned int power_on :1;	/* current (global) power-state */
 	unsigned int power_transition :1; /* power-state in transition */
 	unsigned int power_transition :1; /* power-state in transition */

+ 2 - 0
sound/pci/hda/patch_realtek.c

@@ -2670,6 +2670,8 @@ static int alc_build_pcms(struct hda_codec *codec)
 			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
 			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 		}
 		}
+		/* FIXME: do we need this for all Realtek codec models? */
+		codec->spdif_status_reset = 1;
 	}
 	}
 
 
 	/* If the use of more than one ADC is requested for the current
 	/* If the use of more than one ADC is requested for the current