Loading sound/pci/hda/hda_codec.c +105 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sound/asoundef.h> #include <sound/tlv.h> #include <sound/initval.h> #include <sound/jack.h> #include "hda_local.h" #include "hda_beep.h" #include <sound/hda_hwdep.h> Loading Loading @@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) } EXPORT_SYMBOL_HDA(snd_print_pcm_bits); #ifdef CONFIG_SND_HDA_INPUT_JACK /* * Input-jack notification support */ struct hda_jack_item { hda_nid_t nid; int type; struct snd_jack *jack; }; static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, int type) { switch (type) { case SND_JACK_HEADPHONE: return "Headphone"; case SND_JACK_MICROPHONE: return "Mic"; case SND_JACK_LINEOUT: return "Line-out"; case SND_JACK_HEADSET: return "Headset"; default: return "Misc"; } } static void hda_free_jack_priv(struct snd_jack *jack) { struct hda_jack_item *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name) { struct hda_jack_item *jack; int err; snd_array_init(&codec->jacks, sizeof(*jack), 32); jack = snd_array_new(&codec->jacks); if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; if (!name) name = get_jack_default_name(codec, nid, type); err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) { jack->nid = 0; return err; } jack->jack->private_data = jack; jack->jack->private_free = hda_free_jack_priv; return 0; } EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_item *jacks = codec->jacks.list; int i; if (!jacks) return; for (i = 0; i < codec->jacks.used; i++, jacks++) { unsigned int pin_ctl; unsigned int present; int type; if (jacks->nid != nid) continue; present = snd_hda_jack_detect(codec, nid); type = jacks->type; if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); type = (pin_ctl & AC_PINCTL_HP_EN) ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT; } snd_jack_report(jacks->jack, present ? type : 0); } } EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); /* free jack instances manually when clearing/reconfiguring */ void snd_hda_input_jack_free(struct hda_codec *codec) { if (!codec->bus->shutdown && codec->jacks.list) { struct hda_jack_item *jacks = codec->jacks.list; int i; for (i = 0; i < codec->jacks.used; i++, jacks++) { if (jacks->jack) snd_device_free(codec->bus->card, jacks->jack); } } snd_array_free(&codec->jacks); } EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); #endif /* CONFIG_SND_HDA_INPUT_JACK */ MODULE_DESCRIPTION("HDA codec core"); MODULE_LICENSE("GPL"); sound/pci/hda/hda_codec.h +5 −0 Original line number Diff line number Diff line Loading @@ -866,6 +866,11 @@ struct hda_codec { /* codec-specific additional proc output */ void (*proc_widget_hook)(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid); #ifdef CONFIG_SND_HDA_INPUT_JACK /* jack detection */ struct snd_array jacks; #endif }; /* direction */ Loading sound/pci/hda/hda_local.h +24 −0 Original line number Diff line number Diff line Loading @@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec, #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); /* * Input-jack notification support */ #ifdef CONFIG_SND_HDA_INPUT_JACK int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name); void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid); void snd_hda_input_jack_free(struct hda_codec *codec); #else /* CONFIG_SND_HDA_INPUT_JACK */ static inline int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name) { return 0; } static inline void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) { } static inline void snd_hda_input_jack_free(struct hda_codec *codec) { } #endif /* CONFIG_SND_HDA_INPUT_JACK */ #endif /* __SOUND_HDA_LOCAL_H */ sound/pci/hda/patch_conexant.c +14 −110 Original line number Diff line number Diff line Loading @@ -49,14 +49,6 @@ #define AUTO_MIC_PORTB (1 << 1) #define AUTO_MIC_PORTC (1 << 2) struct conexant_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; struct pin_dac_pair { hda_nid_t pin; hda_nid_t dac; Loading Loading @@ -111,9 +103,6 @@ struct conexant_spec { unsigned int spdif_route; /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct hda_input_mux private_imux; Loading Loading @@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } #ifdef CONFIG_SND_HDA_INPUT_JACK static void conexant_free_jack_priv(struct snd_jack *jack) { struct conexant_jack *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; int i, err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = spec->jacks.list; for (i = 0; i < spec->jacks.used; i++, jack++) if (jack->nid == nid) return 0 ; /* already present */ jack = snd_array_new(&spec->jacks); name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) return err; jack->jack->private_data = jack; jack->jack->private_free = conexant_free_jack_priv; return 0; } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct conexant_spec *spec = codec->spec; struct conexant_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_jack_detect(codec, nid); present = (present) ? jacks->type : 0 ; snd_jack_report(jacks->jack, present); } jacks++; } } } static int conexant_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct conexant_spec *spec = codec->spec; int i; Loading @@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec) int err = 0; switch (hv->param ^ AC_USRSP_EN) { case CONEXANT_HP_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_HEADPHONE); conexant_report_jack(codec, hv->nid); err = snd_hda_input_jack_add(codec, hv->nid, SND_JACK_HEADPHONE, NULL); snd_hda_input_jack_report(codec, hv->nid); break; case CXT5051_PORTC_EVENT: case CONEXANT_MIC_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, hv->nid); err = snd_hda_input_jack_add(codec, hv->nid, SND_JACK_MICROPHONE, NULL); snd_hda_input_jack_report(codec, hv->nid); break; } if (err < 0) Loading @@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec) ++hv; } } return 0; } #else static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { } static inline int conexant_init_jacks(struct hda_codec *codec) { #endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } #endif static int conexant_init(struct hda_codec *codec) { Loading @@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct conexant_spec *spec = codec->spec; if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; for (i = 0; i < spec->jacks.used; i++, jacks++) { if (jacks->jack) snd_device_free(codec->bus->card, jacks->jack); } snd_array_free(&spec->jacks); } #endif snd_hda_input_jack_free(codec); snd_hda_detach_beep_device(codec); kfree(codec->spec); } Loading Loading @@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); } static struct snd_kcontrol_new cxt5051_playback_mixers[] = { Loading Loading @@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | event); #ifdef CONFIG_SND_HDA_INPUT_JACK conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, nid); #endif snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); snd_hda_input_jack_report(codec, nid); } static struct hda_verb cxt5051_ideapad_init_verbs[] = { Loading Loading @@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) switch (res >> 26) { case CONEXANT_HP_EVENT: cx_auto_hp_automute(codec); conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); break; case CONEXANT_MIC_EVENT: cx_auto_automic(codec); conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); break; } } Loading sound/pci/hda/patch_realtek.c +12 −82 Original line number Diff line number Diff line Loading @@ -282,12 +282,6 @@ struct alc_mic_route { unsigned char amix_idx; }; struct alc_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; #define MUX_IDX_UNDEF ((unsigned char)-1) struct alc_customize_define { Loading Loading @@ -366,9 +360,6 @@ struct alc_spec { /* PCM information */ struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct alc_customize_define cdefine; Loading Loading @@ -1032,94 +1023,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, alc_fix_pll(codec); } #ifdef CONFIG_SND_HDA_INPUT_JACK static void alc_free_jack_priv(struct snd_jack *jack) { struct alc_jack *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } static int alc_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct alc_spec *spec; struct alc_jack *jack; const char *name; int err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = snd_array_new(&spec->jacks); if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) return err; jack->jack->private_data = jack; jack->jack->private_free = alc_free_jack_priv; return 0; } static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct alc_spec *spec = codec->spec; struct alc_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_jack_detect(codec, nid); present = (present) ? jacks->type : 0; snd_jack_report(jacks->jack, present); } jacks++; } } } static int alc_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct alc_spec *spec = codec->spec; int err; unsigned int hp_nid = spec->autocfg.hp_pins[0]; unsigned int mic_nid = spec->ext_mic.pin; if (hp_nid) { err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); err = snd_hda_input_jack_add(codec, hp_nid, SND_JACK_HEADPHONE, NULL); if (err < 0) return err; alc_report_jack(codec, hp_nid); snd_hda_input_jack_report(codec, hp_nid); } if (mic_nid) { err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); err = snd_hda_input_jack_add(codec, mic_nid, SND_JACK_MICROPHONE, NULL); if (err < 0) return err; alc_report_jack(codec, mic_nid); snd_hda_input_jack_report(codec, mic_nid); } #endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } #else static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) { } static inline int alc_init_jacks(struct hda_codec *codec) { return 0; } #endif static void alc_automute_speaker(struct hda_codec *codec, int pinctl) { Loading @@ -1133,7 +1062,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) nid = spec->autocfg.hp_pins[i]; if (!nid) break; alc_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); spec->jack_present |= snd_hda_jack_detect(codec, nid); } Loading Loading @@ -1240,7 +1169,7 @@ static void alc_mic_automute(struct hda_codec *codec) AC_VERB_SET_CONNECT_SEL, alive->mux_idx); } alc_report_jack(codec, spec->ext_mic.pin); snd_hda_input_jack_report(codec, spec->ext_mic.pin); /* FIXME: analog mixer */ } Loading Loading @@ -4283,6 +4212,7 @@ static void alc_free(struct hda_codec *codec) return; alc_shutup(codec); snd_hda_input_jack_free(codec); alc_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); Loading Loading @@ -14494,7 +14424,7 @@ static void alc269_speaker_automute(struct hda_codec *codec) HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, HDA_AMP_MUTE, bits); alc_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); } /* unsolicited event for HP jack sensing */ Loading Loading
sound/pci/hda/hda_codec.c +105 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sound/asoundef.h> #include <sound/tlv.h> #include <sound/initval.h> #include <sound/jack.h> #include "hda_local.h" #include "hda_beep.h" #include <sound/hda_hwdep.h> Loading Loading @@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) } EXPORT_SYMBOL_HDA(snd_print_pcm_bits); #ifdef CONFIG_SND_HDA_INPUT_JACK /* * Input-jack notification support */ struct hda_jack_item { hda_nid_t nid; int type; struct snd_jack *jack; }; static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, int type) { switch (type) { case SND_JACK_HEADPHONE: return "Headphone"; case SND_JACK_MICROPHONE: return "Mic"; case SND_JACK_LINEOUT: return "Line-out"; case SND_JACK_HEADSET: return "Headset"; default: return "Misc"; } } static void hda_free_jack_priv(struct snd_jack *jack) { struct hda_jack_item *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name) { struct hda_jack_item *jack; int err; snd_array_init(&codec->jacks, sizeof(*jack), 32); jack = snd_array_new(&codec->jacks); if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; if (!name) name = get_jack_default_name(codec, nid, type); err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) { jack->nid = 0; return err; } jack->jack->private_data = jack; jack->jack->private_free = hda_free_jack_priv; return 0; } EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_item *jacks = codec->jacks.list; int i; if (!jacks) return; for (i = 0; i < codec->jacks.used; i++, jacks++) { unsigned int pin_ctl; unsigned int present; int type; if (jacks->nid != nid) continue; present = snd_hda_jack_detect(codec, nid); type = jacks->type; if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); type = (pin_ctl & AC_PINCTL_HP_EN) ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT; } snd_jack_report(jacks->jack, present ? type : 0); } } EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); /* free jack instances manually when clearing/reconfiguring */ void snd_hda_input_jack_free(struct hda_codec *codec) { if (!codec->bus->shutdown && codec->jacks.list) { struct hda_jack_item *jacks = codec->jacks.list; int i; for (i = 0; i < codec->jacks.used; i++, jacks++) { if (jacks->jack) snd_device_free(codec->bus->card, jacks->jack); } } snd_array_free(&codec->jacks); } EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); #endif /* CONFIG_SND_HDA_INPUT_JACK */ MODULE_DESCRIPTION("HDA codec core"); MODULE_LICENSE("GPL");
sound/pci/hda/hda_codec.h +5 −0 Original line number Diff line number Diff line Loading @@ -866,6 +866,11 @@ struct hda_codec { /* codec-specific additional proc output */ void (*proc_widget_hook)(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid); #ifdef CONFIG_SND_HDA_INPUT_JACK /* jack detection */ struct snd_array jacks; #endif }; /* direction */ Loading
sound/pci/hda/hda_local.h +24 −0 Original line number Diff line number Diff line Loading @@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec, #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); /* * Input-jack notification support */ #ifdef CONFIG_SND_HDA_INPUT_JACK int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name); void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid); void snd_hda_input_jack_free(struct hda_codec *codec); #else /* CONFIG_SND_HDA_INPUT_JACK */ static inline int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, const char *name) { return 0; } static inline void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) { } static inline void snd_hda_input_jack_free(struct hda_codec *codec) { } #endif /* CONFIG_SND_HDA_INPUT_JACK */ #endif /* __SOUND_HDA_LOCAL_H */
sound/pci/hda/patch_conexant.c +14 −110 Original line number Diff line number Diff line Loading @@ -49,14 +49,6 @@ #define AUTO_MIC_PORTB (1 << 1) #define AUTO_MIC_PORTC (1 << 2) struct conexant_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; struct pin_dac_pair { hda_nid_t pin; hda_nid_t dac; Loading Loading @@ -111,9 +103,6 @@ struct conexant_spec { unsigned int spdif_route; /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct hda_input_mux private_imux; Loading Loading @@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } #ifdef CONFIG_SND_HDA_INPUT_JACK static void conexant_free_jack_priv(struct snd_jack *jack) { struct conexant_jack *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; int i, err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = spec->jacks.list; for (i = 0; i < spec->jacks.used; i++, jack++) if (jack->nid == nid) return 0 ; /* already present */ jack = snd_array_new(&spec->jacks); name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) return err; jack->jack->private_data = jack; jack->jack->private_free = conexant_free_jack_priv; return 0; } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct conexant_spec *spec = codec->spec; struct conexant_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_jack_detect(codec, nid); present = (present) ? jacks->type : 0 ; snd_jack_report(jacks->jack, present); } jacks++; } } } static int conexant_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct conexant_spec *spec = codec->spec; int i; Loading @@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec) int err = 0; switch (hv->param ^ AC_USRSP_EN) { case CONEXANT_HP_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_HEADPHONE); conexant_report_jack(codec, hv->nid); err = snd_hda_input_jack_add(codec, hv->nid, SND_JACK_HEADPHONE, NULL); snd_hda_input_jack_report(codec, hv->nid); break; case CXT5051_PORTC_EVENT: case CONEXANT_MIC_EVENT: err = conexant_add_jack(codec, hv->nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, hv->nid); err = snd_hda_input_jack_add(codec, hv->nid, SND_JACK_MICROPHONE, NULL); snd_hda_input_jack_report(codec, hv->nid); break; } if (err < 0) Loading @@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec) ++hv; } } return 0; } #else static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) { } static inline int conexant_init_jacks(struct hda_codec *codec) { #endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } #endif static int conexant_init(struct hda_codec *codec) { Loading @@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct conexant_spec *spec = codec->spec; if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; for (i = 0; i < spec->jacks.used; i++, jacks++) { if (jacks->jack) snd_device_free(codec->bus->card, jacks->jack); } snd_array_free(&spec->jacks); } #endif snd_hda_input_jack_free(codec); snd_hda_detach_beep_device(codec); kfree(codec->spec); } Loading Loading @@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); } static struct snd_kcontrol_new cxt5051_playback_mixers[] = { Loading Loading @@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | event); #ifdef CONFIG_SND_HDA_INPUT_JACK conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); conexant_report_jack(codec, nid); #endif snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); snd_hda_input_jack_report(codec, nid); } static struct hda_verb cxt5051_ideapad_init_verbs[] = { Loading Loading @@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) switch (res >> 26) { case CONEXANT_HP_EVENT: cx_auto_hp_automute(codec); conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); break; case CONEXANT_MIC_EVENT: cx_auto_automic(codec); conexant_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); break; } } Loading
sound/pci/hda/patch_realtek.c +12 −82 Original line number Diff line number Diff line Loading @@ -282,12 +282,6 @@ struct alc_mic_route { unsigned char amix_idx; }; struct alc_jack { hda_nid_t nid; int type; struct snd_jack *jack; }; #define MUX_IDX_UNDEF ((unsigned char)-1) struct alc_customize_define { Loading Loading @@ -366,9 +360,6 @@ struct alc_spec { /* PCM information */ struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ /* jack detection */ struct snd_array jacks; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct alc_customize_define cdefine; Loading Loading @@ -1032,94 +1023,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, alc_fix_pll(codec); } #ifdef CONFIG_SND_HDA_INPUT_JACK static void alc_free_jack_priv(struct snd_jack *jack) { struct alc_jack *jacks = jack->private_data; jacks->nid = 0; jacks->jack = NULL; } static int alc_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct alc_spec *spec; struct alc_jack *jack; const char *name; int err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); jack = snd_array_new(&spec->jacks); if (!jack) return -ENOMEM; jack->nid = nid; jack->type = type; name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; err = snd_jack_new(codec->bus->card, name, type, &jack->jack); if (err < 0) return err; jack->jack->private_data = jack; jack->jack->private_free = alc_free_jack_priv; return 0; } static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) { struct alc_spec *spec = codec->spec; struct alc_jack *jacks = spec->jacks.list; if (jacks) { int i; for (i = 0; i < spec->jacks.used; i++) { if (jacks->nid == nid) { unsigned int present; present = snd_hda_jack_detect(codec, nid); present = (present) ? jacks->type : 0; snd_jack_report(jacks->jack, present); } jacks++; } } } static int alc_init_jacks(struct hda_codec *codec) { #ifdef CONFIG_SND_HDA_INPUT_JACK struct alc_spec *spec = codec->spec; int err; unsigned int hp_nid = spec->autocfg.hp_pins[0]; unsigned int mic_nid = spec->ext_mic.pin; if (hp_nid) { err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); err = snd_hda_input_jack_add(codec, hp_nid, SND_JACK_HEADPHONE, NULL); if (err < 0) return err; alc_report_jack(codec, hp_nid); snd_hda_input_jack_report(codec, hp_nid); } if (mic_nid) { err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); err = snd_hda_input_jack_add(codec, mic_nid, SND_JACK_MICROPHONE, NULL); if (err < 0) return err; alc_report_jack(codec, mic_nid); snd_hda_input_jack_report(codec, mic_nid); } #endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } #else static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) { } static inline int alc_init_jacks(struct hda_codec *codec) { return 0; } #endif static void alc_automute_speaker(struct hda_codec *codec, int pinctl) { Loading @@ -1133,7 +1062,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) nid = spec->autocfg.hp_pins[i]; if (!nid) break; alc_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); spec->jack_present |= snd_hda_jack_detect(codec, nid); } Loading Loading @@ -1240,7 +1169,7 @@ static void alc_mic_automute(struct hda_codec *codec) AC_VERB_SET_CONNECT_SEL, alive->mux_idx); } alc_report_jack(codec, spec->ext_mic.pin); snd_hda_input_jack_report(codec, spec->ext_mic.pin); /* FIXME: analog mixer */ } Loading Loading @@ -4283,6 +4212,7 @@ static void alc_free(struct hda_codec *codec) return; alc_shutup(codec); snd_hda_input_jack_free(codec); alc_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); Loading Loading @@ -14494,7 +14424,7 @@ static void alc269_speaker_automute(struct hda_codec *codec) HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, HDA_AMP_MUTE, bits); alc_report_jack(codec, nid); snd_hda_input_jack_report(codec, nid); } /* unsolicited event for HP jack sensing */ Loading