[alsa-devel] [PATCH] AD1986A 6-channel bugs
Takashi Iwai
tiwai at suse.de
Thu Oct 25 10:05:21 CEST 2007
At Thu, 25 Oct 2007 15:05:40 +0800,
zhejiang wrote:
>
> Hi,
>
> I have a ICH8M + AD1986A machine.
>
> In 6 channel modes, if adjust the volumes when playing 2-channel or
> 4-channel music, codec will be muted and all widget's Amp-Out vals will
> be reset. If you play 2-channel files in 6 channel modes,there is noise
> in the jacks.
>
> By doing experiments, I found that the 6-channel bug was caused by
> sharing channels.
>
> If play 2-channel audio file,the rest channels will share channels with
> the first 2-channel.
>
> The HDA spec doesn’t define the exact behavior under such circumstances.
>
> Majority of the codec chips support sharing channel, but seem that
> AD1986A doesn’t support.
>
> I wrote a patch and tested it in my hardware,now it works well.
Thanks! It's been a bug that I hardly understood what was wrong.
IMO, it's better to have a flag in hda_multi_out rather than
hardcoding the codec id there.
Could you check whether the patch below works?
Takashi
diff -r 4f3f2f4bd5e9 pci/hda/hda_codec.c
--- a/pci/hda/hda_codec.c Wed Oct 24 18:18:11 2007 +0200
+++ b/pci/hda/hda_codec.c Thu Oct 25 11:39:55 2007 +0200
@@ -2486,13 +2486,14 @@ int snd_hda_multi_out_analog_prepare(str
/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
0, format);
- if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
+ if (!mout->no_share_stream &&
+ mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
/* headphone out will just decode front left/right (stereo) */
snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
0, format);
/* extra outputs copied from front */
for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (mout->extra_out_nid[i])
+ if (!mout->no_share_stream && mout->extra_out_nid[i])
snd_hda_codec_setup_stream(codec,
mout->extra_out_nid[i],
stream_tag, 0, format);
@@ -2502,7 +2503,7 @@ int snd_hda_multi_out_analog_prepare(str
if (chs >= (i + 1) * 2) /* independent out */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
i * 2, format);
- else /* copy front */
+ else if (!mout->no_share_stream) /* copy front */
snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
0, format);
}
diff -r 4f3f2f4bd5e9 pci/hda/hda_local.h
--- a/pci/hda/hda_local.h Wed Oct 24 18:18:11 2007 +0200
+++ b/pci/hda/hda_local.h Thu Oct 25 11:39:55 2007 +0200
@@ -220,6 +220,7 @@ struct hda_multi_out {
hda_nid_t dig_out_nid; /* digital out audio widget */
int max_channels; /* currently supported analog channels */
int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
+ int no_share_stream; /* don't share a stream with multiple pins */
};
int snd_hda_multi_out_dig_open(struct hda_codec *codec,
diff -r 4f3f2f4bd5e9 pci/hda/patch_analog.c
--- a/pci/hda/patch_analog.c Wed Oct 24 18:18:11 2007 +0200
+++ b/pci/hda/patch_analog.c Thu Oct 25 11:39:55 2007 +0200
@@ -956,6 +956,14 @@ static int patch_ad1986a(struct hda_code
spec->multiout.dig_out_nid = 0;
break;
}
+
+ /* AD1986A has a hardware problem that it can't share a stream
+ * with multiple output pins. The copy of front to surrounds
+ * causes noisy or silent outputs at a certain timing, e.g.
+ * changing the volume.
+ * So, let's disable the shared stream.
+ */
+ spec->multiout.no_share_stream = 1;
return 0;
}
More information about the Alsa-devel
mailing list