Loading Documentation/sound/alsa/ALSA-Configuration.txt +3 −1 Original line number Diff line number Diff line Loading @@ -1076,7 +1076,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. STAC92HD73* ref Reference board dell-m6 Dell desktops dell-m6-amic Dell desktops/laptops with analog mics dell-m6-dmic Dell desktops/laptops with digital mics dell-m6 Dell desktops/laptops with both type of mics STAC9872 vaio Setup for VAIO FE550G/SZ110 Loading sound/pci/hda/hda_codec.c +2 −2 Original line number Diff line number Diff line Loading @@ -1436,12 +1436,12 @@ static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, { hda_nid_t *d; snd_hda_codec_write(codec, nid, 0, verb, val); snd_hda_codec_write_cache(codec, nid, 0, verb, val); d = codec->slave_dig_outs; if (!d) return; for (; *d; d++) snd_hda_codec_write(codec, *d, 0, verb, val); snd_hda_codec_write_cache(codec, *d, 0, verb, val); } static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid, Loading sound/pci/hda/patch_sigmatel.c +81 −48 Original line number Diff line number Diff line Loading @@ -70,7 +70,9 @@ enum { enum { STAC_92HD73XX_REF, STAC_DELL_M6, STAC_DELL_M6_AMIC, STAC_DELL_M6_DMIC, STAC_DELL_M6_BOTH, STAC_DELL_EQ, STAC_92HD73XX_MODELS }; Loading Loading @@ -1602,13 +1604,17 @@ static unsigned int dell_m6_pin_configs[13] = { static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6] = dell_m6_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, [STAC_DELL_EQ] = dell_m6_pin_configs, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = "ref", [STAC_DELL_M6] = "dell-m6", [STAC_DELL_M6_AMIC] = "dell-m6-amic", [STAC_DELL_M6_DMIC] = "dell-m6-dmic", [STAC_DELL_M6_BOTH] = "dell-m6", [STAC_DELL_EQ] = "dell-eq", }; Loading @@ -1617,21 +1623,23 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD73XX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, "unknown Dell", STAC_DELL_M6), "Dell Studio 1535", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272, "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, "Dell Studio 15", STAC_DELL_M6), "Dell Studio 1537", STAC_DELL_M6_DMIC), {} /* terminator */ }; Loading Loading @@ -2891,7 +2899,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, cfg->hp_outs && !spec->multiout.hp_nid) spec->multiout.hp_nid = nid; if (cfg->hp_outs > 1) { if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { err = stac92xx_add_control(spec, STAC_CTL_WIDGET_HP_SWITCH, "Headphone as Line Out Switch", Loading Loading @@ -3697,10 +3705,14 @@ static void stac92xx_power_down(struct hda_codec *codec) AC_VERB_SET_POWER_STATE, AC_PWRST_D3); } static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable); static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int gpio; int i; snd_hda_sequence_write(codec, spec->init); Loading @@ -3711,6 +3723,16 @@ static int stac92xx_init(struct hda_codec *codec) snd_hda_codec_write_cache(codec, spec->adc_nids[i], 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); /* set up GPIO */ gpio = spec->gpio_data; /* turn on EAPD statically when spec->eapd_switch isn't set. * otherwise, unsol event will turn it on/off dynamically */ if (!spec->eapd_switch) gpio |= spec->eapd_mask; stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); /* set up pins */ if (spec->hp_detect) { /* Enable unsolicited responses on the HP widget */ Loading Loading @@ -3750,39 +3772,43 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < spec->num_dmics; i++) stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], AC_PINCTL_IN_EN); if (cfg->dig_out_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, AC_PINCTL_OUT_EN); if (cfg->dig_in_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, AC_PINCTL_IN_EN); for (i = 0; i < spec->num_pwrs; i++) { int event = is_nid_hp_pin(cfg, spec->pwr_nids[i]) ? STAC_HP_EVENT : STAC_PWR_EVENT; int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 0, AC_VERB_GET_CONFIG_DEFAULT, 0); def_conf = get_defcfg_connect(def_conf); hda_nid_t nid = spec->pwr_nids[i]; int pinctl, def_conf; int event = STAC_PWR_EVENT; if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) continue; /* already has an unsol event */ pinctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); /* outputs are only ports capable of power management * any attempts on powering down a input port cause the * referenced VREF to act quirky. */ if (pinctl & AC_PINCTL_IN_EN) continue; def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); def_conf = get_defcfg_connect(def_conf); /* skip any ports that don't have jacks since presence * detection is useless */ if (def_conf && def_conf != AC_JACK_PORT_FIXED) if (def_conf != AC_JACK_PORT_COMPLEX) { if (def_conf != AC_JACK_PORT_NONE) stac_toggle_power_map(codec, nid, 1); continue; } enable_pin_detect(codec, spec->pwr_nids[i], event | i); codec->patch_ops.unsol_event(codec, (event | i) << 26); } if (spec->dac_list) stac92xx_power_down(codec); if (cfg->dig_out_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, AC_PINCTL_OUT_EN); if (cfg->dig_in_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, AC_PINCTL_IN_EN); stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); return 0; } Loading Loading @@ -3947,14 +3973,18 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) } } static void stac92xx_pin_sense(struct hda_codec *codec, int idx) static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable) { struct sigmatel_spec *spec = codec->spec; hda_nid_t nid = spec->pwr_nids[idx]; int presence, val; val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0x000000ff; presence = get_hp_pin_presence(codec, nid); unsigned int idx, val; for (idx = 0; idx < spec->num_pwrs; idx++) { if (spec->pwr_nids[idx] == nid) break; } if (idx >= spec->num_pwrs) return; /* several codecs have two power down bits */ if (spec->pwr_mapping) Loading @@ -3962,14 +3992,20 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) else idx = 1 << idx; if (presence) val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; if (enable) val &= ~idx; else val |= idx; /* power down unused output ports */ snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); }; } static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) { stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); } static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) { Loading Loading @@ -4253,7 +4289,9 @@ static int patch_stac92hd73xx(struct hda_codec *codec) case STAC_DELL_EQ: spec->init = dell_eq_core_init; /* fallthru */ case STAC_DELL_M6: case STAC_DELL_M6_AMIC: case STAC_DELL_M6_DMIC: case STAC_DELL_M6_BOTH: spec->num_smuxes = 0; spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; Loading @@ -4262,23 +4300,18 @@ static int patch_stac92hd73xx(struct hda_codec *codec) if (!spec->init) spec->init = dell_m6_core_init; switch (codec->subsystem_id) { case 0x1028025e: /* Analog Mics */ case 0x1028025f: switch (spec->board_config) { case STAC_DELL_M6_AMIC: /* Analog Mics */ stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); spec->num_dmics = 0; spec->private_dimux.num_items = 1; break; case 0x10280271: /* Digital Mics */ case 0x10280272: case 0x10280254: case 0x10280255: case STAC_DELL_M6_DMIC: /* Digital Mics */ stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; spec->private_dimux.num_items = 2; break; case 0x10280256: /* Both */ case 0x10280057: case STAC_DELL_M6_BOTH: /* Both */ stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; Loading Loading
Documentation/sound/alsa/ALSA-Configuration.txt +3 −1 Original line number Diff line number Diff line Loading @@ -1076,7 +1076,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. STAC92HD73* ref Reference board dell-m6 Dell desktops dell-m6-amic Dell desktops/laptops with analog mics dell-m6-dmic Dell desktops/laptops with digital mics dell-m6 Dell desktops/laptops with both type of mics STAC9872 vaio Setup for VAIO FE550G/SZ110 Loading
sound/pci/hda/hda_codec.c +2 −2 Original line number Diff line number Diff line Loading @@ -1436,12 +1436,12 @@ static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, { hda_nid_t *d; snd_hda_codec_write(codec, nid, 0, verb, val); snd_hda_codec_write_cache(codec, nid, 0, verb, val); d = codec->slave_dig_outs; if (!d) return; for (; *d; d++) snd_hda_codec_write(codec, *d, 0, verb, val); snd_hda_codec_write_cache(codec, *d, 0, verb, val); } static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid, Loading
sound/pci/hda/patch_sigmatel.c +81 −48 Original line number Diff line number Diff line Loading @@ -70,7 +70,9 @@ enum { enum { STAC_92HD73XX_REF, STAC_DELL_M6, STAC_DELL_M6_AMIC, STAC_DELL_M6_DMIC, STAC_DELL_M6_BOTH, STAC_DELL_EQ, STAC_92HD73XX_MODELS }; Loading Loading @@ -1602,13 +1604,17 @@ static unsigned int dell_m6_pin_configs[13] = { static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6] = dell_m6_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, [STAC_DELL_EQ] = dell_m6_pin_configs, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = "ref", [STAC_DELL_M6] = "dell-m6", [STAC_DELL_M6_AMIC] = "dell-m6-amic", [STAC_DELL_M6_DMIC] = "dell-m6-dmic", [STAC_DELL_M6_BOTH] = "dell-m6", [STAC_DELL_EQ] = "dell-eq", }; Loading @@ -1617,21 +1623,23 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD73XX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, "unknown Dell", STAC_DELL_M6), "Dell Studio 1535", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_AMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, "unknown Dell", STAC_DELL_M6), "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272, "unknown Dell", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, "Dell Studio 15", STAC_DELL_M6), "Dell Studio 1537", STAC_DELL_M6_DMIC), {} /* terminator */ }; Loading Loading @@ -2891,7 +2899,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, cfg->hp_outs && !spec->multiout.hp_nid) spec->multiout.hp_nid = nid; if (cfg->hp_outs > 1) { if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { err = stac92xx_add_control(spec, STAC_CTL_WIDGET_HP_SWITCH, "Headphone as Line Out Switch", Loading Loading @@ -3697,10 +3705,14 @@ static void stac92xx_power_down(struct hda_codec *codec) AC_VERB_SET_POWER_STATE, AC_PWRST_D3); } static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable); static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int gpio; int i; snd_hda_sequence_write(codec, spec->init); Loading @@ -3711,6 +3723,16 @@ static int stac92xx_init(struct hda_codec *codec) snd_hda_codec_write_cache(codec, spec->adc_nids[i], 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); /* set up GPIO */ gpio = spec->gpio_data; /* turn on EAPD statically when spec->eapd_switch isn't set. * otherwise, unsol event will turn it on/off dynamically */ if (!spec->eapd_switch) gpio |= spec->eapd_mask; stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); /* set up pins */ if (spec->hp_detect) { /* Enable unsolicited responses on the HP widget */ Loading Loading @@ -3750,39 +3772,43 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < spec->num_dmics; i++) stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], AC_PINCTL_IN_EN); if (cfg->dig_out_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, AC_PINCTL_OUT_EN); if (cfg->dig_in_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, AC_PINCTL_IN_EN); for (i = 0; i < spec->num_pwrs; i++) { int event = is_nid_hp_pin(cfg, spec->pwr_nids[i]) ? STAC_HP_EVENT : STAC_PWR_EVENT; int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 0, AC_VERB_GET_CONFIG_DEFAULT, 0); def_conf = get_defcfg_connect(def_conf); hda_nid_t nid = spec->pwr_nids[i]; int pinctl, def_conf; int event = STAC_PWR_EVENT; if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) continue; /* already has an unsol event */ pinctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); /* outputs are only ports capable of power management * any attempts on powering down a input port cause the * referenced VREF to act quirky. */ if (pinctl & AC_PINCTL_IN_EN) continue; def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); def_conf = get_defcfg_connect(def_conf); /* skip any ports that don't have jacks since presence * detection is useless */ if (def_conf && def_conf != AC_JACK_PORT_FIXED) if (def_conf != AC_JACK_PORT_COMPLEX) { if (def_conf != AC_JACK_PORT_NONE) stac_toggle_power_map(codec, nid, 1); continue; } enable_pin_detect(codec, spec->pwr_nids[i], event | i); codec->patch_ops.unsol_event(codec, (event | i) << 26); } if (spec->dac_list) stac92xx_power_down(codec); if (cfg->dig_out_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, AC_PINCTL_OUT_EN); if (cfg->dig_in_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, AC_PINCTL_IN_EN); stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); return 0; } Loading Loading @@ -3947,14 +3973,18 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) } } static void stac92xx_pin_sense(struct hda_codec *codec, int idx) static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable) { struct sigmatel_spec *spec = codec->spec; hda_nid_t nid = spec->pwr_nids[idx]; int presence, val; val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0x000000ff; presence = get_hp_pin_presence(codec, nid); unsigned int idx, val; for (idx = 0; idx < spec->num_pwrs; idx++) { if (spec->pwr_nids[idx] == nid) break; } if (idx >= spec->num_pwrs) return; /* several codecs have two power down bits */ if (spec->pwr_mapping) Loading @@ -3962,14 +3992,20 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) else idx = 1 << idx; if (presence) val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; if (enable) val &= ~idx; else val |= idx; /* power down unused output ports */ snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); }; } static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) { stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); } static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) { Loading Loading @@ -4253,7 +4289,9 @@ static int patch_stac92hd73xx(struct hda_codec *codec) case STAC_DELL_EQ: spec->init = dell_eq_core_init; /* fallthru */ case STAC_DELL_M6: case STAC_DELL_M6_AMIC: case STAC_DELL_M6_DMIC: case STAC_DELL_M6_BOTH: spec->num_smuxes = 0; spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; Loading @@ -4262,23 +4300,18 @@ static int patch_stac92hd73xx(struct hda_codec *codec) if (!spec->init) spec->init = dell_m6_core_init; switch (codec->subsystem_id) { case 0x1028025e: /* Analog Mics */ case 0x1028025f: switch (spec->board_config) { case STAC_DELL_M6_AMIC: /* Analog Mics */ stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); spec->num_dmics = 0; spec->private_dimux.num_items = 1; break; case 0x10280271: /* Digital Mics */ case 0x10280272: case 0x10280254: case 0x10280255: case STAC_DELL_M6_DMIC: /* Digital Mics */ stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; spec->private_dimux.num_items = 2; break; case 0x10280256: /* Both */ case 0x10280057: case STAC_DELL_M6_BOTH: /* Both */ stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; Loading