[alsa-devel] [PATCH] ALSA: hda - Send CONNECT_SEL on capture start

Takashi Iwai tiwai at suse.de
Wed Nov 16 09:53:43 CET 2011


At Wed, 16 Nov 2011 00:25:49 -0800,
Dylan Reid wrote:
> 
> cur_adc is set to zero in cs_capture_pcm_prepare.

Not really.  It's set to zero until cs_capture_pcm_preare() is called.

>  This causes the
> SET_CONNECT_SEL verb to be sent to node zero when doing automic after
> recording.  Delay sending the command until we are about to start
> capture and cur_adc is set to the correct NID.
> 
> Signed-off-by: Dylan Reid <dgreid at chromium.org>
> ---
>  sound/pci/hda/patch_cirrus.c |   16 ++++++++++------
>  1 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
> index 2a2d864..30f2f6a 100644
> --- a/sound/pci/hda/patch_cirrus.c
> +++ b/sound/pci/hda/patch_cirrus.c
> @@ -250,6 +250,9 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
>  	spec->cur_adc = spec->adc_nid[spec->cur_input];
>  	spec->cur_adc_stream_tag = stream_tag;
>  	spec->cur_adc_format = format;
> +	snd_hda_codec_write(codec, spec->cur_adc, 0,
> +			    AC_VERB_SET_CONNECT_SEL,
> +			    spec->adc_idx[spec->cur_input]);
>  	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
>  	return 0;
>  }
> @@ -685,13 +688,13 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
>  		/* stream is running, let's swap the current ADC */
>  		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
>  		spec->cur_adc = spec->adc_nid[idx];
> +		snd_hda_codec_write(codec, spec->cur_adc, 0,
> +				    AC_VERB_SET_CONNECT_SEL,
> +				    spec->adc_idx[idx]);
>  		snd_hda_codec_setup_stream(codec, spec->cur_adc,
>  					   spec->cur_adc_stream_tag, 0,
>  					   spec->cur_adc_format);
>  	}
> -	snd_hda_codec_write(codec, spec->cur_adc, 0,
> -			    AC_VERB_SET_CONNECT_SEL,
> -			    spec->adc_idx[idx]);

This breaks the case when the input-source is changed dynamically
during the recording with CS420x.


>  	spec->cur_input = idx;
>  	return 1;
>  }
> @@ -974,9 +977,10 @@ static void cs_automic(struct hda_codec *codec)
>  			spec->cur_input = spec->last_input;
>  		}
>  
> -		snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
> -					AC_VERB_SET_CONNECT_SEL,
> -					spec->adc_idx[spec->cur_input]);
> +		if (spec->cur_adc)
> +			snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
> +				AC_VERB_SET_CONNECT_SEL,
> +				spec->adc_idx[spec->cur_input]);

Well, it'd be better to create a function instead of scattering the
same verb call allover.

How about the (untested) patch below instead?


Takashi

---
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 2a2d864..2fbab8e 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -237,6 +237,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 }
 
+static void cs_update_input_select(struct hda_codec *codec)
+{
+	struct cs_spec *spec = codec->spec;
+	if (spec->cur_adc)
+		snd_hda_codec_write(codec, spec->cur_adc, 0,
+				    AC_VERB_SET_CONNECT_SEL,
+				    spec->adc_idx[spec->cur_input]);
+}
+
 /*
  * Analog capture
  */
@@ -250,6 +259,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 	spec->cur_adc = spec->adc_nid[spec->cur_input];
 	spec->cur_adc_stream_tag = stream_tag;
 	spec->cur_adc_format = format;
+	cs_update_input_select(codec);
 	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
 	return 0;
 }
@@ -689,10 +699,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
 					   spec->cur_adc_stream_tag, 0,
 					   spec->cur_adc_format);
 	}
-	snd_hda_codec_write(codec, spec->cur_adc, 0,
-			    AC_VERB_SET_CONNECT_SEL,
-			    spec->adc_idx[idx]);
 	spec->cur_input = idx;
+	cs_update_input_select(codec);
 	return 1;
 }
 
@@ -973,10 +981,7 @@ static void cs_automic(struct hda_codec *codec)
 		} else  {
 			spec->cur_input = spec->last_input;
 		}
-
-		snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
-					AC_VERB_SET_CONNECT_SEL,
-					spec->adc_idx[spec->cur_input]);
+		cs_update_input_select(codec);
 	} else {
 		if (present)
 			change_cur_input(codec, spec->automic_idx, 0);
@@ -1073,9 +1078,7 @@ static void init_input(struct hda_codec *codec)
 			cs_automic(codec);
 		else  {
 			spec->cur_adc = spec->adc_nid[spec->cur_input];
-			snd_hda_codec_write(codec, spec->cur_adc, 0,
-					AC_VERB_SET_CONNECT_SEL,
-					spec->adc_idx[spec->cur_input]);
+			cs_update_input_select(codec);
 		}
 	} else {
 		change_cur_input(codec, spec->cur_input, 1);


More information about the Alsa-devel mailing list