[alsa-devel] ALC892 optical SPDIF not working
Takashi Iwai
tiwai at suse.de
Mon Aug 2 10:02:48 CEST 2010
At Sun, 1 Aug 2010 01:32:23 +0200,
Manuel Lauss wrote:
>
> > > >> Is there a way to insert an initial playback delay? Under linux, the
> > > >> first 2-2.5 seconds
> > > >> of anything played are just silence; on windows audible playback
> > > >> starts immediately.
> > > >
> > > > It's the time for synchronization your digital receiver takes, I guess.
> > > > Maybe changing SPDIF status makes it resync, which happens at each
> > > > opening / closing the stream.
> > >
> > > Yes, seems so. I've found a workaround in meantime.
> >
> > Could you elaborate on the workaround please, so others having this
> > issue know it.
>
> My receiver allows to mix analog and digital inputs; with analog mix
> enabled it syncs immediately.
Just wondering whether the patch below helps?
It's just a proof-of-concept, and it's not safe for multiple streams.
If this works, we can move on the improvement of the stream assignment.
thanks,
Takashi
---
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 4d5abbd..45f2bb3 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1181,38 +1181,30 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag,
int channel_id, int format)
{
+ u32 oldval;
+
if (!nid)
return;
snd_printdd("hda_codec_setup_stream: "
"NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
nid, stream_tag, channel_id, format);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
- (stream_tag << 4) | channel_id);
- msleep(1);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
+ stream_tag = (stream_tag << 4) | channel_id;
+ oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
+ if (stream_tag != oldval) {
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CHANNEL_STREAMID, stream_tag);
+ }
+ oldval = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_STREAM_FORMAT, 0);
+ if (format != oldval) {
+ msleep(1);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT,
+ format);
+ }
}
EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
-/**
- * snd_hda_codec_cleanup_stream - clean up the codec for closing
- * @codec: the CODEC to clean up
- * @nid: the NID to clean up
- */
-void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
-{
- if (!nid)
- return;
-
- snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
-#if 0 /* keep the format */
- msleep(1);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
-#endif
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
-
/*
* amp access functions
*/
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index a115c0c..61e177d 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -927,7 +927,10 @@ int snd_hda_codec_build_pcms(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);*/
+static inline void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) {}
+
+
unsigned int snd_hda_calc_stream_format(unsigned int rate,
unsigned int channels,
unsigned int format,
More information about the Alsa-devel
mailing list