diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-17 10:18:11 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-17 10:18:11 -0500 |
commit | 247d85ee068610c50d66ee0cd3130e02c69f5f2e (patch) | |
tree | c331245f3b6bb9382a1674fc1e46f96e78ef0c11 /sound/pci/hda/hda_generic.c | |
parent | ac2e87366c18d49c6dc12e89ae4f4512f126eeb4 (diff) |
ALSA: hda - Improve naming rule for primary output
When the volume or mute control of the primary output is shared with
other (headphone or speaker) outputs, we shouldn't name it as a
specific output type but rather name it with the channel name or a
generic name like "PCM".
Also, this check should be performed individually for the volume and
the mute controls because some codecs may have shared volumes but
separate mute controls.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r-- | sound/pci/hda/hda_generic.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index f946714c7d3c..ef4c04adbc21 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -825,19 +825,27 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx, | |||
825 | return add_sw_ctl(codec, pfx, cidx, chs, path); | 825 | return add_sw_ctl(codec, pfx, cidx, chs, path); |
826 | } | 826 | } |
827 | 827 | ||
828 | /* any ctl assigned to the path with the given index? */ | ||
829 | static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) | ||
830 | { | ||
831 | struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx); | ||
832 | return path && path->ctls[ctl_type]; | ||
833 | } | ||
834 | |||
828 | static const char * const channel_name[4] = { | 835 | static const char * const channel_name[4] = { |
829 | "Front", "Surround", "CLFE", "Side" | 836 | "Front", "Surround", "CLFE", "Side" |
830 | }; | 837 | }; |
831 | 838 | ||
832 | /* give some appropriate ctl name prefix for the given line out channel */ | 839 | /* give some appropriate ctl name prefix for the given line out channel */ |
833 | static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch, | 840 | static const char *get_line_out_pfx(struct hda_codec *codec, int ch, |
834 | bool can_be_master, int *index) | 841 | int *index, int ctl_type) |
835 | { | 842 | { |
843 | struct hda_gen_spec *spec = codec->spec; | ||
836 | struct auto_pin_cfg *cfg = &spec->autocfg; | 844 | struct auto_pin_cfg *cfg = &spec->autocfg; |
837 | 845 | ||
838 | *index = 0; | 846 | *index = 0; |
839 | if (cfg->line_outs == 1 && !spec->multi_ios && | 847 | if (cfg->line_outs == 1 && !spec->multi_ios && |
840 | !cfg->hp_outs && !cfg->speaker_outs && can_be_master) | 848 | !cfg->hp_outs && !cfg->speaker_outs) |
841 | return spec->vmaster_mute.hook ? "PCM" : "Master"; | 849 | return spec->vmaster_mute.hook ? "PCM" : "Master"; |
842 | 850 | ||
843 | /* if there is really a single DAC used in the whole output paths, | 851 | /* if there is really a single DAC used in the whole output paths, |
@@ -847,24 +855,41 @@ static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch, | |||
847 | !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) | 855 | !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) |
848 | return spec->vmaster_mute.hook ? "PCM" : "Master"; | 856 | return spec->vmaster_mute.hook ? "PCM" : "Master"; |
849 | 857 | ||
858 | /* multi-io channels */ | ||
859 | if (ch >= cfg->line_outs) | ||
860 | return channel_name[ch]; | ||
861 | |||
850 | switch (cfg->line_out_type) { | 862 | switch (cfg->line_out_type) { |
851 | case AUTO_PIN_SPEAKER_OUT: | 863 | case AUTO_PIN_SPEAKER_OUT: |
864 | /* if the primary channel vol/mute is shared with HP volume, | ||
865 | * don't name it as Speaker | ||
866 | */ | ||
867 | if (!ch && cfg->hp_outs && | ||
868 | !path_has_mixer(codec, spec->hp_paths[0], ctl_type)) | ||
869 | break; | ||
852 | if (cfg->line_outs == 1) | 870 | if (cfg->line_outs == 1) |
853 | return "Speaker"; | 871 | return "Speaker"; |
854 | if (cfg->line_outs == 2) | 872 | if (cfg->line_outs == 2) |
855 | return ch ? "Bass Speaker" : "Speaker"; | 873 | return ch ? "Bass Speaker" : "Speaker"; |
856 | break; | 874 | break; |
857 | case AUTO_PIN_HP_OUT: | 875 | case AUTO_PIN_HP_OUT: |
876 | /* if the primary channel vol/mute is shared with spk volume, | ||
877 | * don't name it as Headphone | ||
878 | */ | ||
879 | if (!ch && cfg->speaker_outs && | ||
880 | !path_has_mixer(codec, spec->speaker_paths[0], ctl_type)) | ||
881 | break; | ||
858 | /* for multi-io case, only the primary out */ | 882 | /* for multi-io case, only the primary out */ |
859 | if (ch && spec->multi_ios) | 883 | if (ch && spec->multi_ios) |
860 | break; | 884 | break; |
861 | *index = ch; | 885 | *index = ch; |
862 | return "Headphone"; | 886 | return "Headphone"; |
863 | default: | ||
864 | if (cfg->line_outs == 1 && !spec->multi_ios) | ||
865 | return "PCM"; | ||
866 | break; | ||
867 | } | 887 | } |
888 | |||
889 | /* for a single channel output, we don't have to name the channel */ | ||
890 | if (cfg->line_outs == 1 && !spec->multi_ios) | ||
891 | return "PCM"; | ||
892 | |||
868 | if (ch >= ARRAY_SIZE(channel_name)) { | 893 | if (ch >= ARRAY_SIZE(channel_name)) { |
869 | snd_BUG(); | 894 | snd_BUG(); |
870 | return "PCM"; | 895 | return "PCM"; |
@@ -1626,16 +1651,11 @@ static int create_multi_out_ctls(struct hda_codec *codec, | |||
1626 | int index; | 1651 | int index; |
1627 | struct nid_path *path; | 1652 | struct nid_path *path; |
1628 | 1653 | ||
1629 | if (i >= cfg->line_outs) { | ||
1630 | index = 0; | ||
1631 | name = channel_name[i]; | ||
1632 | } else { | ||
1633 | name = get_line_out_pfx(spec, i, true, &index); | ||
1634 | } | ||
1635 | |||
1636 | path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]); | 1654 | path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]); |
1637 | if (!path) | 1655 | if (!path) |
1638 | continue; | 1656 | continue; |
1657 | |||
1658 | name = get_line_out_pfx(codec, i, &index, NID_PATH_VOL_CTL); | ||
1639 | if (!name || !strcmp(name, "CLFE")) { | 1659 | if (!name || !strcmp(name, "CLFE")) { |
1640 | /* Center/LFE */ | 1660 | /* Center/LFE */ |
1641 | err = add_vol_ctl(codec, "Center", 0, 1, path); | 1661 | err = add_vol_ctl(codec, "Center", 0, 1, path); |
@@ -1644,6 +1664,14 @@ static int create_multi_out_ctls(struct hda_codec *codec, | |||
1644 | err = add_vol_ctl(codec, "LFE", 0, 2, path); | 1664 | err = add_vol_ctl(codec, "LFE", 0, 2, path); |
1645 | if (err < 0) | 1665 | if (err < 0) |
1646 | return err; | 1666 | return err; |
1667 | } else { | ||
1668 | err = add_stereo_vol(codec, name, index, path); | ||
1669 | if (err < 0) | ||
1670 | return err; | ||
1671 | } | ||
1672 | |||
1673 | name = get_line_out_pfx(codec, i, &index, NID_PATH_MUTE_CTL); | ||
1674 | if (!name || !strcmp(name, "CLFE")) { | ||
1647 | err = add_sw_ctl(codec, "Center", 0, 1, path); | 1675 | err = add_sw_ctl(codec, "Center", 0, 1, path); |
1648 | if (err < 0) | 1676 | if (err < 0) |
1649 | return err; | 1677 | return err; |
@@ -1651,9 +1679,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, | |||
1651 | if (err < 0) | 1679 | if (err < 0) |
1652 | return err; | 1680 | return err; |
1653 | } else { | 1681 | } else { |
1654 | err = add_stereo_vol(codec, name, index, path); | ||
1655 | if (err < 0) | ||
1656 | return err; | ||
1657 | err = add_stereo_sw(codec, name, index, path); | 1682 | err = add_stereo_sw(codec, name, index, path); |
1658 | if (err < 0) | 1683 | if (err < 0) |
1659 | return err; | 1684 | return err; |