diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 83d5335ac348..1d9d6427e0bf 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -211,7 +211,6 @@ struct sigmatel_spec { /* beep widgets */ hda_nid_t anabeep_nid; - hda_nid_t digbeep_nid; /* SPDIF-out mux */ const char * const *spdif_labels; @@ -815,6 +814,29 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) return 0; } +/* check whether a built-in speaker is included in parsed pins */ +static bool has_builtin_speaker(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t *nid_pin; + int nids, i; + + if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) { + nid_pin = spec->gen.autocfg.line_out_pins; + nids = spec->gen.autocfg.line_outs; + } else { + nid_pin = spec->gen.autocfg.speaker_pins; + nids = spec->gen.autocfg.speaker_outs; + } + + for (i = 0; i < nids; i++) { + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]); + if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT) + return true; + } + return false; +} + /* * PC beep controls */ @@ -3506,8 +3528,12 @@ static int stac_parse_auto_config(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; int err; + int flags = 0; + + if (spec->headset_jack) + flags |= HDA_PINCFG_HEADSET_MIC; - err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); + err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags); if (err < 0) return err; @@ -3537,16 +3563,13 @@ static int stac_parse_auto_config(struct hda_codec *codec) /* setup digital beep controls and input device */ #ifdef CONFIG_SND_HDA_INPUT_BEEP - if (spec->digbeep_nid > 0) { - hda_nid_t nid = spec->digbeep_nid; + if (spec->gen.beep_nid) { + hda_nid_t nid = spec->gen.beep_nid; unsigned int caps; err = stac_auto_create_beep_ctls(codec, nid); if (err < 0) return err; - err = snd_hda_attach_beep_device(codec, nid); - if (err < 0) - return err; if (codec->beep) { /* IDT/STAC codecs have linear beep tone parameter */ codec->beep->linear_tone = spec->linear_tone_beep; @@ -3634,17 +3657,7 @@ static void stac_shutup(struct hda_codec *codec) ~spec->eapd_mask); } -static void stac_free(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - - if (!spec) - return; - - snd_hda_gen_spec_free(&spec->gen); - kfree(spec); - snd_hda_detach_beep_device(codec); -} +#define stac_free snd_hda_gen_free #ifdef CONFIG_PROC_FS static void stac92hd_proc_hook(struct snd_info_buffer *buffer, @@ -3774,6 +3787,7 @@ static int patch_stac9200(struct hda_codec *codec) spec->gen.own_eapd_ctl = 1; codec->patch_ops = stac_patch_ops; + codec->power_filter = snd_hda_codec_eapd_power_filter; snd_hda_add_verbs(codec, stac9200_eapd_init); @@ -3861,7 +3875,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) spec->aloopback_mask = 0x01; spec->aloopback_shift = 8; - spec->digbeep_nid = 0x1c; + spec->gen.beep_nid = 0x1c; /* digital beep */ /* GPIO0 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; @@ -3890,6 +3904,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec) return err; } + /* Don't GPIO-mute speakers if there are no internal speakers, because + * the GPIO might be necessary for Headphone + */ + if (spec->eapd_switch && !has_builtin_speaker(codec)) + spec->eapd_switch = 0; + codec->proc_widget_hook = stac92hd7x_proc_hook; snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -3939,7 +3959,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec->gen.power_down_unused = 1; spec->gen.mixer_nid = 0x1b; - spec->digbeep_nid = 0x21; + spec->gen.beep_nid = 0x21; /* digital beep */ spec->pwr_nids = stac92hd83xxx_pwr_nids; spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); spec->default_polarity = -1; /* no default cfg */ @@ -3987,7 +4007,7 @@ static int patch_stac92hd95(struct hda_codec *codec) spec->gen.own_eapd_ctl = 1; spec->gen.power_down_unused = 1; - spec->digbeep_nid = 0x19; + spec->gen.beep_nid = 0x19; /* digital beep */ spec->pwr_nids = stac92hd95_pwr_nids; spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); spec->default_polarity = -1; /* no default cfg */ @@ -4062,7 +4082,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) spec->aloopback_shift = 0; spec->powerdown_adcs = 1; - spec->digbeep_nid = 0x26; + spec->gen.beep_nid = 0x26; /* digital beep */ spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); spec->pwr_nids = stac92hd71bxx_pwr_nids; @@ -4144,7 +4164,7 @@ static int patch_stac927x(struct hda_codec *codec) spec->have_spdif_mux = 1; spec->spdif_labels = stac927x_spdif_labels; - spec->digbeep_nid = 0x23; + spec->gen.beep_nid = 0x23; /* digital beep */ /* GPIO0 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = 0x01; @@ -4203,7 +4223,7 @@ static int patch_stac9205(struct hda_codec *codec) spec->gen.own_eapd_ctl = 1; spec->have_spdif_mux = 1; - spec->digbeep_nid = 0x23; + spec->gen.beep_nid = 0x23; /* digital beep */ snd_hda_add_verbs(codec, stac9205_core_init); spec->aloopback_ctl = &stac9205_loopback; |