Patchwork [QUANTAL] ALSA: hda - use both input paths on Conexant auto parser

login
register
mail settings
Submitter David Henningsson
Date Sept. 26, 2012, 8:55 a.m.
Message ID <1348649737-5094-1-git-send-email-david.henningsson@canonical.com>
Download mbox | patch
Permalink /patch/187014/
State New
Headers show

Comments

David Henningsson - Sept. 26, 2012, 8:55 a.m.
On the Thinkpad W520 - and probably several other machines with
Conexant 506x chips - the Dock Mic and Mic are connected to the
same two selector nodes. This patch will make Dock Mic take one
selector node and Mic take the other, when possible.

Without the patch, both paths would take the first selector,
leading to the normal Mic's volume being controlled by
"Dock Mic Boost".
(On other machines, this could instead fixup similar problems between
Mic and Line In, for example.)

BugLink: https://bugs.launchpad.net/bugs/1037642
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
(cherry picked from commit 739572a545b8ab6faf9e266c3ed83ea202073699,
 linux/kernel/git/tiwai/sound.git)

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---

Motivation:
 * Bug tagged with regression-release
 * Takashi did not want to send to stable because it renames some mixer element
   (change of behaviour). Since we haven't released 12.10 yet, that argument does
   not apply to us.

 sound/pci/hda/patch_conexant.c |   20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
Tim Gardner - Sept. 26, 2012, 12:15 p.m.

Colin King - Oct. 6, 2012, 12:30 p.m.
David,

This patch unfortunately breaks audio on my Lenovo ThinkPad x230. I 
reverted the patch and then audio works again.  :-/

Colin

