aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c59
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
1848static 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
1848static int indep_hp_put(struct snd_kcontrol *kcontrol, 1852static 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 = {
1884static int create_indep_hp_ctls(struct hda_codec *codec) 1908static 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
2028static void update_aamix_paths(struct hda_codec *codec, bool do_mix, 2057static 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