[alsa-devel] [PATCH 1/2] ALSA: hda - Move the function "check_amp_caps" to hda_codec.c
The next patch will use it, so make it visible across modules.
Signed-off-by: David Henningsson david.henningsson@canonical.com --- sound/pci/hda/hda_codec.c | 20 ++++++++++++++++++++ sound/pci/hda/hda_generic.c | 17 ----------------- sound/pci/hda/hda_local.h | 8 ++++++++ 3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0aa2e1e..15e0089 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2002,6 +2002,26 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) EXPORT_SYMBOL_GPL(query_amp_caps);
/** + * snd_hda_check_amp_caps - query AMP capabilities + * @codec: the HD-audio codec + * @nid: the NID to query + * @dir: either #HDA_INPUT or #HDA_OUTPUT + * + * Check whether the widget has the given amp capability for the direction. + */ +bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid, + int dir, unsigned int bits) +{ + if (!nid) + return false; + if (get_wcaps(codec, nid) & (1 << (dir + 1))) + if (query_amp_caps(codec, nid, dir) & bits) + return true; + return false; +} +EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps); + +/** * snd_hda_override_amp_caps - Override the AMP capabilities * @codec: the CODEC to clean up * @nid: the NID to clean up diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 32a85f9..64220c0 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -519,18 +519,6 @@ static unsigned int amp_val_replace_channels(unsigned int val, unsigned int chs) return val; }
-/* check whether the widget has the given amp capability for the direction */ -static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, - int dir, unsigned int bits) -{ - if (!nid) - return false; - if (get_wcaps(codec, nid) & (1 << (dir + 1))) - if (query_amp_caps(codec, nid, dir) & bits) - return true; - return false; -} - static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, hda_nid_t nid2, int dir) { @@ -540,11 +528,6 @@ static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, query_amp_caps(codec, nid2, dir)); }
-#define nid_has_mute(codec, nid, dir) \ - check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) -#define nid_has_volume(codec, nid, dir) \ - check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) - /* look for a widget suitable for assigning a mute switch in the path */ static hda_nid_t look_for_out_mute_nid(struct hda_codec *codec, struct nid_path *path) diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 8a018d4..7eb44e7 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -603,6 +603,14 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, unsigned int caps); +bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid, + int dir, unsigned int bits); + +#define nid_has_mute(codec, nid, dir) \ + snd_hda_check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) +#define nid_has_volume(codec, nid, dir) \ + snd_hda_check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) +
/* flags for hda_nid_item */ #define HDA_NID_ITEM_AMP (1<<0)
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(-)
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;
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
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.
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
At Tue, 23 Sep 2014 10:38:17 +0200, David Henningsson wrote:
The next patch will use it, so make it visible across modules.
Signed-off-by: David Henningsson david.henningsson@canonical.com
Applied both patches. Thanks.
Takashi
sound/pci/hda/hda_codec.c | 20 ++++++++++++++++++++ sound/pci/hda/hda_generic.c | 17 ----------------- sound/pci/hda/hda_local.h | 8 ++++++++ 3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0aa2e1e..15e0089 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2002,6 +2002,26 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) EXPORT_SYMBOL_GPL(query_amp_caps);
/**
- snd_hda_check_amp_caps - query AMP capabilities
- @codec: the HD-audio codec
- @nid: the NID to query
- @dir: either #HDA_INPUT or #HDA_OUTPUT
- Check whether the widget has the given amp capability for the direction.
- */
+bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
int dir, unsigned int bits)
+{
- if (!nid)
return false;
- if (get_wcaps(codec, nid) & (1 << (dir + 1)))
if (query_amp_caps(codec, nid, dir) & bits)
return true;
- return false;
+} +EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps);
+/**
- snd_hda_override_amp_caps - Override the AMP capabilities
- @codec: the CODEC to clean up
- @nid: the NID to clean up
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 32a85f9..64220c0 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -519,18 +519,6 @@ static unsigned int amp_val_replace_channels(unsigned int val, unsigned int chs) return val; }
-/* check whether the widget has the given amp capability for the direction */ -static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
int dir, unsigned int bits)
-{
- if (!nid)
return false;
- if (get_wcaps(codec, nid) & (1 << (dir + 1)))
if (query_amp_caps(codec, nid, dir) & bits)
return true;
- return false;
-}
static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, hda_nid_t nid2, int dir) { @@ -540,11 +528,6 @@ static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, query_amp_caps(codec, nid2, dir)); }
-#define nid_has_mute(codec, nid, dir) \
- check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
-#define nid_has_volume(codec, nid, dir) \
- check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
/* look for a widget suitable for assigning a mute switch in the path */ static hda_nid_t look_for_out_mute_nid(struct hda_codec *codec, struct nid_path *path) diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 8a018d4..7eb44e7 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -603,6 +603,14 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, unsigned int caps); +bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
int dir, unsigned int bits);
+#define nid_has_mute(codec, nid, dir) \
- snd_hda_check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
+#define nid_has_volume(codec, nid, dir) \
- snd_hda_check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
/* flags for hda_nid_item */
#define HDA_NID_ITEM_AMP (1<<0)
1.9.1
participants (3)
-
David Henningsson
-
Raymond Yau
-
Takashi Iwai