On 26/09/12 09:55, David Henningsson wrote:
> On the Thinkpad W520 - and probably several other machines with
> Conexant 506x chips - the Dock Mic and Mic are connected to the
> same two selector nodes. This patch will make Dock Mic take one
> selector node and Mic take the other, when possible.
>
> Without the patch, both paths would take the first selector,
> leading to the normal Mic's volume being controlled by
> "Dock Mic Boost".
> (On other machines, this could instead fixup similar problems between
> Mic and Line In, for example.)
>
> BugLink: https://bugs.launchpad.net/bugs/1037642
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> (cherry picked from commit 739572a545b8ab6faf9e266c3ed83ea202073699,
>   linux/kernel/git/tiwai/sound.git)
>
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> ---
>
> Motivation:
>   * Bug tagged with regression-release
>   * Takashi did not want to send to stable because it renames some mixer element
>     (change of behaviour). Since we haven't released 12.10 yet, that argument does
>     not apply to us.
>
>   sound/pci/hda/patch_conexant.c |   20 ++++++++++++++++----
>   1 file changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
> index 41f28c8..0c127cf 100644
> --- a/sound/pci/hda/patch_conexant.c
> +++ b/sound/pci/hda/patch_conexant.c
> @@ -3545,8 +3545,9 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
>   				     hda_nid_t pin, hda_nid_t *srcp,
>   				     bool do_select, int depth)
>   {
> +	struct conexant_spec *spec = codec->spec;
>   	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
> -	int i, nums;
> +	int startidx, i, nums;
>
>   	switch (get_wcaps_type(get_wcaps(codec, mux))) {
>   	case AC_WID_AUD_IN:
> @@ -3570,14 +3571,25 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
>   	depth++;
>   	if (depth == 2)
>   		return -1;
> +
> +	/* Try to rotate around connections to avoid one boost controlling
> +	   another input path as well */
> +	startidx = 0;
> +	for (i = 0; i < spec->private_imux.num_items; i++)
> +		if (spec->imux_info[i].pin == pin) {
> +			startidx = i;
> +			break;
> +		}
> +
>   	for (i = 0; i < nums; i++) {
> -		int ret  = __select_input_connection(codec, conn[i], pin, srcp,
> +		int j = (i + startidx) % nums;
> +		int ret  = __select_input_connection(codec, conn[j], pin, srcp,
>   						     do_select, depth);
>   		if (ret >= 0) {
>   			if (do_select)
>   				snd_hda_codec_write(codec, mux, 0,
> -						    AC_VERB_SET_CONNECT_SEL, i);
> -			return i;
> +						    AC_VERB_SET_CONNECT_SEL, j);
> +			return j;
>   		}
>   	}
>   	return -1;
>
Colin King - Oct. 7, 2012, 7:19 p.m.
On 06/10/12 13:30, Colin Ian King wrote:
> David,
>
> This patch unfortunately breaks audio on my Lenovo ThinkPad x230. I
> reverted the patch and then audio works again.  :-/
>
> Colin

I was wrong. After watching some content audio died with this reverted 
too. Seems like its some other issue.

Colin
>
> On 26/09/12 09:55, David Henningsson wrote:
>> On the Thinkpad W520 - and probably several other machines with
>> Conexant 506x chips - the Dock Mic and Mic are connected to the
>> same two selector nodes. This patch will make Dock Mic take one
>> selector node and Mic take the other, when possible.
>>
>> Without the patch, both paths would take the first selector,
>> leading to the normal Mic's volume being controlled by
>> "Dock Mic Boost".
>> (On other machines, this could instead fixup similar problems between
>> Mic and Line In, for example.)
>>
>> BugLink: https://bugs.launchpad.net/bugs/1037642
>> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
>> Signed-off-by: Takashi Iwai <tiwai@suse.de>
>> (cherry picked from commit 739572a545b8ab6faf9e266c3ed83ea202073699,
>>   linux/kernel/git/tiwai/sound.git)
>>
>> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
>> ---
>>
>> Motivation:
>>   * Bug tagged with regression-release
>>   * Takashi did not want to send to stable because it renames some
>> mixer element
>>     (change of behaviour). Since we haven't released 12.10 yet, that
>> argument does
>>     not apply to us.
>>
>>   sound/pci/hda/patch_conexant.c |   20 ++++++++++++++++----
>>   1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/sound/pci/hda/patch_conexant.c
>> b/sound/pci/hda/patch_conexant.c
>> index 41f28c8..0c127cf 100644
>> --- a/sound/pci/hda/patch_conexant.c
>> +++ b/sound/pci/hda/patch_conexant.c
>> @@ -3545,8 +3545,9 @@ static int __select_input_connection(struct
>> hda_codec *codec, hda_nid_t mux,
>>                        hda_nid_t pin, hda_nid_t *srcp,
>>                        bool do_select, int depth)
>>   {
>> +    struct conexant_spec *spec = codec->spec;
>>       hda_nid_t conn[HDA_MAX_NUM_INPUTS];
>> -    int i, nums;
>> +    int startidx, i, nums;
>>
>>       switch (get_wcaps_type(get_wcaps(codec, mux))) {
>>       case AC_WID_AUD_IN:
>> @@ -3570,14 +3571,25 @@ static int __select_input_connection(struct
>> hda_codec *codec, hda_nid_t mux,
>>       depth++;
>>       if (depth == 2)
>>           return -1;
>> +
>> +    /* Try to rotate around connections to avoid one boost controlling
>> +       another input path as well */
>> +    startidx = 0;
>> +    for (i = 0; i < spec->private_imux.num_items; i++)
>> +        if (spec->imux_info[i].pin == pin) {
>> +            startidx = i;
>> +            break;
>> +        }
>> +
>>       for (i = 0; i < nums; i++) {
>> -        int ret  = __select_input_connection(codec, conn[i], pin, srcp,
>> +        int j = (i + startidx) % nums;
>> +        int ret  = __select_input_connection(codec, conn[j], pin, srcp,
>>                                do_select, depth);
>>           if (ret >= 0) {
>>               if (do_select)
>>                   snd_hda_codec_write(codec, mux, 0,
>> -                            AC_VERB_SET_CONNECT_SEL, i);
>> -            return i;
>> +                            AC_VERB_SET_CONNECT_SEL, j);
>> +            return j;
>>           }
>>       }
>>       return -1;
>>
>
David Henningsson - Oct. 8, 2012, 6:45 a.m.
On 10/07/2012 09:19 PM, Colin Ian King wrote:
> On 06/10/12 13:30, Colin Ian King wrote:
>> David,
>>
>> This patch unfortunately breaks audio on my Lenovo ThinkPad x230. I
>> reverted the patch and then audio works again.  :-/
>>
>> Colin
>
> I was wrong. After watching some content audio died with this reverted
> too. Seems like its some other issue.
>
> Colin

Ok. Do you have any strange messages in dmesg/syslog/etc when this happens?

There was another bug that surfaced when this first bug was fixed, see 
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1059523 - but 
without seeing your alsa-info I have no idea if this related to you or not.

Patch

diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 41f28c8..0c127cf 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3545,8 +3545,9 @@  static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
 				     hda_nid_t pin, hda_nid_t *srcp,
 				     bool do_select, int depth)
 {
+	struct conexant_spec *spec = codec->spec;
 	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
-	int i, nums;
+	int startidx, i, nums;
 
 	switch (get_wcaps_type(get_wcaps(codec, mux))) {
 	case AC_WID_AUD_IN:
@@ -3570,14 +3571,25 @@  static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
 	depth++;
 	if (depth == 2)
 		return -1;
+
+	/* Try to rotate around connections to avoid one boost controlling
+	   another input path as well */
+	startidx = 0;
+	for (i = 0; i < spec->private_imux.num_items; i++)
+		if (spec->imux_info[i].pin == pin) {
+			startidx = i;
+			break;
+		}
+
 	for (i = 0; i < nums; i++) {
-		int ret  = __select_input_connection(codec, conn[i], pin, srcp,
+		int j = (i + startidx) % nums;
+		int ret  = __select_input_connection(codec, conn[j], pin, srcp,
 						     do_select, depth);
 		if (ret >= 0) {
 			if (do_select)
 				snd_hda_codec_write(codec, mux, 0,
-						    AC_VERB_SET_CONNECT_SEL, i);
-			return i;
+						    AC_VERB_SET_CONNECT_SEL, j);
+			return j;
 		}
 	}
 	return -1;