diff options
Diffstat (limited to 'sound/pci/hda/patch_cirrus.c')
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 70a7abda7e22..acfb64534bf0 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include "hda_codec.h" | 27 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | #include "hda_jack.h" | ||
29 | #include <sound/tlv.h> | 30 | #include <sound/tlv.h> |
30 | 31 | ||
31 | /* | 32 | /* |
@@ -721,8 +722,9 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol, | |||
721 | if (uinfo->value.enumerated.item >= spec->num_inputs) | 722 | if (uinfo->value.enumerated.item >= spec->num_inputs) |
722 | uinfo->value.enumerated.item = spec->num_inputs - 1; | 723 | uinfo->value.enumerated.item = spec->num_inputs - 1; |
723 | idx = spec->input_idx[uinfo->value.enumerated.item]; | 724 | idx = spec->input_idx[uinfo->value.enumerated.item]; |
724 | strcpy(uinfo->value.enumerated.name, | 725 | snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg, |
725 | hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1)); | 726 | uinfo->value.enumerated.name, |
727 | sizeof(uinfo->value.enumerated.name), NULL); | ||
726 | return 0; | 728 | return 0; |
727 | } | 729 | } |
728 | 730 | ||
@@ -1027,9 +1029,7 @@ static void init_output(struct hda_codec *codec) | |||
1027 | if (!cfg->speaker_outs) | 1029 | if (!cfg->speaker_outs) |
1028 | continue; | 1030 | continue; |
1029 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 1031 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { |
1030 | snd_hda_codec_write(codec, nid, 0, | 1032 | snd_hda_jack_detect_enable(codec, nid, HP_EVENT); |
1031 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1032 | AC_USRSP_EN | HP_EVENT); | ||
1033 | spec->hp_detect = 1; | 1033 | spec->hp_detect = 1; |
1034 | } | 1034 | } |
1035 | } | 1035 | } |
@@ -1070,9 +1070,7 @@ static void init_input(struct hda_codec *codec) | |||
1070 | AC_VERB_SET_AMP_GAIN_MUTE, | 1070 | AC_VERB_SET_AMP_GAIN_MUTE, |
1071 | AMP_IN_MUTE(spec->adc_idx[i])); | 1071 | AMP_IN_MUTE(spec->adc_idx[i])); |
1072 | if (spec->mic_detect && spec->automic_idx == i) | 1072 | if (spec->mic_detect && spec->automic_idx == i) |
1073 | snd_hda_codec_write(codec, pin, 0, | 1073 | snd_hda_jack_detect_enable(codec, pin, MIC_EVENT); |
1074 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1075 | AC_USRSP_EN | MIC_EVENT); | ||
1076 | } | 1074 | } |
1077 | /* specific to CS421x */ | 1075 | /* specific to CS421x */ |
1078 | if (spec->vendor_nid == CS421X_VENDOR_NID) { | 1076 | if (spec->vendor_nid == CS421X_VENDOR_NID) { |
@@ -1200,11 +1198,14 @@ static int cs_init(struct hda_codec *codec) | |||
1200 | init_output(codec); | 1198 | init_output(codec); |
1201 | init_input(codec); | 1199 | init_input(codec); |
1202 | init_digital(codec); | 1200 | init_digital(codec); |
1201 | snd_hda_jack_report_sync(codec); | ||
1202 | |||
1203 | return 0; | 1203 | return 0; |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | static int cs_build_controls(struct hda_codec *codec) | 1206 | static int cs_build_controls(struct hda_codec *codec) |
1207 | { | 1207 | { |
1208 | struct cs_spec *spec = codec->spec; | ||
1208 | int err; | 1209 | int err; |
1209 | 1210 | ||
1210 | err = build_output(codec); | 1211 | err = build_output(codec); |
@@ -1219,7 +1220,15 @@ static int cs_build_controls(struct hda_codec *codec) | |||
1219 | err = build_digital_input(codec); | 1220 | err = build_digital_input(codec); |
1220 | if (err < 0) | 1221 | if (err < 0) |
1221 | return err; | 1222 | return err; |
1222 | return cs_init(codec); | 1223 | err = cs_init(codec); |
1224 | if (err < 0) | ||
1225 | return err; | ||
1226 | |||
1227 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1228 | if (err < 0) | ||
1229 | return err; | ||
1230 | |||
1231 | return 0; | ||
1223 | } | 1232 | } |
1224 | 1233 | ||
1225 | static void cs_free(struct hda_codec *codec) | 1234 | static void cs_free(struct hda_codec *codec) |
@@ -1232,7 +1241,7 @@ static void cs_free(struct hda_codec *codec) | |||
1232 | 1241 | ||
1233 | static void cs_unsol_event(struct hda_codec *codec, unsigned int res) | 1242 | static void cs_unsol_event(struct hda_codec *codec, unsigned int res) |
1234 | { | 1243 | { |
1235 | switch ((res >> 26) & 0x7f) { | 1244 | switch (snd_hda_jack_get_action(codec, res >> 26)) { |
1236 | case HP_EVENT: | 1245 | case HP_EVENT: |
1237 | cs_automute(codec); | 1246 | cs_automute(codec); |
1238 | break; | 1247 | break; |
@@ -1240,6 +1249,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1240 | cs_automic(codec); | 1249 | cs_automic(codec); |
1241 | break; | 1250 | break; |
1242 | } | 1251 | } |
1252 | snd_hda_jack_report_sync(codec); | ||
1243 | } | 1253 | } |
1244 | 1254 | ||
1245 | static const struct hda_codec_ops cs_patch_ops = { | 1255 | static const struct hda_codec_ops cs_patch_ops = { |
@@ -1602,10 +1612,7 @@ static void init_cs421x_digital(struct hda_codec *codec) | |||
1602 | if (!cfg->speaker_outs) | 1612 | if (!cfg->speaker_outs) |
1603 | continue; | 1613 | continue; |
1604 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 1614 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { |
1605 | 1615 | snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT); | |
1606 | snd_hda_codec_write(codec, nid, 0, | ||
1607 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1608 | AC_USRSP_EN | SPDIF_EVENT); | ||
1609 | spec->spdif_detect = 1; | 1616 | spec->spdif_detect = 1; |
1610 | } | 1617 | } |
1611 | } | 1618 | } |
@@ -1632,6 +1639,7 @@ static int cs421x_init(struct hda_codec *codec) | |||
1632 | init_output(codec); | 1639 | init_output(codec); |
1633 | init_input(codec); | 1640 | init_input(codec); |
1634 | init_cs421x_digital(codec); | 1641 | init_cs421x_digital(codec); |
1642 | snd_hda_jack_report_sync(codec); | ||
1635 | 1643 | ||
1636 | return 0; | 1644 | return 0; |
1637 | } | 1645 | } |
@@ -1807,6 +1815,7 @@ static int build_cs421x_output(struct hda_codec *codec) | |||
1807 | 1815 | ||
1808 | static int cs421x_build_controls(struct hda_codec *codec) | 1816 | static int cs421x_build_controls(struct hda_codec *codec) |
1809 | { | 1817 | { |
1818 | struct cs_spec *spec = codec->spec; | ||
1810 | int err; | 1819 | int err; |
1811 | 1820 | ||
1812 | err = build_cs421x_output(codec); | 1821 | err = build_cs421x_output(codec); |
@@ -1818,12 +1827,20 @@ static int cs421x_build_controls(struct hda_codec *codec) | |||
1818 | err = build_digital_output(codec); | 1827 | err = build_digital_output(codec); |
1819 | if (err < 0) | 1828 | if (err < 0) |
1820 | return err; | 1829 | return err; |
1821 | return cs421x_init(codec); | 1830 | err = cs421x_init(codec); |
1831 | if (err < 0) | ||
1832 | return err; | ||
1833 | |||
1834 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1835 | if (err < 0) | ||
1836 | return err; | ||
1837 | |||
1838 | return 0; | ||
1822 | } | 1839 | } |
1823 | 1840 | ||
1824 | static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) | 1841 | static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) |
1825 | { | 1842 | { |
1826 | switch ((res >> 26) & 0x3f) { | 1843 | switch (snd_hda_jack_get_action(codec, res >> 26)) { |
1827 | case HP_EVENT: | 1844 | case HP_EVENT: |
1828 | case SPDIF_EVENT: | 1845 | case SPDIF_EVENT: |
1829 | cs_automute(codec); | 1846 | cs_automute(codec); |
@@ -1833,6 +1850,7 @@ static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1833 | cs_automic(codec); | 1850 | cs_automic(codec); |
1834 | break; | 1851 | break; |
1835 | } | 1852 | } |
1853 | snd_hda_jack_report_sync(codec); | ||
1836 | } | 1854 | } |
1837 | 1855 | ||
1838 | static int parse_cs421x_input(struct hda_codec *codec) | 1856 | static int parse_cs421x_input(struct hda_codec *codec) |