aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c313
1 files changed, 263 insertions, 50 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index aa4c25e0f327..f141395dfee6 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -170,10 +170,10 @@ struct alc_spec {
170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; 170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; 171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ 172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
173 hda_nid_t inv_dmic_pin;
173 174
174 /* hooks */ 175 /* hooks */
175 void (*init_hook)(struct hda_codec *codec); 176 void (*init_hook)(struct hda_codec *codec);
176 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
177#ifdef CONFIG_SND_HDA_POWER_SAVE 177#ifdef CONFIG_SND_HDA_POWER_SAVE
178 void (*power_hook)(struct hda_codec *codec); 178 void (*power_hook)(struct hda_codec *codec);
179#endif 179#endif
@@ -201,6 +201,8 @@ struct alc_spec {
201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ 201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ 202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ 203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
204 unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
205 unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
204 206
205 /* auto-mute control */ 207 /* auto-mute control */
206 int automute_mode; 208 int automute_mode;
@@ -298,6 +300,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
298} 300}
299 301
300static void call_update_outputs(struct hda_codec *codec); 302static void call_update_outputs(struct hda_codec *codec);
303static void alc_inv_dmic_sync(struct hda_codec *codec, bool force);
304
305/* for shared I/O, change the pin-control accordingly */
306static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic)
307{
308 struct alc_spec *spec = codec->spec;
309 unsigned int val;
310 hda_nid_t pin = spec->autocfg.inputs[1].pin;
311 /* NOTE: this assumes that there are only two inputs, the
312 * first is the real internal mic and the second is HP/mic jack.
313 */
314
315 val = snd_hda_get_default_vref(codec, pin);
316
317 /* This pin does not have vref caps - let's enable vref on pin 0x18
318 instead, as suggested by Realtek */
319 if (val == AC_PINCTL_VREF_HIZ) {
320 const hda_nid_t vref_pin = 0x18;
321 /* Sanity check pin 0x18 */
322 if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN &&
323 get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) {
324 unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin);
325 if (vref_val != AC_PINCTL_VREF_HIZ)
326 snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0));
327 }
328 }
329
330 val = set_as_mic ? val | PIN_IN : PIN_HP;
331 snd_hda_set_pin_ctl(codec, pin, val);
332
333 spec->automute_speaker = !set_as_mic;
334 call_update_outputs(codec);
335}
301 336
302/* select the given imux item; either unmute exclusively or select the route */ 337/* select the given imux item; either unmute exclusively or select the route */
303static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, 338static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
@@ -325,21 +360,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
325 return 0; 360 return 0;
326 spec->cur_mux[adc_idx] = idx; 361 spec->cur_mux[adc_idx] = idx;
327 362
328 /* for shared I/O, change the pin-control accordingly */ 363 if (spec->shared_mic_hp)
329 if (spec->shared_mic_hp) { 364 update_shared_mic_hp(codec, spec->cur_mux[adc_idx]);
330 unsigned int val;
331 hda_nid_t pin = spec->autocfg.inputs[1].pin;
332 /* NOTE: this assumes that there are only two inputs, the
333 * first is the real internal mic and the second is HP jack.
334 */
335 if (spec->cur_mux[adc_idx])
336 val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
337 else
338 val = PIN_HP;
339 snd_hda_set_pin_ctl(codec, pin, val);
340 spec->automute_speaker = !spec->cur_mux[adc_idx];
341 call_update_outputs(codec);
342 }
343 365
344 if (spec->dyn_adc_switch) { 366 if (spec->dyn_adc_switch) {
345 alc_dyn_adc_pcm_resetup(codec, idx); 367 alc_dyn_adc_pcm_resetup(codec, idx);
@@ -368,6 +390,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
368 AC_VERB_SET_CONNECT_SEL, 390 AC_VERB_SET_CONNECT_SEL,
369 imux->items[idx].index); 391 imux->items[idx].index);
370 } 392 }
393 alc_inv_dmic_sync(codec, true);
371 return 1; 394 return 1;
372} 395}
373 396
@@ -664,7 +687,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
664} 687}
665 688
666/* unsolicited event for HP jack sensing */ 689/* unsolicited event for HP jack sensing */
667static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 690static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
668{ 691{
669 int action; 692 int action;
670 693
@@ -1000,11 +1023,9 @@ static void alc_init_automute(struct hda_codec *codec)
1000 spec->automute_lo = spec->automute_lo_possible; 1023 spec->automute_lo = spec->automute_lo_possible;
1001 spec->automute_speaker = spec->automute_speaker_possible; 1024 spec->automute_speaker = spec->automute_speaker_possible;
1002 1025
1003 if (spec->automute_speaker_possible || spec->automute_lo_possible) { 1026 if (spec->automute_speaker_possible || spec->automute_lo_possible)
1004 /* create a control for automute mode */ 1027 /* create a control for automute mode */
1005 alc_add_automute_mode_enum(codec); 1028 alc_add_automute_mode_enum(codec);
1006 spec->unsol_event = alc_sku_unsol_event;
1007 }
1008} 1029}
1009 1030
1010/* return the position of NID in the list, or -1 if not found */ 1031/* return the position of NID in the list, or -1 if not found */
@@ -1167,7 +1188,6 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1167 1188
1168 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1189 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1169 ext, fixed, dock); 1190 ext, fixed, dock);
1170 spec->unsol_event = alc_sku_unsol_event;
1171} 1191}
1172 1192
1173/* check the availabilities of auto-mute and auto-mic switches */ 1193/* check the availabilities of auto-mute and auto-mic switches */
@@ -1556,14 +1576,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1556 1576
1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1577static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558 struct snd_ctl_elem_value *ucontrol, 1578 struct snd_ctl_elem_value *ucontrol,
1559 getput_call_t func, bool check_adc_switch) 1579 getput_call_t func, bool is_put)
1560{ 1580{
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1581 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct alc_spec *spec = codec->spec; 1582 struct alc_spec *spec = codec->spec;
1563 int i, err = 0; 1583 int i, err = 0;
1564 1584
1565 mutex_lock(&codec->control_mutex); 1585 mutex_lock(&codec->control_mutex);
1566 if (check_adc_switch && spec->dyn_adc_switch) { 1586 if (is_put && spec->dyn_adc_switch) {
1567 for (i = 0; i < spec->num_adc_nids; i++) { 1587 for (i = 0; i < spec->num_adc_nids; i++) {
1568 kcontrol->private_value = 1588 kcontrol->private_value =
1569 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1589 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
@@ -1584,6 +1604,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1584 3, 0, HDA_INPUT); 1604 3, 0, HDA_INPUT);
1585 err = func(kcontrol, ucontrol); 1605 err = func(kcontrol, ucontrol);
1586 } 1606 }
1607 if (err >= 0 && is_put)
1608 alc_inv_dmic_sync(codec, false);
1587 error: 1609 error:
1588 mutex_unlock(&codec->control_mutex); 1610 mutex_unlock(&codec->control_mutex);
1589 return err; 1611 return err;
@@ -1676,6 +1698,116 @@ DEFINE_CAPMIX_NOSRC(2);
1676DEFINE_CAPMIX_NOSRC(3); 1698DEFINE_CAPMIX_NOSRC(3);
1677 1699
1678/* 1700/*
1701 * Inverted digital-mic handling
1702 *
1703 * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch"
1704 * gives the additional mute only to the right channel of the digital mic
1705 * capture stream. This is a workaround for avoiding the almost silence
1706 * by summing the stereo stream from some (known to be ForteMedia)
1707 * digital mic unit.
1708 *
1709 * The logic is to call alc_inv_dmic_sync() after each action (possibly)
1710 * modifying ADC amp. When the mute flag is set, it mutes the R-channel
1711 * without caching so that the cache can still keep the original value.
1712 * The cached value is then restored when the flag is set off or any other
1713 * than d-mic is used as the current input source.
1714 */
1715static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
1716{
1717 struct alc_spec *spec = codec->spec;
1718 int i;
1719
1720 if (!spec->inv_dmic_fixup)
1721 return;
1722 if (!spec->inv_dmic_muted && !force)
1723 return;
1724 for (i = 0; i < spec->num_adc_nids; i++) {
1725 int src = spec->dyn_adc_switch ? 0 : i;
1726 bool dmic_fixup = false;
1727 hda_nid_t nid;
1728 int parm, dir, v;
1729
1730 if (spec->inv_dmic_muted &&
1731 spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin)
1732 dmic_fixup = true;
1733 if (!dmic_fixup && !force)
1734 continue;
1735 if (spec->vol_in_capsrc) {
1736 nid = spec->capsrc_nids[i];
1737 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT;
1738 dir = HDA_OUTPUT;
1739 } else {
1740 nid = spec->adc_nids[i];
1741 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT;
1742 dir = HDA_INPUT;
1743 }
1744 /* we care only right channel */
1745 v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
1746 if (v & 0x80) /* if already muted, we don't need to touch */
1747 continue;
1748 if (dmic_fixup) /* add mute for d-mic */
1749 v |= 0x80;
1750 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1751 parm | v);
1752 }
1753}
1754
1755static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
1756 struct snd_ctl_elem_value *ucontrol)
1757{
1758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1759 struct alc_spec *spec = codec->spec;
1760
1761 ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
1762 return 0;
1763}
1764
1765static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
1766 struct snd_ctl_elem_value *ucontrol)
1767{
1768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1769 struct alc_spec *spec = codec->spec;
1770 unsigned int val = !ucontrol->value.integer.value[0];
1771
1772 if (val == spec->inv_dmic_muted)
1773 return 0;
1774 spec->inv_dmic_muted = val;
1775 alc_inv_dmic_sync(codec, true);
1776 return 0;
1777}
1778
1779static const struct snd_kcontrol_new alc_inv_dmic_sw = {
1780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1781 .info = snd_ctl_boolean_mono_info,
1782 .get = alc_inv_dmic_sw_get,
1783 .put = alc_inv_dmic_sw_put,
1784};
1785
1786static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
1787{
1788 struct alc_spec *spec = codec->spec;
1789 struct snd_kcontrol_new *knew = alc_kcontrol_new(spec);
1790 if (!knew)
1791 return -ENOMEM;
1792 *knew = alc_inv_dmic_sw;
1793 knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL);
1794 if (!knew->name)
1795 return -ENOMEM;
1796 spec->inv_dmic_fixup = 1;
1797 spec->inv_dmic_muted = 0;
1798 spec->inv_dmic_pin = nid;
1799 return 0;
1800}
1801
1802/* typically the digital mic is put at node 0x12 */
1803static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
1804 const struct alc_fixup *fix, int action)
1805{
1806 if (action == ALC_FIXUP_ACT_PROBE)
1807 alc_add_inv_dmic_mixer(codec, 0x12);
1808}
1809
1810/*
1679 * virtual master controls 1811 * virtual master controls
1680 */ 1812 */
1681 1813
@@ -1865,13 +1997,31 @@ static int __alc_build_controls(struct hda_codec *codec)
1865 return 0; 1997 return 0;
1866} 1998}
1867 1999
1868static int alc_build_controls(struct hda_codec *codec) 2000static int alc_build_jacks(struct hda_codec *codec)
1869{ 2001{
1870 struct alc_spec *spec = codec->spec; 2002 struct alc_spec *spec = codec->spec;
2003
2004 if (spec->shared_mic_hp) {
2005 int err;
2006 int nid = spec->autocfg.inputs[1].pin;
2007 err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0);
2008 if (err < 0)
2009 return err;
2010 err = snd_hda_jack_detect_enable(codec, nid, 0);
2011 if (err < 0)
2012 return err;
2013 }
2014
2015 return snd_hda_jack_add_kctls(codec, &spec->autocfg);
2016}
2017
2018static int alc_build_controls(struct hda_codec *codec)
2019{
1871 int err = __alc_build_controls(codec); 2020 int err = __alc_build_controls(codec);
1872 if (err < 0) 2021 if (err < 0)
1873 return err; 2022 return err;
1874 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 2023
2024 err = alc_build_jacks(codec);
1875 if (err < 0) 2025 if (err < 0)
1876 return err; 2026 return err;
1877 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); 2027 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
@@ -1908,14 +2058,6 @@ static int alc_init(struct hda_codec *codec)
1908 return 0; 2058 return 0;
1909} 2059}
1910 2060
1911static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1912{
1913 struct alc_spec *spec = codec->spec;
1914
1915 if (spec->unsol_event)
1916 spec->unsol_event(codec, res);
1917}
1918
1919#ifdef CONFIG_SND_HDA_POWER_SAVE 2061#ifdef CONFIG_SND_HDA_POWER_SAVE
1920static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2062static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1921{ 2063{
@@ -2300,7 +2442,7 @@ static void alc_power_eapd(struct hda_codec *codec)
2300 alc_auto_setup_eapd(codec, false); 2442 alc_auto_setup_eapd(codec, false);
2301} 2443}
2302 2444
2303static int alc_suspend(struct hda_codec *codec, pm_message_t state) 2445static int alc_suspend(struct hda_codec *codec)
2304{ 2446{
2305 struct alc_spec *spec = codec->spec; 2447 struct alc_spec *spec = codec->spec;
2306 alc_shutup(codec); 2448 alc_shutup(codec);
@@ -2317,6 +2459,7 @@ static int alc_resume(struct hda_codec *codec)
2317 codec->patch_ops.init(codec); 2459 codec->patch_ops.init(codec);
2318 snd_hda_codec_resume_amp(codec); 2460 snd_hda_codec_resume_amp(codec);
2319 snd_hda_codec_resume_cache(codec); 2461 snd_hda_codec_resume_cache(codec);
2462 alc_inv_dmic_sync(codec, true);
2320 hda_call_check_power_status(codec, 0x01); 2463 hda_call_check_power_status(codec, 0x01);
2321 return 0; 2464 return 0;
2322} 2465}
@@ -4116,14 +4259,12 @@ static void set_capture_mixer(struct hda_codec *codec)
4116 */ 4259 */
4117static void alc_auto_init_std(struct hda_codec *codec) 4260static void alc_auto_init_std(struct hda_codec *codec)
4118{ 4261{
4119 struct alc_spec *spec = codec->spec;
4120 alc_auto_init_multi_out(codec); 4262 alc_auto_init_multi_out(codec);
4121 alc_auto_init_extra_out(codec); 4263 alc_auto_init_extra_out(codec);
4122 alc_auto_init_analog_input(codec); 4264 alc_auto_init_analog_input(codec);
4123 alc_auto_init_input_src(codec); 4265 alc_auto_init_input_src(codec);
4124 alc_auto_init_digital(codec); 4266 alc_auto_init_digital(codec);
4125 if (spec->unsol_event) 4267 alc_inithook(codec);
4126 alc_inithook(codec);
4127} 4268}
4128 4269
4129/* 4270/*
@@ -4724,7 +4865,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4724 spec->automute_speaker = 1; 4865 spec->automute_speaker = 1;
4725 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 4866 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4726 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); 4867 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4727 spec->unsol_event = alc_sku_unsol_event;
4728 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); 4868 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
4729 } 4869 }
4730} 4870}
@@ -4909,6 +5049,7 @@ enum {
4909 ALC889_FIXUP_DAC_ROUTE, 5049 ALC889_FIXUP_DAC_ROUTE,
4910 ALC889_FIXUP_MBP_VREF, 5050 ALC889_FIXUP_MBP_VREF,
4911 ALC889_FIXUP_IMAC91_VREF, 5051 ALC889_FIXUP_IMAC91_VREF,
5052 ALC882_FIXUP_INV_DMIC,
4912}; 5053};
4913 5054
4914static void alc889_fixup_coef(struct hda_codec *codec, 5055static void alc889_fixup_coef(struct hda_codec *codec,
@@ -5212,6 +5353,10 @@ static const struct alc_fixup alc882_fixups[] = {
5212 .chained = true, 5353 .chained = true,
5213 .chain_id = ALC882_FIXUP_GPIO1, 5354 .chain_id = ALC882_FIXUP_GPIO1,
5214 }, 5355 },
5356 [ALC882_FIXUP_INV_DMIC] = {
5357 .type = ALC_FIXUP_FUNC,
5358 .v.func = alc_fixup_inv_dmic_0x12,
5359 },
5215}; 5360};
5216 5361
5217static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5362static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -5286,6 +5431,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = {
5286 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, 5431 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
5287 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, 5432 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
5288 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, 5433 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
5434 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
5289 {} 5435 {}
5290}; 5436};
5291 5437
@@ -5373,6 +5519,7 @@ enum {
5373 ALC262_FIXUP_LENOVO_3000, 5519 ALC262_FIXUP_LENOVO_3000,
5374 ALC262_FIXUP_BENQ, 5520 ALC262_FIXUP_BENQ,
5375 ALC262_FIXUP_BENQ_T31, 5521 ALC262_FIXUP_BENQ_T31,
5522 ALC262_FIXUP_INV_DMIC,
5376}; 5523};
5377 5524
5378static const struct alc_fixup alc262_fixups[] = { 5525static const struct alc_fixup alc262_fixups[] = {
@@ -5424,6 +5571,10 @@ static const struct alc_fixup alc262_fixups[] = {
5424 {} 5571 {}
5425 } 5572 }
5426 }, 5573 },
5574 [ALC262_FIXUP_INV_DMIC] = {
5575 .type = ALC_FIXUP_FUNC,
5576 .v.func = alc_fixup_inv_dmic_0x12,
5577 },
5427}; 5578};
5428 5579
5429static const struct snd_pci_quirk alc262_fixup_tbl[] = { 5580static const struct snd_pci_quirk alc262_fixup_tbl[] = {
@@ -5438,6 +5589,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
5438 {} 5589 {}
5439}; 5590};
5440 5591
5592static const struct alc_model_fixup alc262_fixup_models[] = {
5593 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
5594 {}
5595};
5441 5596
5442/* 5597/*
5443 */ 5598 */
@@ -5466,7 +5621,8 @@ static int patch_alc262(struct hda_codec *codec)
5466#endif 5621#endif
5467 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 5622 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
5468 5623
5469 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 5624 alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
5625 alc262_fixups);
5470 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5626 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5471 5627
5472 alc_auto_parse_customize_define(codec); 5628 alc_auto_parse_customize_define(codec);
@@ -5522,6 +5678,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = {
5522 { } 5678 { }
5523}; 5679};
5524 5680
5681enum {
5682 ALC268_FIXUP_INV_DMIC,
5683};
5684
5685static const struct alc_fixup alc268_fixups[] = {
5686 [ALC268_FIXUP_INV_DMIC] = {
5687 .type = ALC_FIXUP_FUNC,
5688 .v.func = alc_fixup_inv_dmic_0x12,
5689 },
5690};
5691
5692static const struct alc_model_fixup alc268_fixup_models[] = {
5693 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
5694 {}
5695};
5696
5525/* 5697/*
5526 * BIOS auto configuration 5698 * BIOS auto configuration
5527 */ 5699 */
@@ -5553,6 +5725,9 @@ static int patch_alc268(struct hda_codec *codec)
5553 5725
5554 spec = codec->spec; 5726 spec = codec->spec;
5555 5727
5728 alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
5729 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5730
5556 /* automatic parse from the BIOS config */ 5731 /* automatic parse from the BIOS config */
5557 err = alc268_parse_auto_config(codec); 5732 err = alc268_parse_auto_config(codec);
5558 if (err < 0) 5733 if (err < 0)
@@ -5582,6 +5757,8 @@ static int patch_alc268(struct hda_codec *codec)
5582 codec->patch_ops = alc_patch_ops; 5757 codec->patch_ops = alc_patch_ops;
5583 spec->shutup = alc_eapd_shutup; 5758 spec->shutup = alc_eapd_shutup;
5584 5759
5760 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5761
5585 return 0; 5762 return 0;
5586 5763
5587 error: 5764 error:
@@ -5704,6 +5881,15 @@ static int alc269_resume(struct hda_codec *codec)
5704} 5881}
5705#endif /* CONFIG_PM */ 5882#endif /* CONFIG_PM */
5706 5883
5884static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
5885 const struct alc_fixup *fix, int action)
5886{
5887 struct alc_spec *spec = codec->spec;
5888
5889 if (action == ALC_FIXUP_ACT_PRE_PROBE)
5890 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5891}
5892
5707static void alc269_fixup_hweq(struct hda_codec *codec, 5893static void alc269_fixup_hweq(struct hda_codec *codec,
5708 const struct alc_fixup *fix, int action) 5894 const struct alc_fixup *fix, int action)
5709{ 5895{
@@ -5810,6 +5996,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5810 } 5996 }
5811} 5997}
5812 5998
5999
5813enum { 6000enum {
5814 ALC269_FIXUP_SONY_VAIO, 6001 ALC269_FIXUP_SONY_VAIO,
5815 ALC275_FIXUP_SONY_VAIO_GPIO2, 6002 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5828,6 +6015,9 @@ enum {
5828 ALC269VB_FIXUP_AMIC, 6015 ALC269VB_FIXUP_AMIC,
5829 ALC269VB_FIXUP_DMIC, 6016 ALC269VB_FIXUP_DMIC,
5830 ALC269_FIXUP_MIC2_MUTE_LED, 6017 ALC269_FIXUP_MIC2_MUTE_LED,
6018 ALC269_FIXUP_INV_DMIC,
6019 ALC269_FIXUP_LENOVO_DOCK,
6020 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
5831}; 6021};
5832 6022
5833static const struct alc_fixup alc269_fixups[] = { 6023static const struct alc_fixup alc269_fixups[] = {
@@ -5952,12 +6142,33 @@ static const struct alc_fixup alc269_fixups[] = {
5952 .type = ALC_FIXUP_FUNC, 6142 .type = ALC_FIXUP_FUNC,
5953 .v.func = alc269_fixup_mic2_mute, 6143 .v.func = alc269_fixup_mic2_mute,
5954 }, 6144 },
6145 [ALC269_FIXUP_INV_DMIC] = {
6146 .type = ALC_FIXUP_FUNC,
6147 .v.func = alc_fixup_inv_dmic_0x12,
6148 },
6149 [ALC269_FIXUP_LENOVO_DOCK] = {
6150 .type = ALC_FIXUP_PINS,
6151 .v.pins = (const struct alc_pincfg[]) {
6152 { 0x19, 0x23a11040 }, /* dock mic */
6153 { 0x1b, 0x2121103f }, /* dock headphone */
6154 { }
6155 },
6156 .chained = true,
6157 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6158 },
6159 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
6160 .type = ALC_FIXUP_FUNC,
6161 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6162 },
5955}; 6163};
5956 6164
5957static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6165static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6166 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6167 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5958 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), 6168 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5959 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), 6169 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
5960 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6170 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
6171 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5961 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6172 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5962 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6173 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5963 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 6174 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
@@ -5975,6 +6186,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5975 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 6186 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5976 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 6187 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5977 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 6188 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
6189 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5978 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), 6190 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
5979 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6191 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
5980 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6192 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
@@ -6033,6 +6245,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6033static const struct alc_model_fixup alc269_fixup_models[] = { 6245static const struct alc_model_fixup alc269_fixup_models[] = {
6034 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, 6246 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6035 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, 6247 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
6248 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
6249 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
6250 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
6251 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
6036 {} 6252 {}
6037}; 6253};
6038 6254
@@ -6329,12 +6545,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6329 {} 6545 {}
6330}; 6546};
6331 6547
6332static const struct hda_verb alc660vd_eapd_verbs[] = {
6333 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
6334 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
6335 { }
6336};
6337
6338/* 6548/*
6339 */ 6549 */
6340static int patch_alc861vd(struct hda_codec *codec) 6550static int patch_alc861vd(struct hda_codec *codec)
@@ -6356,11 +6566,6 @@ static int patch_alc861vd(struct hda_codec *codec)
6356 if (err < 0) 6566 if (err < 0)
6357 goto error; 6567 goto error;
6358 6568
6359 if (codec->vendor_id == 0x10ec0660) {
6360 /* always turn on EAPD */
6361 snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
6362 }
6363
6364 if (!spec->no_analog) { 6569 if (!spec->no_analog) {
6365 err = snd_hda_attach_beep_device(codec, 0x23); 6570 err = snd_hda_attach_beep_device(codec, 0x23);
6366 if (err < 0) 6571 if (err < 0)
@@ -6443,6 +6648,7 @@ enum {
6443 ALC662_FIXUP_ASUS_MODE8, 6648 ALC662_FIXUP_ASUS_MODE8,
6444 ALC662_FIXUP_NO_JACK_DETECT, 6649 ALC662_FIXUP_NO_JACK_DETECT,
6445 ALC662_FIXUP_ZOTAC_Z68, 6650 ALC662_FIXUP_ZOTAC_Z68,
6651 ALC662_FIXUP_INV_DMIC,
6446}; 6652};
6447 6653
6448static const struct alc_fixup alc662_fixups[] = { 6654static const struct alc_fixup alc662_fixups[] = {
@@ -6599,12 +6805,17 @@ static const struct alc_fixup alc662_fixups[] = {
6599 { } 6805 { }
6600 } 6806 }
6601 }, 6807 },
6808 [ALC662_FIXUP_INV_DMIC] = {
6809 .type = ALC_FIXUP_FUNC,
6810 .v.func = alc_fixup_inv_dmic_0x12,
6811 },
6602}; 6812};
6603 6813
6604static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6814static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6605 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 6815 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6606 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 6816 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6607 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6817 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6818 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6608 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6819 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6609 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6820 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6610 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 6821 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
@@ -6685,6 +6896,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
6685 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 6896 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6686 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 6897 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6687 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 6898 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6899 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6688 {} 6900 {}
6689}; 6901};
6690 6902
@@ -6831,6 +7043,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
6831 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 7043 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
6832 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 7044 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
6833 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 7045 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
7046 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
6834 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 7047 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6835 .patch = patch_alc861 }, 7048 .patch = patch_alc861 },
6836 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 7049 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },