diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/alc268_quirks.c | 36 | ||||
-rw-r--r-- | sound/pci/hda/alc269_quirks.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_eld.c | 31 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 9 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 57 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 71 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 2 |
10 files changed, 150 insertions, 83 deletions
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c index be58bf2f3aec..2e5876ce71fe 100644 --- a/sound/pci/hda/alc268_quirks.c +++ b/sound/pci/hda/alc268_quirks.c @@ -476,8 +476,8 @@ static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { static const struct alc_config_preset alc268_presets[] = { [ALC267_QUANTA_IL1] = { - .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, - alc268_capture_nosrc_mixer }, + .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_nosrc_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc267_quanta_il1_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -492,8 +492,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_3ST] = { - .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, - alc268_beep_mixer }, + .mixers = { alc268_base_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_alt_mixer, .init_verbs = { alc268_base_init_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), .dac_nids = alc268_dac_nids, @@ -507,8 +507,8 @@ static const struct alc_config_preset alc268_presets[] = { .input_mux = &alc268_capture_source, }, [ALC268_TOSHIBA] = { - .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, - alc268_beep_mixer }, + .mixers = { alc268_toshiba_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_alt_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_toshiba_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -525,8 +525,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_ACER] = { - .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, - alc268_beep_mixer }, + .mixers = { alc268_acer_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_alt_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_acer_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -543,8 +543,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_ACER_DMIC] = { - .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, - alc268_beep_mixer }, + .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_alt_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_acer_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -561,9 +561,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_ACER_ASPIRE_ONE] = { - .mixers = { alc268_acer_aspire_one_mixer, - alc268_beep_mixer, - alc268_capture_nosrc_mixer }, + .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer}, + .cap_mixer = alc268_capture_nosrc_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_acer_aspire_one_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -579,8 +578,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_DELL] = { - .mixers = { alc268_dell_mixer, alc268_beep_mixer, - alc268_capture_nosrc_mixer }, + .mixers = { alc268_dell_mixer, alc268_beep_mixer}, + .cap_mixer = alc268_capture_nosrc_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_dell_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -596,8 +595,8 @@ static const struct alc_config_preset alc268_presets[] = { .init_hook = alc_inithook, }, [ALC268_ZEPTO] = { - .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, - alc268_beep_mixer }, + .mixers = { alc268_base_mixer, alc268_beep_mixer }, + .cap_mixer = alc268_capture_alt_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_toshiba_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), @@ -616,7 +615,8 @@ static const struct alc_config_preset alc268_presets[] = { }, #ifdef CONFIG_SND_DEBUG [ALC268_TEST] = { - .mixers = { alc268_test_mixer, alc268_capture_mixer }, + .mixers = { alc268_test_mixer }, + .cap_mixer = alc268_capture_mixer, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_volume_init_verbs, alc268_beep_init_verbs }, diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c index 14fdcf29b154..5ac0e2162a46 100644 --- a/sound/pci/hda/alc269_quirks.c +++ b/sound/pci/hda/alc269_quirks.c @@ -531,17 +531,10 @@ static const struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), - SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", - ALC269_DMIC), - SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", - ALC269_DMIC), - SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), - SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3e7850c238c3..f3aefef37216 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -579,9 +579,13 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, return -1; } recursive++; - for (i = 0; i < nums; i++) + for (i = 0; i < nums; i++) { + unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i])); + if (type == AC_WID_PIN || type == AC_WID_AUD_OUT) + continue; if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0) return i; + } return -1; } EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 28ce17d09c33..c34f730f4815 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -144,25 +144,17 @@ static int cea_sampling_frequencies[8] = { SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ }; -static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, +static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid, int byte_index) { unsigned int val; val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD, byte_index); - #ifdef BE_PARANOID printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); #endif - - if ((val & AC_ELDD_ELD_VALID) == 0) { - snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", - byte_index); - val = 0; - } - - return val & AC_ELDD_ELD_DATA; + return val; } #define GRAB_BITS(buf, byte, lowbit, bits) \ @@ -344,11 +336,26 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, if (!buf) return -ENOMEM; - for (i = 0; i < size; i++) - buf[i] = hdmi_get_eld_byte(codec, nid, i); + for (i = 0; i < size; i++) { + unsigned int val = hdmi_get_eld_data(codec, nid, i); + if (!(val & AC_ELDD_ELD_VALID)) { + if (!i) { + snd_printd(KERN_INFO + "HDMI: invalid ELD data\n"); + ret = -EINVAL; + goto error; + } + snd_printd(KERN_INFO + "HDMI: invalid ELD data byte %d\n", i); + val = 0; + } else + val &= AC_ELDD_ELD_DATA; + buf[i] = val; + } ret = hdmi_update_eld(eld, buf, size); +error: kfree(buf); return ret; } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index be6982289c0d..e9a2a8795d1b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1924,7 +1924,8 @@ static unsigned int azx_via_get_position(struct azx *chip, } static unsigned int azx_get_position(struct azx *chip, - struct azx_dev *azx_dev) + struct azx_dev *azx_dev, + bool with_check) { unsigned int pos; int stream = azx_dev->substream->stream; @@ -1940,7 +1941,7 @@ static unsigned int azx_get_position(struct azx *chip, default: /* use the position buffer */ pos = le32_to_cpu(*azx_dev->posbuf); - if (chip->position_fix[stream] == POS_FIX_AUTO) { + if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) { if (!pos || pos == (u32)-1) { printk(KERN_WARNING "hda-intel: Invalid position buffer, " @@ -1964,7 +1965,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) struct azx *chip = apcm->chip; struct azx_dev *azx_dev = get_azx_dev(substream); return bytes_to_frames(substream->runtime, - azx_get_position(chip, azx_dev)); + azx_get_position(chip, azx_dev, false)); } /* @@ -1987,7 +1988,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) return -1; /* bogus (too early) interrupt */ stream = azx_dev->substream->stream; - pos = azx_get_position(chip, azx_dev); + pos = azx_get_position(chip, azx_dev, true); if (WARN_ONCE(!azx_dev->period_bytes, "hda-intel: zero azx_dev->period_bytes")) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 47d6ffc9b5b5..c45f3e69bcf0 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -375,7 +375,7 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx) static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, unsigned int *idxp) { - int i; + int i, idx; hda_nid_t nid; nid = codec->start_nid; @@ -384,9 +384,11 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, type = get_wcaps_type(get_wcaps(codec, nid)); if (type != AC_WID_AUD_IN) continue; - *idxp = snd_hda_get_conn_index(codec, nid, pin, false); - if (*idxp >= 0) + idx = snd_hda_get_conn_index(codec, nid, pin, false); + if (idx >= 0) { + *idxp = idx; return nid; + } } return 0; } @@ -533,7 +535,7 @@ static int add_volume(struct hda_codec *codec, const char *name, int index, unsigned int pval, int dir, struct snd_kcontrol **kctlp) { - char tmp[32]; + char tmp[44]; struct snd_kcontrol_new knew = HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); knew.private_value = pval; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 502fc9499453..7696d05b9356 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, #define MAX_AUTO_DACS 5 +#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */ + /* fill analog DAC list from the widget tree */ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) { @@ -3370,16 +3372,26 @@ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) /* fill pin_dac_pair list from the pin and dac list */ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, int num_pins, hda_nid_t *dacs, int *rest, - struct pin_dac_pair *filled, int type) + struct pin_dac_pair *filled, int nums, + int type) { - int i, nums; + int i, start = nums; - nums = 0; - for (i = 0; i < num_pins; i++) { + for (i = 0; i < num_pins; i++, nums++) { filled[nums].pin = pins[i]; filled[nums].type = type; filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); - nums++; + if (filled[nums].dac) + continue; + if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) { + filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG; + continue; + } + if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) { + filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG; + continue; + } + snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]); } return nums; } @@ -3395,19 +3407,19 @@ static void cx_auto_parse_output(struct hda_codec *codec) rest = fill_cx_auto_dacs(codec, dacs); /* parse all analog output pins */ nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, - dacs, &rest, spec->dac_info, - AUTO_PIN_LINE_OUT); - nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, - dacs, &rest, spec->dac_info + nums, - AUTO_PIN_HP_OUT); - nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, - dacs, &rest, spec->dac_info + nums, - AUTO_PIN_SPEAKER_OUT); + dacs, &rest, spec->dac_info, 0, + AUTO_PIN_LINE_OUT); + nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, + dacs, &rest, spec->dac_info, nums, + AUTO_PIN_HP_OUT); + nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, + dacs, &rest, spec->dac_info, nums, + AUTO_PIN_SPEAKER_OUT); spec->dac_info_filled = nums; /* fill multiout struct */ for (i = 0; i < nums; i++) { hda_nid_t dac = spec->dac_info[i].dac; - if (!dac) + if (!dac || (dac & DAC_SLAVE_FLAG)) continue; switch (spec->dac_info[i].type) { case AUTO_PIN_LINE_OUT: @@ -3862,7 +3874,7 @@ static void cx_auto_parse_input(struct hda_codec *codec) } if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) cx_auto_check_auto_mic(codec); - if (imux->num_items > 1 && !spec->auto_mic) { + if (imux->num_items > 1) { for (i = 1; i < imux->num_items; i++) { if (spec->imux_info[i].adc != spec->imux_info[0].adc) { spec->adc_switching = 1; @@ -4035,6 +4047,8 @@ static void cx_auto_init_output(struct hda_codec *codec) nid = spec->dac_info[i].dac; if (!nid) nid = spec->multiout.dac_nids[0]; + else if (nid & DAC_SLAVE_FLAG) + nid &= ~DAC_SLAVE_FLAG; select_connection(codec, spec->dac_info[i].pin, nid); } if (spec->auto_mute) { @@ -4167,9 +4181,11 @@ static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, hda_nid_t pin, const char *name, int idx) { unsigned int caps; - caps = query_amp_caps(codec, dac, HDA_OUTPUT); - if (caps & AC_AMPCAP_NUM_STEPS) - return cx_auto_add_pb_volume(codec, dac, name, idx); + if (dac && !(dac & DAC_SLAVE_FLAG)) { + caps = query_amp_caps(codec, dac, HDA_OUTPUT); + if (caps & AC_AMPCAP_NUM_STEPS) + return cx_auto_add_pb_volume(codec, dac, name, idx); + } caps = query_amp_caps(codec, pin, HDA_OUTPUT); if (caps & AC_AMPCAP_NUM_STEPS) return cx_auto_add_pb_volume(codec, pin, name, idx); @@ -4191,8 +4207,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) for (i = 0; i < spec->dac_info_filled; i++) { const char *label; int idx, type; - if (!spec->dac_info[i].dac) - continue; + hda_nid_t dac = spec->dac_info[i].dac; type = spec->dac_info[i].type; if (type == AUTO_PIN_LINE_OUT) type = spec->autocfg.line_out_type; @@ -4211,7 +4226,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) idx = num_spk++; break; } - err = try_add_pb_volume(codec, spec->dac_info[i].dac, + err = try_add_pb_volume(codec, dac, spec->dac_info[i].pin, label, idx); if (err < 0) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e125c60fe352..7a73621a8909 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -168,7 +168,7 @@ struct alc_spec { unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ unsigned int automute:1; /* HP automute enabled */ unsigned int detect_line:1; /* Line-out detection enabled */ - unsigned int automute_lines:1; /* automute line-out as well */ + unsigned int automute_lines:1; /* automute line-out as well; NOP when automute_hp_lo isn't set */ unsigned int automute_hp_lo:1; /* both HP and LO available */ /* other flags */ @@ -551,7 +551,7 @@ static void update_speakers(struct hda_codec *codec) if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) return; - if (!spec->automute_lines || !spec->automute) + if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines)) on = 0; else on = spec->jack_present; @@ -565,11 +565,11 @@ static void alc_hp_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (!spec->automute) - return; spec->jack_present = detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), spec->autocfg.hp_pins); + if (!spec->automute) + return; update_speakers(codec); } @@ -578,11 +578,15 @@ static void alc_line_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (!spec->automute || !spec->detect_line) + /* check LO jack only when it's different from HP */ + if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) return; + spec->line_jack_present = detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), spec->autocfg.line_out_pins); + if (!spec->automute || !spec->detect_line) + return; update_speakers(codec); } @@ -803,7 +807,7 @@ static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, unsigned int val; if (!spec->automute) val = 0; - else if (!spec->automute_lines) + else if (!spec->automute_hp_lo || !spec->automute_lines) val = 1; else val = 2; @@ -824,7 +828,8 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, spec->automute = 0; break; case 1: - if (spec->automute && !spec->automute_lines) + if (spec->automute && + (!spec->automute_hp_lo || !spec->automute_lines)) return 0; spec->automute = 1; spec->automute_lines = 0; @@ -1320,7 +1325,9 @@ do_sku: * 15 : 1 --> enable the function "Mute internal speaker * when the external headphone out jack is plugged" */ - if (!spec->autocfg.hp_pins[0]) { + if (!spec->autocfg.hp_pins[0] && + !(spec->autocfg.line_out_pins[0] && + spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) { hda_nid_t nid; tmp = (ass >> 11) & 0x3; /* HP to chassis */ if (tmp == 0) @@ -1784,6 +1791,7 @@ static const char * const alc_slave_vols[] = { "Speaker Playback Volume", "Mono Playback Volume", "Line-Out Playback Volume", + "PCM Playback Volume", NULL, }; @@ -1798,6 +1806,7 @@ static const char * const alc_slave_sws[] = { "Mono Playback Switch", "IEC958 Playback Switch", "Line-Out Playback Switch", + "PCM Playback Switch", NULL, }; @@ -3081,16 +3090,22 @@ static void alc_auto_init_multi_out(struct hda_codec *codec) static void alc_auto_init_extra_out(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - hda_nid_t pin; + hda_nid_t pin, dac; pin = spec->autocfg.hp_pins[0]; - if (pin) - alc_auto_set_output_and_unmute(codec, pin, PIN_HP, - spec->multiout.hp_nid); + if (pin) { + dac = spec->multiout.hp_nid; + if (!dac) + dac = spec->multiout.dac_nids[0]; + alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); + } pin = spec->autocfg.speaker_pins[0]; - if (pin) - alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, - spec->multiout.extra_out_nid[0]); + if (pin) { + dac = spec->multiout.extra_out_nid[0]; + if (!dac) + dac = spec->multiout.dac_nids[0]; + alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); + } } /* @@ -4484,6 +4499,22 @@ static void alc269_fixup_pcm_44k(struct hda_codec *codec, spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; } +static void alc269_fixup_stereo_dmic(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + int coef; + + if (action != ALC_FIXUP_ACT_INIT) + return; + /* The digital-mic unit sends PDM (differential signal) instead of + * the standard PCM, thus you can't record a valid mono stream as is. + * Below is a workaround specific to ALC269 to control the dmic + * signal source as mono. + */ + coef = alc_read_coef_idx(codec, 0x07); + alc_write_coef_idx(codec, 0x07, coef | 0x80); +} + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -4494,6 +4525,7 @@ enum { ALC275_FIXUP_SONY_HWEQ, ALC271_FIXUP_DMIC, ALC269_FIXUP_PCM_44K, + ALC269_FIXUP_STEREO_DMIC, }; static const struct alc_fixup alc269_fixups[] = { @@ -4556,10 +4588,19 @@ static const struct alc_fixup alc269_fixups[] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_pcm_44k, }, + [ALC269_FIXUP_STEREO_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc269_fixup_stereo_dmic, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index aa376b59c006..987e3cf71a0b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -673,6 +673,7 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE static int stac_vrefout_set(struct hda_codec *codec, hda_nid_t nid, unsigned int new_vref) { @@ -696,6 +697,7 @@ static int stac_vrefout_set(struct hda_codec *codec, return 1; } +#endif static unsigned int stac92xx_vref_set(struct hda_codec *codec, hda_nid_t nid, unsigned int new_vref) @@ -5628,6 +5630,7 @@ again: switch (codec->vendor_id) { case 0x111d76d1: case 0x111d76d9: + case 0x111d76df: case 0x111d76e5: case 0x111d7666: case 0x111d7667: @@ -6571,6 +6574,7 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, + { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 84d8798bf33a..4ebfbd874c9a 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -2084,7 +2084,7 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec) struct via_spec *spec = codec->spec; struct nid_path *path; bool check_dac; - hda_nid_t pin, dac; + hda_nid_t pin, dac = 0; int err; pin = spec->autocfg.speaker_pins[0]; |