diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 91 |
1 files changed, 72 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3457f61..f6d7ef4 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -40,6 +40,7 @@ enum { STAC_INSERT_EVENT, STAC_PWR_EVENT, STAC_HP_EVENT, + STAC_LO_EVENT, STAC_MIC_EVENT, }; @@ -1806,6 +1807,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { "Dell Studio 1537", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, "Dell Studio 17", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be, + "Dell Studio 1555", STAC_DELL_M6_DMIC), {} /* terminator */ }; @@ -1916,6 +1919,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP mini 1000", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, "HP HDX", STAC_HP_HDX), /* HDX16 */ + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, + "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, @@ -2261,7 +2266,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), @@ -3320,11 +3325,11 @@ static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol, { int err; err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, - "Captuer Volume", vol); + "Capture Volume", vol); if (err < 0) return err; err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx, - "Captuer Switch", sw); + "Capture Switch", sw); if (err < 0) return err; return 0; @@ -3696,7 +3701,7 @@ static int set_mic_route(struct hda_codec *codec, if (i < 0) return -1; mic->mux_idx = i; - } else { + } else if (spec->dmux_nids) { /* digital pin */ mic->mux_idx = 0; i = get_connection_index(codec, spec->dmux_nids[0], pin); @@ -4376,6 +4381,15 @@ static int stac92xx_init(struct hda_codec *codec) hda_nid_t nid = cfg->hp_pins[i]; enable_pin_detect(codec, nid, STAC_HP_EVENT); } + if (cfg->line_out_type == AUTO_PIN_LINE_OUT && + cfg->speaker_outs > 0) { + /* enable pin-detect for line-outs as well */ + for (i = 0; i < cfg->line_outs; i++) { + hda_nid_t nid = cfg->line_out_pins[i]; + enable_pin_detect(codec, nid, STAC_LO_EVENT); + } + } + /* force to enable the first line-out; the others are set up * in unsol_event */ @@ -4391,7 +4405,8 @@ static int stac92xx_init(struct hda_codec *codec) } if (spec->auto_mic) { /* initialize connection to analog input */ - snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, + if (spec->dmux_nids) + snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, AC_VERB_SET_CONNECT_SEL, 0); if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) stac_issue_unsol_event(codec, spec->ext_mic.pin); @@ -4574,6 +4589,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) return 0; } +static void stac92xx_line_out_detect(struct hda_codec *codec, + int presence) +{ + struct sigmatel_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int i; + + for (i = 0; i < cfg->line_outs; i++) { + if (presence) + break; + presence = get_pin_presence(codec, cfg->line_out_pins[i]); + if (presence) { + unsigned int pinctl; + pinctl = snd_hda_codec_read(codec, + cfg->line_out_pins[i], 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + if (pinctl & AC_PINCTL_IN_EN) + presence = 0; /* mic- or line-input */ + } + } + + if (presence) { + /* disable speakers */ + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + if (spec->eapd_mask && spec->eapd_switch) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data & + ~spec->eapd_mask); + } else { + /* enable speakers */ + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_set_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + if (spec->eapd_mask && spec->eapd_switch) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data | + spec->eapd_mask); + } +} + /* return non-zero if the hp-pin of the given array index isn't * a jack-detection target */ @@ -4626,13 +4683,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); - for (i = 0; i < cfg->speaker_outs; i++) - stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], - AC_PINCTL_OUT_EN); - if (spec->eapd_mask && spec->eapd_switch) - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data & - ~spec->eapd_mask); } else { /* enable lineouts */ if (spec->hp_switch) @@ -4641,14 +4691,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) stac92xx_set_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); - for (i = 0; i < cfg->speaker_outs; i++) - stac92xx_set_pinctl(codec, cfg->speaker_pins[i], - AC_PINCTL_OUT_EN); - if (spec->eapd_mask && spec->eapd_switch) - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data | - spec->eapd_mask); } + stac92xx_line_out_detect(codec, presence); /* toggle hp outs */ for (i = 0; i < cfg->hp_outs; i++) { unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; @@ -4773,6 +4817,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) switch (event->type) { case STAC_HP_EVENT: + case STAC_LO_EVENT: stac92xx_hp_detect(codec); break; case STAC_MIC_EVENT: @@ -4782,6 +4827,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) switch (event->type) { case STAC_HP_EVENT: + case STAC_LO_EVENT: case STAC_MIC_EVENT: case STAC_INSERT_EVENT: case STAC_PWR_EVENT: @@ -5776,6 +5822,13 @@ static int patch_stac927x(struct hda_codec *codec) /* GPIO2 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04; spec->gpio_data = 0x04; + switch (codec->subsystem_id) { + case 0x1028022f: + /* correct EAPD to be GPIO0 */ + spec->eapd_mask = spec->gpio_mask = 0x01; + spec->gpio_dir = spec->gpio_data = 0x01; + break; + }; spec->dmic_nids = stac927x_dmic_nids; spec->num_dmics = STAC927X_NUM_DMICS; |