[2/2] ALSA: hda - Sort input pins depending on amp caps
diff mbox

Message ID 1411461498-11837-2-git-send-email-david.henningsson@canonical.com
State Accepted
Commit 95f72cf2cdf0e612aeaf36d8af51689882fd64db
Delegated to: Takashi Iwai
Headers show

Commit Message

David Henningsson Sept. 23, 2014, 8:38 a.m. UTC
If one input has a boost and another one has not, and they're equal
otherwise, it's more likely you want to use the input with the boost
as your primary input.

See hda-emu.git/codecs/canonical/cx20590-lenovo-20b2z00bus-ccert-201305-13496
for an example.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 sound/pci/hda/hda_auto_parser.c | 21 ++++++++++++++-------
 sound/pci/hda/hda_auto_parser.h |  1 +
 2 files changed, 15 insertions(+), 7 deletions(-)

Comments

Raymond Yau Sept. 24, 2014, 3:31 a.m. UTC | #1
>
> If one input has a boost and another one has not, and they're equal
> otherwise, it's more likely you want to use the input with the boost
> as your primary input.
>
> See
hda-emu.git/codecs/canonical/cx20590-lenovo-20b2z00bus-ccert-201305-13496
> for an example.

Is this a firmware bug since your firmware 1.02 have two internal Mic 0x1e
and 0x23 but firmware 1.09 only have one internal mic 0x23

http://www.alsa-project.org/db/?f=a265ed3ac422c0ea77b0ada8596338c6421b4de1

Cannot detect the codec with firmware 1.10

http://www.alsa-project.org/db/?f=a60449e5a19b3dbb7a422defd5a9d51f56216693

The proper fix is remove the redundant internal Mic since auto Mic is
disabled
David Henningsson Sept. 24, 2014, 6:33 a.m. UTC | #2
On 2014-09-24 05:31, Raymond Yau wrote:
>  >
>  > If one input has a boost and another one has not, and they're equal
>  > otherwise, it's more likely you want to use the input with the boost
>  > as your primary input.
>  >
>  > See
> hda-emu.git/codecs/canonical/cx20590-lenovo-20b2z00bus-ccert-201305-13496
>  > for an example.
>
> Is this a firmware bug since your firmware 1.02 have two internal Mic
> 0x1e and 0x23 but firmware 1.09 only have one internal mic 0x23
>
> http://www.alsa-project.org/db/?f=a265ed3ac422c0ea77b0ada8596338c6421b4de1
>
> Cannot detect the codec with firmware 1.10
>
> http://www.alsa-project.org/db/?f=a60449e5a19b3dbb7a422defd5a9d51f56216693
>
> The proper fix is remove the redundant internal Mic since auto Mic is
> disabled

The E545 has dual-array mics, so probably both pins are actual internal 
mics.
It seems reasonable that upgrading the firmware would also resolve this 
problem, but either way I believe this is a good patch for potentially 
future codecs in the same situation.
Raymond Yau Sept. 24, 2014, 8:59 a.m. UTC | #3
>>
>>  >
>>  > If one input has a boost and another one has not, and they're equal
>>  > otherwise, it's more likely you want to use the input with the boost
>>  > as your primary input.
>>  >
>>  > See
>> hda-emu.git/codecs/canonical/cx20590-lenovo-20b2z00bus-ccert-201305-13496
>>  > for an example.
>>
>> Is this a firmware bug since your firmware 1.02 have two internal Mic
>> 0x1e and 0x23 but firmware 1.09 only have one internal mic 0x23
>>
>>
http://www.alsa-project.org/db/?f=a265ed3ac422c0ea77b0ada8596338c6421b4de1
>>
>> Cannot detect the codec with firmware 1.10
>>
>>
http://www.alsa-project.org/db/?f=a60449e5a19b3dbb7a422defd5a9d51f56216693
>>
>> The proper fix is remove the redundant internal Mic since auto Mic is
>> disabled
>
>
> The E545 has dual-array mics, so probably both pins are actual internal
mics.
> It seems reasonable that upgrading the firmware would also resolve this
problem, but either way I believe this is a good patch for potentially
future codecs in the same situation.
>

If dual array mic use two nodes and you can record from any one of the
internal mic using the capture source control

Need to implement multi channel capture if you need to record with both mic

Patch
diff mbox

diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 51dea49..fcc5e47 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -57,12 +57,14 @@  static void sort_pins_by_sequence(hda_nid_t *pins, struct auto_out_pin *list,
 
 
 /* add the found input-pin to the cfg->inputs[] table */
-static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid,
-				   int type)
+static void add_auto_cfg_input_pin(struct hda_codec *codec, struct auto_pin_cfg *cfg,
+				   hda_nid_t nid, int type)
 {
 	if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
 		cfg->inputs[cfg->num_inputs].pin = nid;
 		cfg->inputs[cfg->num_inputs].type = type;
+		cfg->inputs[cfg->num_inputs].has_boost_on_pin =
+			nid_has_volume(codec, nid, HDA_INPUT);
 		cfg->num_inputs++;
 	}
 }
@@ -71,7 +73,12 @@  static int compare_input_type(const void *ap, const void *bp)
 {
 	const struct auto_pin_cfg_item *a = ap;
 	const struct auto_pin_cfg_item *b = bp;
-	return (int)(a->type - b->type);
+	if (a->type != b->type)
+		return (int)(a->type - b->type);
+
+	/* In case one has boost and the other one has not,
+	   pick the one with boost first. */
+	return (int)(b->has_boost_on_pin - a->has_boost_on_pin);
 }
 
 /* Reorder the surround channels
@@ -268,16 +275,16 @@  int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
 			cfg->hp_outs++;
 			break;
 		case AC_JACK_MIC_IN:
-			add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC);
+			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_MIC);
 			break;
 		case AC_JACK_LINE_IN:
-			add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN);
+			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_LINE_IN);
 			break;
 		case AC_JACK_CD:
-			add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD);
+			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_CD);
 			break;
 		case AC_JACK_AUX:
-			add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX);
+			add_auto_cfg_input_pin(codec, cfg, nid, AUTO_PIN_AUX);
 			break;
 		case AC_JACK_SPDIF_OUT:
 		case AC_JACK_DIG_OTHER_OUT:
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h
index e941f60..2b8e29f 100644
--- a/sound/pci/hda/hda_auto_parser.h
+++ b/sound/pci/hda/hda_auto_parser.h
@@ -38,6 +38,7 @@  struct auto_pin_cfg_item {
 	int type;
 	unsigned int is_headset_mic:1;
 	unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */
+	unsigned int has_boost_on_pin:1;
 };
 
 struct auto_pin_cfg;