diff options
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r-- | sound/pci/hda/hda_generic.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index e26e8d3430f2..6d1e843c6e8d 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, | |||
1845 | return 0; | 1845 | return 0; |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | static void update_aamix_paths(struct hda_codec *codec, bool do_mix, | ||
1849 | int nomix_path_idx, int mix_path_idx, | ||
1850 | int out_type); | ||
1851 | |||
1848 | static int indep_hp_put(struct snd_kcontrol *kcontrol, | 1852 | static int indep_hp_put(struct snd_kcontrol *kcontrol, |
1849 | struct snd_ctl_elem_value *ucontrol) | 1853 | struct snd_ctl_elem_value *ucontrol) |
1850 | { | 1854 | { |
@@ -1860,11 +1864,31 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, | |||
1860 | } | 1864 | } |
1861 | 1865 | ||
1862 | if (spec->indep_hp_enabled != select) { | 1866 | if (spec->indep_hp_enabled != select) { |
1867 | hda_nid_t *dacp; | ||
1868 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
1869 | dacp = &spec->private_dac_nids[0]; | ||
1870 | else | ||
1871 | dacp = &spec->multiout.hp_out_nid[0]; | ||
1872 | |||
1873 | /* update HP aamix paths in case it conflicts with indep HP */ | ||
1874 | if (spec->have_aamix_ctl) { | ||
1875 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
1876 | update_aamix_paths(codec, spec->aamix_mode, | ||
1877 | spec->out_paths[0], | ||
1878 | spec->aamix_out_paths[0], | ||
1879 | spec->autocfg.line_out_type); | ||
1880 | else | ||
1881 | update_aamix_paths(codec, spec->aamix_mode, | ||
1882 | spec->hp_paths[0], | ||
1883 | spec->aamix_out_paths[1], | ||
1884 | AUTO_PIN_HP_OUT); | ||
1885 | } | ||
1886 | |||
1863 | spec->indep_hp_enabled = select; | 1887 | spec->indep_hp_enabled = select; |
1864 | if (spec->indep_hp_enabled) | 1888 | if (spec->indep_hp_enabled) |
1865 | spec->multiout.hp_out_nid[0] = 0; | 1889 | *dacp = 0; |
1866 | else | 1890 | else |
1867 | spec->multiout.hp_out_nid[0] = spec->alt_dac_nid; | 1891 | *dacp = spec->alt_dac_nid; |
1868 | ret = 1; | 1892 | ret = 1; |
1869 | } | 1893 | } |
1870 | unlock: | 1894 | unlock: |
@@ -1884,16 +1908,21 @@ static const struct snd_kcontrol_new indep_hp_ctl = { | |||
1884 | static int create_indep_hp_ctls(struct hda_codec *codec) | 1908 | static int create_indep_hp_ctls(struct hda_codec *codec) |
1885 | { | 1909 | { |
1886 | struct hda_gen_spec *spec = codec->spec; | 1910 | struct hda_gen_spec *spec = codec->spec; |
1911 | hda_nid_t dac; | ||
1887 | 1912 | ||
1888 | if (!spec->indep_hp) | 1913 | if (!spec->indep_hp) |
1889 | return 0; | 1914 | return 0; |
1890 | if (!spec->multiout.hp_out_nid[0]) { | 1915 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) |
1916 | dac = spec->multiout.dac_nids[0]; | ||
1917 | else | ||
1918 | dac = spec->multiout.hp_out_nid[0]; | ||
1919 | if (!dac) { | ||
1891 | spec->indep_hp = 0; | 1920 | spec->indep_hp = 0; |
1892 | return 0; | 1921 | return 0; |
1893 | } | 1922 | } |
1894 | 1923 | ||
1895 | spec->indep_hp_enabled = false; | 1924 | spec->indep_hp_enabled = false; |
1896 | spec->alt_dac_nid = spec->multiout.hp_out_nid[0]; | 1925 | spec->alt_dac_nid = dac; |
1897 | if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl)) | 1926 | if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl)) |
1898 | return -ENOMEM; | 1927 | return -ENOMEM; |
1899 | return 0; | 1928 | return 0; |
@@ -2026,14 +2055,24 @@ static int loopback_mixing_get(struct snd_kcontrol *kcontrol, | |||
2026 | } | 2055 | } |
2027 | 2056 | ||
2028 | static void update_aamix_paths(struct hda_codec *codec, bool do_mix, | 2057 | static void update_aamix_paths(struct hda_codec *codec, bool do_mix, |
2029 | int nomix_path_idx, int mix_path_idx) | 2058 | int nomix_path_idx, int mix_path_idx, |
2059 | int out_type) | ||
2030 | { | 2060 | { |
2061 | struct hda_gen_spec *spec = codec->spec; | ||
2031 | struct nid_path *nomix_path, *mix_path; | 2062 | struct nid_path *nomix_path, *mix_path; |
2032 | 2063 | ||
2033 | nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx); | 2064 | nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx); |
2034 | mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx); | 2065 | mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx); |
2035 | if (!nomix_path || !mix_path) | 2066 | if (!nomix_path || !mix_path) |
2036 | return; | 2067 | return; |
2068 | |||
2069 | /* if HP aamix path is driven from a different DAC and the | ||
2070 | * independent HP mode is ON, can't turn on aamix path | ||
2071 | */ | ||
2072 | if (out_type == AUTO_PIN_HP_OUT && spec->indep_hp_enabled && | ||
2073 | mix_path->path[0] != spec->alt_dac_nid) | ||
2074 | do_mix = false; | ||
2075 | |||
2037 | if (do_mix) { | 2076 | if (do_mix) { |
2038 | snd_hda_activate_path(codec, nomix_path, false, true); | 2077 | snd_hda_activate_path(codec, nomix_path, false, true); |
2039 | snd_hda_activate_path(codec, mix_path, true, true); | 2078 | snd_hda_activate_path(codec, mix_path, true, true); |
@@ -2054,11 +2093,14 @@ static int loopback_mixing_put(struct snd_kcontrol *kcontrol, | |||
2054 | return 0; | 2093 | return 0; |
2055 | spec->aamix_mode = val; | 2094 | spec->aamix_mode = val; |
2056 | update_aamix_paths(codec, val, spec->out_paths[0], | 2095 | update_aamix_paths(codec, val, spec->out_paths[0], |
2057 | spec->aamix_out_paths[0]); | 2096 | spec->aamix_out_paths[0], |
2097 | spec->autocfg.line_out_type); | ||
2058 | update_aamix_paths(codec, val, spec->hp_paths[0], | 2098 | update_aamix_paths(codec, val, spec->hp_paths[0], |
2059 | spec->aamix_out_paths[1]); | 2099 | spec->aamix_out_paths[1], |
2100 | AUTO_PIN_HP_OUT); | ||
2060 | update_aamix_paths(codec, val, spec->speaker_paths[0], | 2101 | update_aamix_paths(codec, val, spec->speaker_paths[0], |
2061 | spec->aamix_out_paths[2]); | 2102 | spec->aamix_out_paths[2], |
2103 | AUTO_PIN_SPEAKER_OUT); | ||
2062 | return 1; | 2104 | return 1; |
2063 | } | 2105 | } |
2064 | 2106 | ||
@@ -2081,6 +2123,7 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec) | |||
2081 | return 0; | 2123 | return 0; |
2082 | if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) | 2124 | if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) |
2083 | return -ENOMEM; | 2125 | return -ENOMEM; |
2126 | spec->have_aamix_ctl = 1; | ||
2084 | return 0; | 2127 | return 0; |
2085 | } | 2128 | } |
2086 | 2129 | ||