[alsa-devel] [PATCH 00/12] More updates on HD-audio generic parser
Hi,
not surprisingly, here is another batch for fixing / improving the HD-audio generic parser code. With these, now AD and IDT codecs have proper analog-loopback features, and VIA and Conexant codecs have better aamix handling. The conflict of aamixer and indep-hp mode seen on VIA codecs should have been fixed now.
As usual, all changes are found in test/hda-gen-parser (or test/hda-migrate) branch of sound-unstable tree. It's already merged in master branch as well.
Takashi
Looking through the whole definitions, some fields have inappropriate array sizes, especially about the capture. The array assigned to each input (pin) should have HDA_MAX_NUM_INPUTS entries while the array assigned to each ADC should have AUTO_CFG_MAX_INS entries.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index eacfca9..696b606 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -102,11 +102,11 @@ struct hda_gen_spec {
/* capture */ unsigned int num_adc_nids; - hda_nid_t adc_nids[AUTO_CFG_MAX_OUTS]; + hda_nid_t adc_nids[AUTO_CFG_MAX_INS]; hda_nid_t dig_in_nid; /* digital-in NID; optional */ hda_nid_t mixer_nid; /* analog-mixer NID */ - const char *input_labels[AUTO_CFG_MAX_INS]; - int input_label_idxs[AUTO_CFG_MAX_INS]; + const char *input_labels[HDA_MAX_NUM_INPUTS]; + int input_label_idxs[HDA_MAX_NUM_INPUTS];
/* capture setup for dynamic dual-adc switch */ hda_nid_t cur_adc; @@ -148,7 +148,7 @@ struct hda_gen_spec { int num_all_dacs; hda_nid_t all_dacs[16]; int num_all_adcs; - hda_nid_t all_adcs[AUTO_CFG_MAX_OUTS]; + hda_nid_t all_adcs[AUTO_CFG_MAX_INS];
/* path list */ struct snd_array paths;
Conexant CX20551 codec has a mixer in NID 0x19 and a few outputs have to take the input through this widget.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_conexant.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2f94acb..2e6e2b0 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3197,6 +3197,9 @@ static const struct hda_codec_ops cx_auto_patch_ops = { .init = snd_hda_gen_init, .free = snd_hda_gen_free, .unsol_event = snd_hda_jack_unsol_event, +#ifdef CONFIG_PM + .check_power_status = snd_hda_gen_check_power_status, +#endif };
/* @@ -3348,6 +3351,10 @@ static int patch_conexant_auto(struct hda_codec *codec) case 0x14f15045: codec->single_adc_amp = 1; break; + case 0x14f15047: + codec->pin_amp_workaround = 1; + spec->gen.mixer_nid = 0x19; + break; case 0x14f15051: add_cx5051_fake_mutes(codec); codec->pin_amp_workaround = 1;
Print the information of outputs in a bit more details and concisely in a single place instead of printing the path at each time when detected.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 57 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 11 deletions(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 29f37c9..37d7ed7 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1113,7 +1113,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, if (!path) dac = dacs[i] = 0; else { - print_nid_path("output", path); + /* print_nid_path("output", path); */ path->active = true; path_idx[i] = snd_hda_get_path_idx(codec, path); badness += assign_out_path_ctls(codec, path); @@ -1240,7 +1240,7 @@ static int fill_multi_ios(struct hda_codec *codec, badness++; continue; } - print_nid_path("multiio", path); + /* print_nid_path("multiio", path); */ spec->multi_io[spec->multi_ios].pin = nid; spec->multi_io[spec->multi_ios].dac = dac; spec->out_paths[cfg->line_outs + spec->multi_ios] = @@ -1297,7 +1297,7 @@ static bool map_singles(struct hda_codec *codec, int outs, if (path) { dacs[i] = dac; found = true; - print_nid_path("output", path); + /* print_nid_path("output", path); */ path->active = true; path_idx[i] = snd_hda_get_path_idx(codec, path); } @@ -1320,7 +1320,7 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx) spec->mixer_nid); if (!path) return 0; - print_nid_path("output-aamix", path); + /* print_nid_path("output-aamix", path); */ path->active = false; /* unused as default */ return snd_hda_get_path_idx(codec, path); } @@ -1514,35 +1514,70 @@ static int fill_and_eval_dacs(struct hda_codec *codec, #define debug_badness(...) #endif
-static void debug_show_configs(struct hda_gen_spec *spec, struct auto_pin_cfg *cfg) +#ifdef DEBUG_BADNESS +static inline void print_nid_path_idx(struct hda_codec *codec, + const char *pfx, int idx) +{ + struct nid_path *path; + + path = snd_hda_get_path_from_idx(codec, idx); + if (path) + print_nid_path(pfx, path); +} + +static void debug_show_configs(struct hda_codec *codec, + struct auto_pin_cfg *cfg) { - debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", + struct hda_gen_spec *spec = codec->spec; +#ifdef CONFIG_SND_DEBUG_VERBOSE + static const char * const lo_type[3] = { "LO", "SP", "HP" }; +#endif + int i; + + debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x (type %s)\n", cfg->line_out_pins[0], cfg->line_out_pins[1], cfg->line_out_pins[2], cfg->line_out_pins[3], spec->multiout.dac_nids[0], spec->multiout.dac_nids[1], spec->multiout.dac_nids[2], - spec->multiout.dac_nids[3]); + spec->multiout.dac_nids[3], + lo_type[cfg->line_out_type]); + for (i = 0; i < cfg->line_outs; i++) + print_nid_path_idx(codec, " out", spec->out_paths[i]); if (spec->multi_ios > 0) debug_badness("multi_ios(%d) = %x/%x : %x/%x\n", spec->multi_ios, spec->multi_io[0].pin, spec->multi_io[1].pin, spec->multi_io[0].dac, spec->multi_io[1].dac); - debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", + for (i = 0; i < spec->multi_ios; i++) + print_nid_path_idx(codec, " mio", + spec->out_paths[cfg->line_outs + i]); + if (cfg->hp_outs) + debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", cfg->hp_pins[0], cfg->hp_pins[1], cfg->hp_pins[2], cfg->hp_pins[3], spec->multiout.hp_out_nid[0], spec->multiout.hp_out_nid[1], spec->multiout.hp_out_nid[2], spec->multiout.hp_out_nid[3]); - debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", + for (i = 0; i < cfg->hp_outs; i++) + print_nid_path_idx(codec, " hp ", spec->hp_paths[i]); + if (cfg->speaker_outs) + debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", cfg->speaker_pins[0], cfg->speaker_pins[1], cfg->speaker_pins[2], cfg->speaker_pins[3], spec->multiout.extra_out_nid[0], spec->multiout.extra_out_nid[1], spec->multiout.extra_out_nid[2], spec->multiout.extra_out_nid[3]); + for (i = 0; i < cfg->speaker_outs; i++) + print_nid_path_idx(codec, " spk", spec->speaker_paths[i]); + for (i = 0; i < 3; i++) + print_nid_path_idx(codec, " mix", spec->aamix_out_paths[i]); } +#else +#define debug_show_configs(codec, cfg) /* NOP */ +#endif
/* find all available DACs of the codec */ static void fill_all_dac_nids(struct hda_codec *codec) @@ -1590,7 +1625,7 @@ static int parse_output_paths(struct hda_codec *codec) debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", cfg->line_out_type, fill_hardwired, fill_mio_first, badness); - debug_show_configs(spec, cfg); + debug_show_configs(codec, cfg); if (badness < best_badness) { best_badness = badness; *best_cfg = *cfg; @@ -1646,7 +1681,7 @@ static int parse_output_paths(struct hda_codec *codec) } debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n", cfg->line_out_type, best_wired, best_mio); - debug_show_configs(spec, cfg); + debug_show_configs(codec, cfg);
if (cfg->line_out_pins[0]) { struct nid_path *path;
Since fill_and_eval_dacs() may be called repeatedly with different configurations, setting pinctls at each time there isn't optimal. We can set it better only once after deciding the output configuration in parse_output_paths().
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 37d7ed7..7b739b5 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1352,7 +1352,6 @@ static int fill_and_eval_dacs(struct hda_codec *codec, struct hda_gen_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i, err, badness; - unsigned int val;
/* set num_dacs once to full for look_for_dac() */ spec->multiout.num_dacs = cfg->line_outs; @@ -1489,20 +1488,6 @@ static int fill_and_eval_dacs(struct hda_codec *codec, spec->multiout.extra_out_nid, spec->speaker_paths);
- /* set initial pinctl targets */ - if (spec->prefer_hp_amp || cfg->line_out_type == AUTO_PIN_HP_OUT) - val = PIN_HP; - else - val = PIN_OUT; - set_pin_targets(codec, cfg->line_outs, cfg->line_out_pins, val); - if (cfg->line_out_type != AUTO_PIN_HP_OUT) - set_pin_targets(codec, cfg->hp_outs, cfg->hp_pins, PIN_HP); - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { - val = spec->prefer_hp_amp ? PIN_HP : PIN_OUT; - set_pin_targets(codec, cfg->speaker_outs, - cfg->speaker_pins, val); - } - return badness; }
@@ -1604,6 +1589,7 @@ static int parse_output_paths(struct hda_codec *codec) struct hda_gen_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; struct auto_pin_cfg *best_cfg; + unsigned int val; int best_badness = INT_MAX; int badness; bool fill_hardwired = true, fill_mio_first = true; @@ -1693,6 +1679,20 @@ static int parse_output_paths(struct hda_codec *codec) HDA_OUTPUT, spec->vmaster_tlv); }
+ /* set initial pinctl targets */ + if (spec->prefer_hp_amp || cfg->line_out_type == AUTO_PIN_HP_OUT) + val = PIN_HP; + else + val = PIN_OUT; + set_pin_targets(codec, cfg->line_outs, cfg->line_out_pins, val); + if (cfg->line_out_type != AUTO_PIN_HP_OUT) + set_pin_targets(codec, cfg->hp_outs, cfg->hp_pins, PIN_HP); + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { + val = spec->prefer_hp_amp ? PIN_HP : PIN_OUT; + set_pin_targets(codec, cfg->speaker_outs, + cfg->speaker_pins, val); + } + kfree(best_cfg); return 0; }
When a patch couldn't be resolved in try_assign_dacs() although the target DAC is expected, we forgot to add a proper badness value but continued.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 7b739b5..4e9761a 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1105,14 +1105,17 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, else badness += bad->no_dac; } + if (!dac) + continue; path = snd_hda_add_new_path(codec, dac, pin, -spec->mixer_nid); if (!path && !i && spec->mixer_nid) { /* try with aamix */ path = snd_hda_add_new_path(codec, dac, pin, 0); } - if (!path) + if (!path) { dac = dacs[i] = 0; - else { + badness += bad->no_dac; + } else { /* print_nid_path("output", path); */ path->active = true; path_idx[i] = snd_hda_get_path_idx(codec, path);
Many codecs provide routes to multiple output pins through an aamix widget, but most of them do it only from a single DAC. However, the current generic parser checks only the aamix paths from the original (directly bound) DACs through aamix NID, and miss the path: primary DAC -> aamix -> target out pin
This patch adds a more check for the routes like the above.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 4e9761a..e26e8d3 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1313,14 +1313,26 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx) { struct hda_gen_spec *spec = codec->spec; struct nid_path *path; + hda_nid_t dac, pin;
path = snd_hda_get_path_from_idx(codec, path_idx); if (!path || !path->depth || is_nid_contained(path, spec->mixer_nid)) return 0; - path = snd_hda_add_new_path(codec, path->path[0], - path->path[path->depth - 1], - spec->mixer_nid); + dac = path->path[0]; + pin = path->path[path->depth - 1]; + path = snd_hda_add_new_path(codec, dac, pin, spec->mixer_nid); + if (!path) { + if (dac != spec->multiout.dac_nids[0]) + dac = spec->multiout.dac_nids[0]; + else if (spec->multiout.hp_out_nid[0]) + dac = spec->multiout.hp_out_nid[0]; + else if (spec->multiout.extra_out_nid[0]) + dac = spec->multiout.extra_out_nid[0]; + if (dac) + path = snd_hda_add_new_path(codec, dac, pin, + spec->mixer_nid); + } if (!path) return 0; /* print_nid_path("output-aamix", path); */
This patch eventually fixes two issues: - Handle the case where the primary output is a headphone and can have independent HP mode; so far we checked only the case where the headphone is the secondary output.
- Fix the conflict of HP independent mode and aamix mode; when switched to aamix mode, the DAC might be also switched to another widget shared with other outputs. Then even if we disable the DAC for the original output, it doesn't change -- because the active route is from another (shared) DAC to HP pin through aamix. So, in such a case, we have to prohibit the switch to aamix for HP routes.
This fixes issues appearing on VT codecs.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 59 +++++++++++++++++++++++++++++++++++++++------ sound/pci/hda/hda_generic.h | 1 + 2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index e26e8d3..6d1e843 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1845,6 +1845,10 @@ static int indep_hp_get(struct snd_kcontrol *kcontrol, return 0; }
+static void update_aamix_paths(struct hda_codec *codec, bool do_mix, + int nomix_path_idx, int mix_path_idx, + int out_type); + static int indep_hp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1860,11 +1864,31 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, }
if (spec->indep_hp_enabled != select) { + hda_nid_t *dacp; + if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) + dacp = &spec->private_dac_nids[0]; + else + dacp = &spec->multiout.hp_out_nid[0]; + + /* update HP aamix paths in case it conflicts with indep HP */ + if (spec->have_aamix_ctl) { + if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) + update_aamix_paths(codec, spec->aamix_mode, + spec->out_paths[0], + spec->aamix_out_paths[0], + spec->autocfg.line_out_type); + else + update_aamix_paths(codec, spec->aamix_mode, + spec->hp_paths[0], + spec->aamix_out_paths[1], + AUTO_PIN_HP_OUT); + } + spec->indep_hp_enabled = select; if (spec->indep_hp_enabled) - spec->multiout.hp_out_nid[0] = 0; + *dacp = 0; else - spec->multiout.hp_out_nid[0] = spec->alt_dac_nid; + *dacp = spec->alt_dac_nid; ret = 1; } unlock: @@ -1884,16 +1908,21 @@ static const struct snd_kcontrol_new indep_hp_ctl = { static int create_indep_hp_ctls(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; + hda_nid_t dac;
if (!spec->indep_hp) return 0; - if (!spec->multiout.hp_out_nid[0]) { + if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) + dac = spec->multiout.dac_nids[0]; + else + dac = spec->multiout.hp_out_nid[0]; + if (!dac) { spec->indep_hp = 0; return 0; }
spec->indep_hp_enabled = false; - spec->alt_dac_nid = spec->multiout.hp_out_nid[0]; + spec->alt_dac_nid = dac; if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl)) return -ENOMEM; return 0; @@ -2026,14 +2055,24 @@ static int loopback_mixing_get(struct snd_kcontrol *kcontrol, }
static void update_aamix_paths(struct hda_codec *codec, bool do_mix, - int nomix_path_idx, int mix_path_idx) + int nomix_path_idx, int mix_path_idx, + int out_type) { + struct hda_gen_spec *spec = codec->spec; struct nid_path *nomix_path, *mix_path;
nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx); mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx); if (!nomix_path || !mix_path) return; + + /* if HP aamix path is driven from a different DAC and the + * independent HP mode is ON, can't turn on aamix path + */ + if (out_type == AUTO_PIN_HP_OUT && spec->indep_hp_enabled && + mix_path->path[0] != spec->alt_dac_nid) + do_mix = false; + if (do_mix) { snd_hda_activate_path(codec, nomix_path, false, true); snd_hda_activate_path(codec, mix_path, true, true); @@ -2054,11 +2093,14 @@ static int loopback_mixing_put(struct snd_kcontrol *kcontrol, return 0; spec->aamix_mode = val; update_aamix_paths(codec, val, spec->out_paths[0], - spec->aamix_out_paths[0]); + spec->aamix_out_paths[0], + spec->autocfg.line_out_type); update_aamix_paths(codec, val, spec->hp_paths[0], - spec->aamix_out_paths[1]); + spec->aamix_out_paths[1], + AUTO_PIN_HP_OUT); update_aamix_paths(codec, val, spec->speaker_paths[0], - spec->aamix_out_paths[2]); + spec->aamix_out_paths[2], + AUTO_PIN_SPEAKER_OUT); return 1; }
@@ -2081,6 +2123,7 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec) return 0; if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) return -ENOMEM; + spec->have_aamix_ctl = 1; return 0; }
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 696b606..9c63555 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -212,6 +212,7 @@ struct hda_gen_spec { unsigned int no_analog:1; /* digital I/O only */ unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ unsigned int indep_hp_enabled:1; /* independent HP enabled */ + unsigned int have_aamix_ctl:1;
/* loopback mixing mode */ bool aamix_mode;
The original VIA codec parser enabled it as default, so let's keep the behavior as it was.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_via.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index eade21c..9d9583c 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -135,6 +135,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec) if (spec->codec_type == VT1708BCE) spec->codec_type = VT1708S; spec->no_pin_power_ctl = 1; + spec->gen.indep_hp = 1; spec->gen.pcm_playback_hook = via_playback_pcm_hook; return spec; }
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_analog.c | 1 - sound/pci/hda/patch_ca0110.c | 1 - sound/pci/hda/patch_cirrus.c | 1 - sound/pci/hda/patch_cmedia.c | 1 - sound/pci/hda/patch_realtek.c | 1 - sound/pci/hda/patch_sigmatel.c | 1 - 6 files changed, 6 deletions(-)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 6feaec4..162bc2f 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -20,7 +20,6 @@ */
#include <linux/init.h> -#include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/module.h> diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index db7635c..30b3a4b 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -19,7 +19,6 @@ */
#include <linux/init.h> -#include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/module.h> diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index b9dfbd8..72ebb8a 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -19,7 +19,6 @@ */
#include <linux/init.h> -#include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/module.h> diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 087cabb..9c6ce73 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -22,7 +22,6 @@ */
#include <linux/init.h> -#include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/module.h> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 79ff34d..6eb9551 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -29,7 +29,6 @@ #include <linux/pci.h> #include <linux/dmi.h> #include <linux/module.h> -#include <linux/sort.h> #include <sound/core.h> #include <sound/jack.h> #include "hda_codec.h" diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fe3e082..fd29f49 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -31,7 +31,6 @@ #include <linux/dmi.h> #include <linux/module.h> #include <sound/core.h> -#include <sound/asoundef.h> #include <sound/jack.h> #include <sound/tlv.h> #include "hda_codec.h"
IDT codecs have analog-loopback mixer widgets, but we haven't cared about it, so far. Let's set them. This will avoid also possible wrong routes for the input paths.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_sigmatel.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fd29f49..c53b6f9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3743,6 +3743,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
spec = codec->spec; spec->linear_tone_beep = 0; + spec->gen.mixer_nid = 0x1d;
num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1; if (num_dacs < 3 || num_dacs > 5) { @@ -3840,6 +3841,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec = codec->spec; spec->linear_tone_beep = 0; spec->gen.own_eapd_ctl = 1; + spec->gen.mixer_nid = 0x1b;
spec->digbeep_nid = 0x21; spec->pwr_nids = stac92hd83xxx_pwr_nids; @@ -3882,6 +3884,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) spec = codec->spec; spec->linear_tone_beep = 0; spec->gen.own_eapd_ctl = 1; + spec->gen.mixer_nid = 0x17;
codec->patch_ops = stac_patch_ops;
The aamix NIDs are also missing for AD codecs. All AD codecs seem to have a (more or less) working aamix widget.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_analog.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 162bc2f..ad79abd 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1187,6 +1187,7 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec) /* AD1986A has the inverted EAPD implementation */ codec->inv_eapd = 1;
+ spec->gen.mixer_nid = 0x07; spec->beep_dev_nid = 0x19; set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
@@ -1950,6 +1951,7 @@ static int ad1981_parse_auto_config(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec;
+ spec->gen.mixer_nid = 0x0e; spec->beep_dev_nid = 0x10; set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec); @@ -2825,6 +2827,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec;
+ spec->gen.mixer_nid = 0x20; spec->beep_dev_nid = 0x10; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec); @@ -3172,6 +3175,7 @@ static int ad1884_parse_auto_config(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec;
+ spec->gen.mixer_nid = 0x20; spec->beep_dev_nid = 0x10; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec); @@ -4632,7 +4636,7 @@ static int ad1882_parse_auto_config(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec;
- spec->beep_dev_nid = 0x10; + spec->beep_dev_nid = 0x20; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec); }
The aamix NIDs are also missing for AD codecs. All AD codecs seem to have a (more or less) working aamix widget.
Signed-off-by: Takashi Iwai tiwai@suse.de
@@ -4632,7 +4636,7 @@ static int ad1882_parse_auto_config(struct
hda_codec *codec)
{ struct ad198x_spec *spec = codec->spec;
spec->beep_dev_nid = 0x10;
spec->beep_dev_nid = 0x20; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec);
}
Seem typo in aamix nid
At Tue, 22 Jan 2013 20:57:47 +0800, Raymond Yau wrote:
The aamix NIDs are also missing for AD codecs. All AD codecs seem to have a (more or less) working aamix widget.
Signed-off-by: Takashi Iwai tiwai@suse.de
@@ -4632,7 +4636,7 @@ static int ad1882_parse_auto_config(struct
hda_codec *codec)
{ struct ad198x_spec *spec = codec->spec;
spec->beep_dev_nid = 0x10;
spec->beep_dev_nid = 0x20; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); return ad198x_parse_auto_config(codec);
}
Seem typo in aamix nid
Good catch, fixed now.
thanks,
Takashi
It'd be better to give another name to the secondary (alt) analog PCM stream, which is dedicated for the independent HP out and extra inputs.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_generic.c | 5 ++++- sound/pci/hda/hda_generic.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 6d1e843..63d12ef 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -4531,9 +4531,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) !spec->dyn_adc_switch && !spec->auto_mic; /* Additional Analaog capture for index #2 */ if (spec->alt_dac_nid || have_multi_adcs) { + fill_pcm_stream_name(spec->stream_name_alt_analog, + sizeof(spec->stream_name_alt_analog), + " Alt Analog", codec->chip_name); codec->num_pcms = 3; info = spec->pcm_rec + 2; - info->name = spec->stream_name_analog; + info->name = spec->stream_name_alt_analog; if (spec->alt_dac_nid) { p = spec->stream_analog_alt_playback; if (!p) diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 9c63555..980707f 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -80,6 +80,8 @@ struct hda_gen_spec { char stream_name_analog[32]; /* analog PCM stream */ const struct hda_pcm_stream *stream_analog_playback; const struct hda_pcm_stream *stream_analog_capture; + + char stream_name_alt_analog[32]; /* alternative analog PCM stream */ const struct hda_pcm_stream *stream_analog_alt_playback; const struct hda_pcm_stream *stream_analog_alt_capture;
participants (2)
-
Raymond Yau
-
Takashi Iwai