diff options
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 77 |
1 files changed, 20 insertions, 57 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 0de21193a2b0..bf14a0a0ce1c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "hda_codec.h" | 31 | #include "hda_codec.h" |
32 | #include "hda_local.h" | 32 | #include "hda_local.h" |
33 | #include "hda_beep.h" | 33 | #include "hda_beep.h" |
34 | #include "hda_jack.h" | ||
34 | 35 | ||
35 | #define CXT_PIN_DIR_IN 0x00 | 36 | #define CXT_PIN_DIR_IN 0x00 |
36 | #define CXT_PIN_DIR_OUT 0x01 | 37 | #define CXT_PIN_DIR_OUT 0x01 |
@@ -415,40 +416,6 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
415 | &spec->cur_mux[adc_idx]); | 416 | &spec->cur_mux[adc_idx]); |
416 | } | 417 | } |
417 | 418 | ||
418 | static int conexant_init_jacks(struct hda_codec *codec) | ||
419 | { | ||
420 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
421 | struct conexant_spec *spec = codec->spec; | ||
422 | int i; | ||
423 | |||
424 | for (i = 0; i < spec->num_init_verbs; i++) { | ||
425 | const struct hda_verb *hv; | ||
426 | |||
427 | hv = spec->init_verbs[i]; | ||
428 | while (hv->nid) { | ||
429 | int err = 0; | ||
430 | switch (hv->param ^ AC_USRSP_EN) { | ||
431 | case CONEXANT_HP_EVENT: | ||
432 | err = snd_hda_input_jack_add(codec, hv->nid, | ||
433 | SND_JACK_HEADPHONE, NULL); | ||
434 | snd_hda_input_jack_report(codec, hv->nid); | ||
435 | break; | ||
436 | case CXT5051_PORTC_EVENT: | ||
437 | case CONEXANT_MIC_EVENT: | ||
438 | err = snd_hda_input_jack_add(codec, hv->nid, | ||
439 | SND_JACK_MICROPHONE, NULL); | ||
440 | snd_hda_input_jack_report(codec, hv->nid); | ||
441 | break; | ||
442 | } | ||
443 | if (err < 0) | ||
444 | return err; | ||
445 | ++hv; | ||
446 | } | ||
447 | } | ||
448 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg, | 419 | static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg, |
453 | unsigned int power_state) | 420 | unsigned int power_state) |
454 | { | 421 | { |
@@ -474,7 +441,6 @@ static int conexant_init(struct hda_codec *codec) | |||
474 | 441 | ||
475 | static void conexant_free(struct hda_codec *codec) | 442 | static void conexant_free(struct hda_codec *codec) |
476 | { | 443 | { |
477 | snd_hda_input_jack_free(codec); | ||
478 | snd_hda_detach_beep_device(codec); | 444 | snd_hda_detach_beep_device(codec); |
479 | kfree(codec->spec); | 445 | kfree(codec->spec); |
480 | } | 446 | } |
@@ -1750,7 +1716,6 @@ static void cxt5051_hp_automute(struct hda_codec *codec) | |||
1750 | static void cxt5051_hp_unsol_event(struct hda_codec *codec, | 1716 | static void cxt5051_hp_unsol_event(struct hda_codec *codec, |
1751 | unsigned int res) | 1717 | unsigned int res) |
1752 | { | 1718 | { |
1753 | int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; | ||
1754 | switch (res >> 26) { | 1719 | switch (res >> 26) { |
1755 | case CONEXANT_HP_EVENT: | 1720 | case CONEXANT_HP_EVENT: |
1756 | cxt5051_hp_automute(codec); | 1721 | cxt5051_hp_automute(codec); |
@@ -1762,7 +1727,6 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, | |||
1762 | cxt5051_portc_automic(codec); | 1727 | cxt5051_portc_automic(codec); |
1763 | break; | 1728 | break; |
1764 | } | 1729 | } |
1765 | snd_hda_input_jack_report(codec, nid); | ||
1766 | } | 1730 | } |
1767 | 1731 | ||
1768 | static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { | 1732 | static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { |
@@ -1901,8 +1865,6 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, | |||
1901 | snd_hda_codec_write(codec, nid, 0, | 1865 | snd_hda_codec_write(codec, nid, 0, |
1902 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1866 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1903 | AC_USRSP_EN | event); | 1867 | AC_USRSP_EN | event); |
1904 | snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); | ||
1905 | snd_hda_input_jack_report(codec, nid); | ||
1906 | } | 1868 | } |
1907 | 1869 | ||
1908 | static const struct hda_verb cxt5051_ideapad_init_verbs[] = { | 1870 | static const struct hda_verb cxt5051_ideapad_init_verbs[] = { |
@@ -1918,7 +1880,6 @@ static int cxt5051_init(struct hda_codec *codec) | |||
1918 | struct conexant_spec *spec = codec->spec; | 1880 | struct conexant_spec *spec = codec->spec; |
1919 | 1881 | ||
1920 | conexant_init(codec); | 1882 | conexant_init(codec); |
1921 | conexant_init_jacks(codec); | ||
1922 | 1883 | ||
1923 | if (spec->auto_mic & AUTO_MIC_PORTB) | 1884 | if (spec->auto_mic & AUTO_MIC_PORTB) |
1924 | cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT); | 1885 | cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT); |
@@ -3450,7 +3411,6 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | |||
3450 | hda_nid_t nid = pins[i]; | 3411 | hda_nid_t nid = pins[i]; |
3451 | if (!nid || !is_jack_detectable(codec, nid)) | 3412 | if (!nid || !is_jack_detectable(codec, nid)) |
3452 | break; | 3413 | break; |
3453 | snd_hda_input_jack_report(codec, nid); | ||
3454 | present |= snd_hda_jack_detect(codec, nid); | 3414 | present |= snd_hda_jack_detect(codec, nid); |
3455 | } | 3415 | } |
3456 | return present; | 3416 | return present; |
@@ -3755,8 +3715,7 @@ static void cx_auto_automic(struct hda_codec *codec) | |||
3755 | 3715 | ||
3756 | static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | 3716 | static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) |
3757 | { | 3717 | { |
3758 | int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; | 3718 | switch (snd_hda_jack_get_action(codec, res >> 26)) { |
3759 | switch (res >> 26) { | ||
3760 | case CONEXANT_HP_EVENT: | 3719 | case CONEXANT_HP_EVENT: |
3761 | cx_auto_hp_automute(codec); | 3720 | cx_auto_hp_automute(codec); |
3762 | break; | 3721 | break; |
@@ -3765,9 +3724,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | |||
3765 | break; | 3724 | break; |
3766 | case CONEXANT_MIC_EVENT: | 3725 | case CONEXANT_MIC_EVENT: |
3767 | cx_auto_automic(codec); | 3726 | cx_auto_automic(codec); |
3768 | snd_hda_input_jack_report(codec, nid); | ||
3769 | break; | 3727 | break; |
3770 | } | 3728 | } |
3729 | snd_hda_jack_report_sync(codec); | ||
3771 | } | 3730 | } |
3772 | 3731 | ||
3773 | /* check whether the pin config is suitable for auto-mic switching; | 3732 | /* check whether the pin config is suitable for auto-mic switching; |
@@ -3979,13 +3938,11 @@ static void mute_outputs(struct hda_codec *codec, int num_nids, | |||
3979 | } | 3938 | } |
3980 | 3939 | ||
3981 | static void enable_unsol_pins(struct hda_codec *codec, int num_pins, | 3940 | static void enable_unsol_pins(struct hda_codec *codec, int num_pins, |
3982 | hda_nid_t *pins, unsigned int tag) | 3941 | hda_nid_t *pins, unsigned int action) |
3983 | { | 3942 | { |
3984 | int i; | 3943 | int i; |
3985 | for (i = 0; i < num_pins; i++) | 3944 | for (i = 0; i < num_pins; i++) |
3986 | snd_hda_codec_write(codec, pins[i], 0, | 3945 | snd_hda_jack_detect_enable(codec, pins[i], action); |
3987 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
3988 | AC_USRSP_EN | tag); | ||
3989 | } | 3946 | } |
3990 | 3947 | ||
3991 | static void cx_auto_init_output(struct hda_codec *codec) | 3948 | static void cx_auto_init_output(struct hda_codec *codec) |
@@ -4060,16 +4017,14 @@ static void cx_auto_init_input(struct hda_codec *codec) | |||
4060 | 4017 | ||
4061 | if (spec->auto_mic) { | 4018 | if (spec->auto_mic) { |
4062 | if (spec->auto_mic_ext >= 0) { | 4019 | if (spec->auto_mic_ext >= 0) { |
4063 | snd_hda_codec_write(codec, | 4020 | snd_hda_jack_detect_enable(codec, |
4064 | cfg->inputs[spec->auto_mic_ext].pin, 0, | 4021 | cfg->inputs[spec->auto_mic_ext].pin, |
4065 | AC_VERB_SET_UNSOLICITED_ENABLE, | 4022 | CONEXANT_MIC_EVENT); |
4066 | AC_USRSP_EN | CONEXANT_MIC_EVENT); | ||
4067 | } | 4023 | } |
4068 | if (spec->auto_mic_dock >= 0) { | 4024 | if (spec->auto_mic_dock >= 0) { |
4069 | snd_hda_codec_write(codec, | 4025 | snd_hda_jack_detect_enable(codec, |
4070 | cfg->inputs[spec->auto_mic_dock].pin, 0, | 4026 | cfg->inputs[spec->auto_mic_dock].pin, |
4071 | AC_VERB_SET_UNSOLICITED_ENABLE, | 4027 | CONEXANT_MIC_EVENT); |
4072 | AC_USRSP_EN | CONEXANT_MIC_EVENT); | ||
4073 | } | 4028 | } |
4074 | cx_auto_automic(codec); | 4029 | cx_auto_automic(codec); |
4075 | } else { | 4030 | } else { |
@@ -4097,6 +4052,7 @@ static int cx_auto_init(struct hda_codec *codec) | |||
4097 | cx_auto_init_output(codec); | 4052 | cx_auto_init_output(codec); |
4098 | cx_auto_init_input(codec); | 4053 | cx_auto_init_input(codec); |
4099 | cx_auto_init_digital(codec); | 4054 | cx_auto_init_digital(codec); |
4055 | snd_hda_jack_report_sync(codec); | ||
4100 | return 0; | 4056 | return 0; |
4101 | } | 4057 | } |
4102 | 4058 | ||
@@ -4326,6 +4282,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) | |||
4326 | 4282 | ||
4327 | static int cx_auto_build_controls(struct hda_codec *codec) | 4283 | static int cx_auto_build_controls(struct hda_codec *codec) |
4328 | { | 4284 | { |
4285 | struct conexant_spec *spec = codec->spec; | ||
4329 | int err; | 4286 | int err; |
4330 | 4287 | ||
4331 | err = cx_auto_build_output_controls(codec); | 4288 | err = cx_auto_build_output_controls(codec); |
@@ -4334,7 +4291,13 @@ static int cx_auto_build_controls(struct hda_codec *codec) | |||
4334 | err = cx_auto_build_input_controls(codec); | 4291 | err = cx_auto_build_input_controls(codec); |
4335 | if (err < 0) | 4292 | if (err < 0) |
4336 | return err; | 4293 | return err; |
4337 | return conexant_build_controls(codec); | 4294 | err = conexant_build_controls(codec); |
4295 | if (err < 0) | ||
4296 | return err; | ||
4297 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
4298 | if (err < 0) | ||
4299 | return err; | ||
4300 | return 0; | ||
4338 | } | 4301 | } |
4339 | 4302 | ||
4340 | static int cx_auto_search_adcs(struct hda_codec *codec) | 4303 | static int cx_auto_search_adcs(struct hda_codec *codec) |