[alsa-devel] [PATCH] AD1986A 6-channel bugs

zhejiang zhe.jiang at intel.com
Fri Oct 26 11:19:31 CEST 2007


On Thu, 2007-10-25 at 10:05 +0200, Takashi Iwai wrote:
> 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?
> 

I have tested them and they are okay! Thanks!
> 
> 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