diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 972 |
1 files changed, 687 insertions, 285 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ff20048504b6..c7465053d6bb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -131,8 +131,8 @@ enum { | |||
131 | enum { | 131 | enum { |
132 | ALC269_BASIC, | 132 | ALC269_BASIC, |
133 | ALC269_QUANTA_FL1, | 133 | ALC269_QUANTA_FL1, |
134 | ALC269_ASUS_EEEPC_P703, | 134 | ALC269_ASUS_AMIC, |
135 | ALC269_ASUS_EEEPC_P901, | 135 | ALC269_ASUS_DMIC, |
136 | ALC269_FUJITSU, | 136 | ALC269_FUJITSU, |
137 | ALC269_LIFEBOOK, | 137 | ALC269_LIFEBOOK, |
138 | ALC269_AUTO, | 138 | ALC269_AUTO, |
@@ -188,6 +188,8 @@ enum { | |||
188 | ALC663_ASUS_MODE4, | 188 | ALC663_ASUS_MODE4, |
189 | ALC663_ASUS_MODE5, | 189 | ALC663_ASUS_MODE5, |
190 | ALC663_ASUS_MODE6, | 190 | ALC663_ASUS_MODE6, |
191 | ALC663_ASUS_MODE7, | ||
192 | ALC663_ASUS_MODE8, | ||
191 | ALC272_DELL, | 193 | ALC272_DELL, |
192 | ALC272_DELL_ZM1, | 194 | ALC272_DELL_ZM1, |
193 | ALC272_SAMSUNG_NC10, | 195 | ALC272_SAMSUNG_NC10, |
@@ -208,6 +210,7 @@ enum { | |||
208 | ALC885_MBP3, | 210 | ALC885_MBP3, |
209 | ALC885_MB5, | 211 | ALC885_MB5, |
210 | ALC885_IMAC24, | 212 | ALC885_IMAC24, |
213 | ALC885_IMAC91, | ||
211 | ALC883_3ST_2ch_DIG, | 214 | ALC883_3ST_2ch_DIG, |
212 | ALC883_3ST_6ch_DIG, | 215 | ALC883_3ST_6ch_DIG, |
213 | ALC883_3ST_6ch, | 216 | ALC883_3ST_6ch, |
@@ -334,6 +337,9 @@ struct alc_spec { | |||
334 | /* hooks */ | 337 | /* hooks */ |
335 | void (*init_hook)(struct hda_codec *codec); | 338 | void (*init_hook)(struct hda_codec *codec); |
336 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | 339 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); |
340 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
341 | void (*power_hook)(struct hda_codec *codec, int power); | ||
342 | #endif | ||
337 | 343 | ||
338 | /* for pin sensing */ | 344 | /* for pin sensing */ |
339 | unsigned int sense_updated: 1; | 345 | unsigned int sense_updated: 1; |
@@ -385,6 +391,7 @@ struct alc_config_preset { | |||
385 | void (*init_hook)(struct hda_codec *); | 391 | void (*init_hook)(struct hda_codec *); |
386 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 392 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
387 | struct hda_amp_list *loopbacks; | 393 | struct hda_amp_list *loopbacks; |
394 | void (*power_hook)(struct hda_codec *codec, int power); | ||
388 | #endif | 395 | #endif |
389 | }; | 396 | }; |
390 | 397 | ||
@@ -897,6 +904,7 @@ static void setup_preset(struct hda_codec *codec, | |||
897 | spec->unsol_event = preset->unsol_event; | 904 | spec->unsol_event = preset->unsol_event; |
898 | spec->init_hook = preset->init_hook; | 905 | spec->init_hook = preset->init_hook; |
899 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 906 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
907 | spec->power_hook = preset->power_hook; | ||
900 | spec->loopback.amplist = preset->loopbacks; | 908 | spec->loopback.amplist = preset->loopbacks; |
901 | #endif | 909 | #endif |
902 | 910 | ||
@@ -961,18 +969,12 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
961 | static void alc_automute_pin(struct hda_codec *codec) | 969 | static void alc_automute_pin(struct hda_codec *codec) |
962 | { | 970 | { |
963 | struct alc_spec *spec = codec->spec; | 971 | struct alc_spec *spec = codec->spec; |
964 | unsigned int present, pincap; | ||
965 | unsigned int nid = spec->autocfg.hp_pins[0]; | 972 | unsigned int nid = spec->autocfg.hp_pins[0]; |
966 | int i; | 973 | int i; |
967 | 974 | ||
968 | if (!nid) | 975 | if (!nid) |
969 | return; | 976 | return; |
970 | pincap = snd_hda_query_pin_caps(codec, nid); | 977 | spec->jack_present = snd_hda_jack_detect(codec, nid); |
971 | if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ | ||
972 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
973 | present = snd_hda_codec_read(codec, nid, 0, | ||
974 | AC_VERB_GET_PIN_SENSE, 0); | ||
975 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | ||
976 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | 978 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
977 | nid = spec->autocfg.speaker_pins[i]; | 979 | nid = spec->autocfg.speaker_pins[i]; |
978 | if (!nid) | 980 | if (!nid) |
@@ -1012,9 +1014,7 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1012 | 1014 | ||
1013 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; | 1015 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; |
1014 | 1016 | ||
1015 | present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0, | 1017 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); |
1016 | AC_VERB_GET_PIN_SENSE, 0); | ||
1017 | present &= AC_PINSENSE_PRESENCE; | ||
1018 | if (present) { | 1018 | if (present) { |
1019 | alive = &spec->ext_mic; | 1019 | alive = &spec->ext_mic; |
1020 | dead = &spec->int_mic; | 1020 | dead = &spec->int_mic; |
@@ -1402,6 +1402,17 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1402 | add_verb(codec->spec, fix->verbs); | 1402 | add_verb(codec->spec, fix->verbs); |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | static int alc_read_coef_idx(struct hda_codec *codec, | ||
1406 | unsigned int coef_idx) | ||
1407 | { | ||
1408 | unsigned int val; | ||
1409 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, | ||
1410 | coef_idx); | ||
1411 | val = snd_hda_codec_read(codec, 0x20, 0, | ||
1412 | AC_VERB_GET_PROC_COEF, 0); | ||
1413 | return val; | ||
1414 | } | ||
1415 | |||
1405 | /* | 1416 | /* |
1406 | * ALC888 | 1417 | * ALC888 |
1407 | */ | 1418 | */ |
@@ -1513,7 +1524,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1513 | static void alc_automute_amp(struct hda_codec *codec) | 1524 | static void alc_automute_amp(struct hda_codec *codec) |
1514 | { | 1525 | { |
1515 | struct alc_spec *spec = codec->spec; | 1526 | struct alc_spec *spec = codec->spec; |
1516 | unsigned int val, mute, pincap; | 1527 | unsigned int mute; |
1517 | hda_nid_t nid; | 1528 | hda_nid_t nid; |
1518 | int i; | 1529 | int i; |
1519 | 1530 | ||
@@ -1522,13 +1533,7 @@ static void alc_automute_amp(struct hda_codec *codec) | |||
1522 | nid = spec->autocfg.hp_pins[i]; | 1533 | nid = spec->autocfg.hp_pins[i]; |
1523 | if (!nid) | 1534 | if (!nid) |
1524 | break; | 1535 | break; |
1525 | pincap = snd_hda_query_pin_caps(codec, nid); | 1536 | if (snd_hda_jack_detect(codec, nid)) { |
1526 | if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ | ||
1527 | snd_hda_codec_read(codec, nid, 0, | ||
1528 | AC_VERB_SET_PIN_SENSE, 0); | ||
1529 | val = snd_hda_codec_read(codec, nid, 0, | ||
1530 | AC_VERB_GET_PIN_SENSE, 0); | ||
1531 | if (val & AC_PINSENSE_PRESENCE) { | ||
1532 | spec->jack_present = 1; | 1537 | spec->jack_present = 1; |
1533 | break; | 1538 | break; |
1534 | } | 1539 | } |
@@ -1665,9 +1670,6 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { | |||
1665 | /* some bit here disables the other DACs. Init=0x4900 */ | 1670 | /* some bit here disables the other DACs. Init=0x4900 */ |
1666 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | 1671 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, |
1667 | {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, | 1672 | {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, |
1668 | /* Enable amplifiers */ | ||
1669 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
1670 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
1671 | /* DMIC fix | 1673 | /* DMIC fix |
1672 | * This laptop has a stereo digital microphone. The mics are only 1cm apart | 1674 | * This laptop has a stereo digital microphone. The mics are only 1cm apart |
1673 | * which makes the stereo useless. However, either the mic or the ALC889 | 1675 | * which makes the stereo useless. However, either the mic or the ALC889 |
@@ -1780,12 +1782,33 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
1780 | { } /* end */ | 1782 | { } /* end */ |
1781 | }; | 1783 | }; |
1782 | 1784 | ||
1785 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { | ||
1786 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1787 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1788 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
1789 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
1790 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, | ||
1791 | HDA_OUTPUT), | ||
1792 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
1793 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
1794 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
1795 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
1796 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
1797 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
1798 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
1799 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
1800 | { } /* end */ | ||
1801 | }; | ||
1802 | |||
1803 | |||
1783 | static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) | 1804 | static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) |
1784 | { | 1805 | { |
1785 | struct alc_spec *spec = codec->spec; | 1806 | struct alc_spec *spec = codec->spec; |
1786 | 1807 | ||
1787 | spec->autocfg.hp_pins[0] = 0x15; | 1808 | spec->autocfg.hp_pins[0] = 0x15; |
1788 | spec->autocfg.speaker_pins[0] = 0x14; | 1809 | spec->autocfg.speaker_pins[0] = 0x14; |
1810 | spec->autocfg.speaker_pins[1] = 0x16; | ||
1811 | spec->autocfg.speaker_pins[2] = 0x17; | ||
1789 | } | 1812 | } |
1790 | 1813 | ||
1791 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) | 1814 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) |
@@ -1808,6 +1831,16 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
1808 | spec->autocfg.speaker_pins[2] = 0x1b; | 1831 | spec->autocfg.speaker_pins[2] = 0x1b; |
1809 | } | 1832 | } |
1810 | 1833 | ||
1834 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
1835 | static void alc889_power_eapd(struct hda_codec *codec, int power) | ||
1836 | { | ||
1837 | snd_hda_codec_write(codec, 0x14, 0, | ||
1838 | AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); | ||
1839 | snd_hda_codec_write(codec, 0x15, 0, | ||
1840 | AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); | ||
1841 | } | ||
1842 | #endif | ||
1843 | |||
1811 | /* | 1844 | /* |
1812 | * ALC880 3-stack model | 1845 | * ALC880 3-stack model |
1813 | * | 1846 | * |
@@ -2401,6 +2434,8 @@ static const char *alc_slave_sws[] = { | |||
2401 | "Speaker Playback Switch", | 2434 | "Speaker Playback Switch", |
2402 | "Mono Playback Switch", | 2435 | "Mono Playback Switch", |
2403 | "IEC958 Playback Switch", | 2436 | "IEC958 Playback Switch", |
2437 | "Line-Out Playback Switch", | ||
2438 | "PCM Playback Switch", | ||
2404 | NULL, | 2439 | NULL, |
2405 | }; | 2440 | }; |
2406 | 2441 | ||
@@ -2410,12 +2445,14 @@ static const char *alc_slave_sws[] = { | |||
2410 | 2445 | ||
2411 | static void alc_free_kctls(struct hda_codec *codec); | 2446 | static void alc_free_kctls(struct hda_codec *codec); |
2412 | 2447 | ||
2448 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2413 | /* additional beep mixers; the actual parameters are overwritten at build */ | 2449 | /* additional beep mixers; the actual parameters are overwritten at build */ |
2414 | static struct snd_kcontrol_new alc_beep_mixer[] = { | 2450 | static struct snd_kcontrol_new alc_beep_mixer[] = { |
2415 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), | 2451 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), |
2416 | HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT), | 2452 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), |
2417 | { } /* end */ | 2453 | { } /* end */ |
2418 | }; | 2454 | }; |
2455 | #endif | ||
2419 | 2456 | ||
2420 | static int alc_build_controls(struct hda_codec *codec) | 2457 | static int alc_build_controls(struct hda_codec *codec) |
2421 | { | 2458 | { |
@@ -2452,6 +2489,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2452 | return err; | 2489 | return err; |
2453 | } | 2490 | } |
2454 | 2491 | ||
2492 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2455 | /* create beep controls if needed */ | 2493 | /* create beep controls if needed */ |
2456 | if (spec->beep_amp) { | 2494 | if (spec->beep_amp) { |
2457 | struct snd_kcontrol_new *knew; | 2495 | struct snd_kcontrol_new *knew; |
@@ -2461,11 +2499,13 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2461 | if (!kctl) | 2499 | if (!kctl) |
2462 | return -ENOMEM; | 2500 | return -ENOMEM; |
2463 | kctl->private_value = spec->beep_amp; | 2501 | kctl->private_value = spec->beep_amp; |
2464 | err = snd_hda_ctl_add(codec, kctl); | 2502 | err = snd_hda_ctl_add(codec, |
2503 | get_amp_nid_(spec->beep_amp), kctl); | ||
2465 | if (err < 0) | 2504 | if (err < 0) |
2466 | return err; | 2505 | return err; |
2467 | } | 2506 | } |
2468 | } | 2507 | } |
2508 | #endif | ||
2469 | 2509 | ||
2470 | /* if we have no master control, let's create it */ | 2510 | /* if we have no master control, let's create it */ |
2471 | if (!spec->no_analog && | 2511 | if (!spec->no_analog && |
@@ -2779,8 +2819,7 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec) | |||
2779 | unsigned int present; | 2819 | unsigned int present; |
2780 | unsigned char bits; | 2820 | unsigned char bits; |
2781 | 2821 | ||
2782 | present = snd_hda_codec_read(codec, 0x18, 0, | 2822 | present = snd_hda_jack_detect(codec, 0x18); |
2783 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
2784 | bits = present ? HDA_AMP_MUTE : 0; | 2823 | bits = present ? HDA_AMP_MUTE : 0; |
2785 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | 2824 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); |
2786 | } | 2825 | } |
@@ -3480,7 +3519,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3480 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), | 3519 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), |
3481 | "%s Analog", codec->chip_name); | 3520 | "%s Analog", codec->chip_name); |
3482 | info->name = spec->stream_name_analog; | 3521 | info->name = spec->stream_name_analog; |
3483 | 3522 | ||
3484 | if (spec->stream_analog_playback) { | 3523 | if (spec->stream_analog_playback) { |
3485 | if (snd_BUG_ON(!spec->multiout.dac_nids)) | 3524 | if (snd_BUG_ON(!spec->multiout.dac_nids)) |
3486 | return -EINVAL; | 3525 | return -EINVAL; |
@@ -3595,12 +3634,29 @@ static void alc_free(struct hda_codec *codec) | |||
3595 | snd_hda_detach_beep_device(codec); | 3634 | snd_hda_detach_beep_device(codec); |
3596 | } | 3635 | } |
3597 | 3636 | ||
3637 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3638 | static int alc_suspend(struct hda_codec *codec, pm_message_t state) | ||
3639 | { | ||
3640 | struct alc_spec *spec = codec->spec; | ||
3641 | if (spec && spec->power_hook) | ||
3642 | spec->power_hook(codec, 0); | ||
3643 | return 0; | ||
3644 | } | ||
3645 | #endif | ||
3646 | |||
3598 | #ifdef SND_HDA_NEEDS_RESUME | 3647 | #ifdef SND_HDA_NEEDS_RESUME |
3599 | static int alc_resume(struct hda_codec *codec) | 3648 | static int alc_resume(struct hda_codec *codec) |
3600 | { | 3649 | { |
3650 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3651 | struct alc_spec *spec = codec->spec; | ||
3652 | #endif | ||
3601 | codec->patch_ops.init(codec); | 3653 | codec->patch_ops.init(codec); |
3602 | snd_hda_codec_resume_amp(codec); | 3654 | snd_hda_codec_resume_amp(codec); |
3603 | snd_hda_codec_resume_cache(codec); | 3655 | snd_hda_codec_resume_cache(codec); |
3656 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3657 | if (spec && spec->power_hook) | ||
3658 | spec->power_hook(codec, 1); | ||
3659 | #endif | ||
3604 | return 0; | 3660 | return 0; |
3605 | } | 3661 | } |
3606 | #endif | 3662 | #endif |
@@ -3617,6 +3673,7 @@ static struct hda_codec_ops alc_patch_ops = { | |||
3617 | .resume = alc_resume, | 3673 | .resume = alc_resume, |
3618 | #endif | 3674 | #endif |
3619 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3675 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3676 | .suspend = alc_suspend, | ||
3620 | .check_power_status = alc_check_power_status, | 3677 | .check_power_status = alc_check_power_status, |
3621 | #endif | 3678 | #endif |
3622 | }; | 3679 | }; |
@@ -4322,10 +4379,26 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
4322 | knew->name = kstrdup(name, GFP_KERNEL); | 4379 | knew->name = kstrdup(name, GFP_KERNEL); |
4323 | if (!knew->name) | 4380 | if (!knew->name) |
4324 | return -ENOMEM; | 4381 | return -ENOMEM; |
4382 | if (get_amp_nid_(val)) | ||
4383 | knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); | ||
4325 | knew->private_value = val; | 4384 | knew->private_value = val; |
4326 | return 0; | 4385 | return 0; |
4327 | } | 4386 | } |
4328 | 4387 | ||
4388 | static int add_control_with_pfx(struct alc_spec *spec, int type, | ||
4389 | const char *pfx, const char *dir, | ||
4390 | const char *sfx, unsigned long val) | ||
4391 | { | ||
4392 | char name[32]; | ||
4393 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); | ||
4394 | return add_control(spec, type, name, val); | ||
4395 | } | ||
4396 | |||
4397 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ | ||
4398 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) | ||
4399 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ | ||
4400 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) | ||
4401 | |||
4329 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) | 4402 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) |
4330 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) | 4403 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) |
4331 | #define alc880_is_multi_pin(nid) ((nid) >= 0x18) | 4404 | #define alc880_is_multi_pin(nid) ((nid) >= 0x18) |
@@ -4379,7 +4452,6 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, | |||
4379 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | 4452 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, |
4380 | const struct auto_pin_cfg *cfg) | 4453 | const struct auto_pin_cfg *cfg) |
4381 | { | 4454 | { |
4382 | char name[32]; | ||
4383 | static const char *chname[4] = { | 4455 | static const char *chname[4] = { |
4384 | "Front", "Surround", NULL /*CLFE*/, "Side" | 4456 | "Front", "Surround", NULL /*CLFE*/, "Side" |
4385 | }; | 4457 | }; |
@@ -4392,26 +4464,26 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
4392 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | 4464 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); |
4393 | if (i == 2) { | 4465 | if (i == 2) { |
4394 | /* Center/LFE */ | 4466 | /* Center/LFE */ |
4395 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 4467 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
4396 | "Center Playback Volume", | 4468 | "Center", |
4397 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | 4469 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, |
4398 | HDA_OUTPUT)); | 4470 | HDA_OUTPUT)); |
4399 | if (err < 0) | 4471 | if (err < 0) |
4400 | return err; | 4472 | return err; |
4401 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 4473 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
4402 | "LFE Playback Volume", | 4474 | "LFE", |
4403 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | 4475 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, |
4404 | HDA_OUTPUT)); | 4476 | HDA_OUTPUT)); |
4405 | if (err < 0) | 4477 | if (err < 0) |
4406 | return err; | 4478 | return err; |
4407 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 4479 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
4408 | "Center Playback Switch", | 4480 | "Center", |
4409 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | 4481 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, |
4410 | HDA_INPUT)); | 4482 | HDA_INPUT)); |
4411 | if (err < 0) | 4483 | if (err < 0) |
4412 | return err; | 4484 | return err; |
4413 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 4485 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
4414 | "LFE Playback Switch", | 4486 | "LFE", |
4415 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | 4487 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, |
4416 | HDA_INPUT)); | 4488 | HDA_INPUT)); |
4417 | if (err < 0) | 4489 | if (err < 0) |
@@ -4423,14 +4495,12 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
4423 | pfx = "Speaker"; | 4495 | pfx = "Speaker"; |
4424 | else | 4496 | else |
4425 | pfx = chname[i]; | 4497 | pfx = chname[i]; |
4426 | sprintf(name, "%s Playback Volume", pfx); | 4498 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, |
4427 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
4428 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | 4499 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
4429 | HDA_OUTPUT)); | 4500 | HDA_OUTPUT)); |
4430 | if (err < 0) | 4501 | if (err < 0) |
4431 | return err; | 4502 | return err; |
4432 | sprintf(name, "%s Playback Switch", pfx); | 4503 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, |
4433 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
4434 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | 4504 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, |
4435 | HDA_INPUT)); | 4505 | HDA_INPUT)); |
4436 | if (err < 0) | 4506 | if (err < 0) |
@@ -4446,7 +4516,6 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
4446 | { | 4516 | { |
4447 | hda_nid_t nid; | 4517 | hda_nid_t nid; |
4448 | int err; | 4518 | int err; |
4449 | char name[32]; | ||
4450 | 4519 | ||
4451 | if (!pin) | 4520 | if (!pin) |
4452 | return 0; | 4521 | return 0; |
@@ -4460,21 +4529,18 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
4460 | spec->multiout.extra_out_nid[0] = nid; | 4529 | spec->multiout.extra_out_nid[0] = nid; |
4461 | /* control HP volume/switch on the output mixer amp */ | 4530 | /* control HP volume/switch on the output mixer amp */ |
4462 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | 4531 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); |
4463 | sprintf(name, "%s Playback Volume", pfx); | 4532 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, |
4464 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
4465 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 4533 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); |
4466 | if (err < 0) | 4534 | if (err < 0) |
4467 | return err; | 4535 | return err; |
4468 | sprintf(name, "%s Playback Switch", pfx); | 4536 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, |
4469 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
4470 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); | 4537 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); |
4471 | if (err < 0) | 4538 | if (err < 0) |
4472 | return err; | 4539 | return err; |
4473 | } else if (alc880_is_multi_pin(pin)) { | 4540 | } else if (alc880_is_multi_pin(pin)) { |
4474 | /* set manual connection */ | 4541 | /* set manual connection */ |
4475 | /* we have only a switch on HP-out PIN */ | 4542 | /* we have only a switch on HP-out PIN */ |
4476 | sprintf(name, "%s Playback Switch", pfx); | 4543 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, |
4477 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
4478 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | 4544 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
4479 | if (err < 0) | 4545 | if (err < 0) |
4480 | return err; | 4546 | return err; |
@@ -4487,16 +4553,13 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | |||
4487 | const char *ctlname, | 4553 | const char *ctlname, |
4488 | int idx, hda_nid_t mix_nid) | 4554 | int idx, hda_nid_t mix_nid) |
4489 | { | 4555 | { |
4490 | char name[32]; | ||
4491 | int err; | 4556 | int err; |
4492 | 4557 | ||
4493 | sprintf(name, "%s Playback Volume", ctlname); | 4558 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, |
4494 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
4495 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 4559 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4496 | if (err < 0) | 4560 | if (err < 0) |
4497 | return err; | 4561 | return err; |
4498 | sprintf(name, "%s Playback Switch", ctlname); | 4562 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, |
4499 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
4500 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 4563 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
4501 | if (err < 0) | 4564 | if (err < 0) |
4502 | return err; | 4565 | return err; |
@@ -4684,9 +4747,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4684 | spec->multiout.dig_out_nid = dig_nid; | 4747 | spec->multiout.dig_out_nid = dig_nid; |
4685 | else { | 4748 | else { |
4686 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | 4749 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; |
4687 | spec->slave_dig_outs[i - 1] = dig_nid; | 4750 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) |
4688 | if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
4689 | break; | 4751 | break; |
4752 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
4690 | } | 4753 | } |
4691 | } | 4754 | } |
4692 | if (spec->autocfg.dig_in_pin) | 4755 | if (spec->autocfg.dig_in_pin) |
@@ -4773,8 +4836,12 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4773 | } | 4836 | } |
4774 | } | 4837 | } |
4775 | 4838 | ||
4839 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
4776 | #define set_beep_amp(spec, nid, idx, dir) \ | 4840 | #define set_beep_amp(spec, nid, idx, dir) \ |
4777 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 4841 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
4842 | #else | ||
4843 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
4844 | #endif | ||
4778 | 4845 | ||
4779 | /* | 4846 | /* |
4780 | * OK, here we have finally the patch for ALC880 | 4847 | * OK, here we have finally the patch for ALC880 |
@@ -5087,11 +5154,8 @@ static struct hda_verb alc260_hp_unsol_verbs[] = { | |||
5087 | static void alc260_hp_automute(struct hda_codec *codec) | 5154 | static void alc260_hp_automute(struct hda_codec *codec) |
5088 | { | 5155 | { |
5089 | struct alc_spec *spec = codec->spec; | 5156 | struct alc_spec *spec = codec->spec; |
5090 | unsigned int present; | ||
5091 | 5157 | ||
5092 | present = snd_hda_codec_read(codec, 0x10, 0, | 5158 | spec->jack_present = snd_hda_jack_detect(codec, 0x10); |
5093 | AC_VERB_GET_PIN_SENSE, 0); | ||
5094 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | ||
5095 | alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); | 5159 | alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); |
5096 | } | 5160 | } |
5097 | 5161 | ||
@@ -5156,11 +5220,8 @@ static struct hda_verb alc260_hp_3013_unsol_verbs[] = { | |||
5156 | static void alc260_hp_3013_automute(struct hda_codec *codec) | 5220 | static void alc260_hp_3013_automute(struct hda_codec *codec) |
5157 | { | 5221 | { |
5158 | struct alc_spec *spec = codec->spec; | 5222 | struct alc_spec *spec = codec->spec; |
5159 | unsigned int present; | ||
5160 | 5223 | ||
5161 | present = snd_hda_codec_read(codec, 0x15, 0, | 5224 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); |
5162 | AC_VERB_GET_PIN_SENSE, 0); | ||
5163 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | ||
5164 | alc260_hp_master_update(codec, 0x15, 0x10, 0x11); | 5225 | alc260_hp_master_update(codec, 0x15, 0x10, 0x11); |
5165 | } | 5226 | } |
5166 | 5227 | ||
@@ -5173,12 +5234,8 @@ static void alc260_hp_3013_unsol_event(struct hda_codec *codec, | |||
5173 | 5234 | ||
5174 | static void alc260_hp_3012_automute(struct hda_codec *codec) | 5235 | static void alc260_hp_3012_automute(struct hda_codec *codec) |
5175 | { | 5236 | { |
5176 | unsigned int present, bits; | 5237 | unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; |
5177 | |||
5178 | present = snd_hda_codec_read(codec, 0x10, 0, | ||
5179 | AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; | ||
5180 | 5238 | ||
5181 | bits = present ? 0 : PIN_OUT; | ||
5182 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 5239 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
5183 | bits); | 5240 | bits); |
5184 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 5241 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
@@ -5748,8 +5805,7 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec) | |||
5748 | unsigned int present; | 5805 | unsigned int present; |
5749 | 5806 | ||
5750 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | 5807 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ |
5751 | present = snd_hda_codec_read(codec, 0x0f, 0, | 5808 | present = snd_hda_jack_detect(codec, 0x0f); |
5752 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5753 | if (present) { | 5809 | if (present) { |
5754 | snd_hda_codec_write_cache(codec, 0x01, 0, | 5810 | snd_hda_codec_write_cache(codec, 0x01, 0, |
5755 | AC_VERB_SET_GPIO_DATA, 1); | 5811 | AC_VERB_SET_GPIO_DATA, 1); |
@@ -5989,7 +6045,6 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | |||
5989 | { | 6045 | { |
5990 | hda_nid_t nid_vol; | 6046 | hda_nid_t nid_vol; |
5991 | unsigned long vol_val, sw_val; | 6047 | unsigned long vol_val, sw_val; |
5992 | char name[32]; | ||
5993 | int err; | 6048 | int err; |
5994 | 6049 | ||
5995 | if (nid >= 0x0f && nid < 0x11) { | 6050 | if (nid >= 0x0f && nid < 0x11) { |
@@ -6009,14 +6064,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | |||
6009 | 6064 | ||
6010 | if (!(*vol_bits & (1 << nid_vol))) { | 6065 | if (!(*vol_bits & (1 << nid_vol))) { |
6011 | /* first control for the volume widget */ | 6066 | /* first control for the volume widget */ |
6012 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | 6067 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); |
6013 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); | ||
6014 | if (err < 0) | 6068 | if (err < 0) |
6015 | return err; | 6069 | return err; |
6016 | *vol_bits |= (1 << nid_vol); | 6070 | *vol_bits |= (1 << nid_vol); |
6017 | } | 6071 | } |
6018 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | 6072 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); |
6019 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); | ||
6020 | if (err < 0) | 6073 | if (err < 0) |
6021 | return err; | 6074 | return err; |
6022 | return 1; | 6075 | return 1; |
@@ -6246,10 +6299,11 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { | |||
6246 | 6299 | ||
6247 | static struct snd_pci_quirk alc260_cfg_tbl[] = { | 6300 | static struct snd_pci_quirk alc260_cfg_tbl[] = { |
6248 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | 6301 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), |
6302 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), | ||
6249 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | 6303 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), |
6250 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), | 6304 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), |
6251 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), | 6305 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), |
6252 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), | 6306 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ |
6253 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | 6307 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), |
6254 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), | 6308 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), |
6255 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), | 6309 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), |
@@ -6619,7 +6673,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = { | |||
6619 | /* Front Mic (0x01) unused */ | 6673 | /* Front Mic (0x01) unused */ |
6620 | { "Line", 0x2 }, | 6674 | { "Line", 0x2 }, |
6621 | /* Line 2 (0x03) unused */ | 6675 | /* Line 2 (0x03) unused */ |
6622 | /* CD (0x04) unsused? */ | 6676 | /* CD (0x04) unused? */ |
6623 | }, | 6677 | }, |
6624 | }; | 6678 | }; |
6625 | 6679 | ||
@@ -7051,6 +7105,20 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { | |||
7051 | { } /* end */ | 7105 | { } /* end */ |
7052 | }; | 7106 | }; |
7053 | 7107 | ||
7108 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { | ||
7109 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
7110 | HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
7111 | HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), | ||
7112 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
7113 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7114 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7115 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
7116 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
7117 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
7118 | { } /* end */ | ||
7119 | }; | ||
7120 | |||
7121 | |||
7054 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | 7122 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { |
7055 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7123 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
7056 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 7124 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -7336,8 +7404,8 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = { | |||
7336 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | 7404 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), |
7337 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | 7405 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), |
7338 | /* FIXME: this looks suspicious... | 7406 | /* FIXME: this looks suspicious... |
7339 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), | 7407 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), |
7340 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), | 7408 | HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), |
7341 | */ | 7409 | */ |
7342 | { } /* end */ | 7410 | { } /* end */ |
7343 | }; | 7411 | }; |
@@ -7506,6 +7574,66 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { | |||
7506 | { } | 7574 | { } |
7507 | }; | 7575 | }; |
7508 | 7576 | ||
7577 | /* iMac 9,1 */ | ||
7578 | static struct hda_verb alc885_imac91_init_verbs[] = { | ||
7579 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | ||
7580 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7581 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7582 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7583 | /* Rear mixer */ | ||
7584 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7585 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7586 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7587 | /* HP Pin: output 0 (0x0c) */ | ||
7588 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
7589 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7590 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7591 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
7592 | /* Internal Speakers: output 0 (0x0d) */ | ||
7593 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7594 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7595 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7596 | /* Mic (rear) pin: input vref at 80% */ | ||
7597 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7598 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7599 | /* Front Mic pin: input vref at 80% */ | ||
7600 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7601 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7602 | /* Line In pin: use output 1 when in LineOut mode */ | ||
7603 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
7604 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7605 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
7606 | |||
7607 | /* FIXME: use matrix-type input source selection */ | ||
7608 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
7609 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
7610 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7611 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7612 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7613 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7614 | /* Input mixer2 */ | ||
7615 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7616 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7617 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7618 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7619 | /* Input mixer3 */ | ||
7620 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7621 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7622 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7623 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7624 | /* ADC1: mute amp left and right */ | ||
7625 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7626 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7627 | /* ADC2: mute amp left and right */ | ||
7628 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7629 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7630 | /* ADC3: mute amp left and right */ | ||
7631 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7632 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7633 | |||
7634 | { } | ||
7635 | }; | ||
7636 | |||
7509 | /* iMac 24 mixer. */ | 7637 | /* iMac 24 mixer. */ |
7510 | static struct snd_kcontrol_new alc885_imac24_mixer[] = { | 7638 | static struct snd_kcontrol_new alc885_imac24_mixer[] = { |
7511 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 7639 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
@@ -7552,6 +7680,26 @@ static void alc885_mbp3_setup(struct hda_codec *codec) | |||
7552 | spec->autocfg.speaker_pins[0] = 0x14; | 7680 | spec->autocfg.speaker_pins[0] = 0x14; |
7553 | } | 7681 | } |
7554 | 7682 | ||
7683 | static void alc885_imac91_automute(struct hda_codec *codec) | ||
7684 | { | ||
7685 | unsigned int present; | ||
7686 | |||
7687 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
7688 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
7689 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
7690 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
7691 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, | ||
7692 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
7693 | |||
7694 | } | ||
7695 | |||
7696 | static void alc885_imac91_unsol_event(struct hda_codec *codec, | ||
7697 | unsigned int res) | ||
7698 | { | ||
7699 | /* Headphone insertion or removal. */ | ||
7700 | if ((res >> 26) == ALC880_HP_EVENT) | ||
7701 | alc885_imac91_automute(codec); | ||
7702 | } | ||
7555 | 7703 | ||
7556 | static struct hda_verb alc882_targa_verbs[] = { | 7704 | static struct hda_verb alc882_targa_verbs[] = { |
7557 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7705 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -8184,12 +8332,8 @@ static void alc883_mitac_setup(struct hda_codec *codec) | |||
8184 | /* | 8332 | /* |
8185 | static void alc883_mitac_mic_automute(struct hda_codec *codec) | 8333 | static void alc883_mitac_mic_automute(struct hda_codec *codec) |
8186 | { | 8334 | { |
8187 | unsigned int present; | 8335 | unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; |
8188 | unsigned char bits; | ||
8189 | 8336 | ||
8190 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
8191 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8192 | bits = present ? HDA_AMP_MUTE : 0; | ||
8193 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | 8337 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); |
8194 | } | 8338 | } |
8195 | */ | 8339 | */ |
@@ -8411,10 +8555,8 @@ static struct hda_channel_mode alc888_3st_hp_modes[3] = { | |||
8411 | /* toggle front-jack and RCA according to the hp-jack state */ | 8555 | /* toggle front-jack and RCA according to the hp-jack state */ |
8412 | static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) | 8556 | static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) |
8413 | { | 8557 | { |
8414 | unsigned int present; | 8558 | unsigned int present = snd_hda_jack_detect(codec, 0x1b); |
8415 | 8559 | ||
8416 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8417 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8418 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8560 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, |
8419 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8561 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8420 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8562 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
@@ -8424,10 +8566,8 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) | |||
8424 | /* toggle RCA according to the front-jack state */ | 8566 | /* toggle RCA according to the front-jack state */ |
8425 | static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) | 8567 | static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) |
8426 | { | 8568 | { |
8427 | unsigned int present; | 8569 | unsigned int present = snd_hda_jack_detect(codec, 0x14); |
8428 | 8570 | ||
8429 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
8430 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8431 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8571 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
8432 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8572 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8433 | } | 8573 | } |
@@ -8468,8 +8608,7 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | |||
8468 | { | 8608 | { |
8469 | unsigned int present; | 8609 | unsigned int present; |
8470 | 8610 | ||
8471 | present = snd_hda_codec_read(codec, 0x18, 0, | 8611 | present = snd_hda_jack_detect(codec, 0x18); |
8472 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8473 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, | 8612 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, |
8474 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8613 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8475 | } | 8614 | } |
@@ -8520,24 +8659,16 @@ static void alc883_haier_w66_setup(struct hda_codec *codec) | |||
8520 | 8659 | ||
8521 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 8660 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
8522 | { | 8661 | { |
8523 | unsigned int present; | 8662 | int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; |
8524 | unsigned char bits; | ||
8525 | 8663 | ||
8526 | present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
8527 | & AC_PINSENSE_PRESENCE; | ||
8528 | bits = present ? HDA_AMP_MUTE : 0; | ||
8529 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8664 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
8530 | HDA_AMP_MUTE, bits); | 8665 | HDA_AMP_MUTE, bits); |
8531 | } | 8666 | } |
8532 | 8667 | ||
8533 | static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) | 8668 | static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) |
8534 | { | 8669 | { |
8535 | unsigned int present; | 8670 | int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; |
8536 | unsigned char bits; | ||
8537 | 8671 | ||
8538 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8539 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8540 | bits = present ? HDA_AMP_MUTE : 0; | ||
8541 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8672 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
8542 | HDA_AMP_MUTE, bits); | 8673 | HDA_AMP_MUTE, bits); |
8543 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8674 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, |
@@ -8688,8 +8819,7 @@ static void alc889A_mb31_automute(struct hda_codec *codec) | |||
8688 | /* Mute only in 2ch or 4ch mode */ | 8819 | /* Mute only in 2ch or 4ch mode */ |
8689 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) | 8820 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) |
8690 | == 0x00) { | 8821 | == 0x00) { |
8691 | present = snd_hda_codec_read(codec, 0x15, 0, | 8822 | present = snd_hda_jack_detect(codec, 0x15); |
8692 | AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; | ||
8693 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8823 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, |
8694 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8824 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8695 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | 8825 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, |
@@ -8737,6 +8867,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
8737 | [ALC885_MB5] = "mb5", | 8867 | [ALC885_MB5] = "mb5", |
8738 | [ALC885_MBP3] = "mbp3", | 8868 | [ALC885_MBP3] = "mbp3", |
8739 | [ALC885_IMAC24] = "imac24", | 8869 | [ALC885_IMAC24] = "imac24", |
8870 | [ALC885_IMAC91] = "imac91", | ||
8740 | [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", | 8871 | [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", |
8741 | [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", | 8872 | [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", |
8742 | [ALC883_3ST_6ch] = "3stack-6ch", | 8873 | [ALC883_3ST_6ch] = "3stack-6ch", |
@@ -8839,7 +8970,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
8839 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), | 8970 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), |
8840 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), | 8971 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), |
8841 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ | 8972 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ |
8842 | SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), | 8973 | SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), |
8843 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), | 8974 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), |
8844 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), | 8975 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), |
8845 | SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), | 8976 | SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), |
@@ -8910,11 +9041,13 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | |||
8910 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), | 9041 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), |
8911 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), | 9042 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), |
8912 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), | 9043 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), |
9044 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), | ||
8913 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), | 9045 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), |
8914 | /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently | 9046 | /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, |
8915 | * no perfect solution yet | 9047 | * so apparently no perfect solution yet |
8916 | */ | 9048 | */ |
8917 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), | 9049 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), |
9050 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), | ||
8918 | {} /* terminator */ | 9051 | {} /* terminator */ |
8919 | }; | 9052 | }; |
8920 | 9053 | ||
@@ -9020,6 +9153,20 @@ static struct alc_config_preset alc882_presets[] = { | |||
9020 | .setup = alc885_imac24_setup, | 9153 | .setup = alc885_imac24_setup, |
9021 | .init_hook = alc885_imac24_init_hook, | 9154 | .init_hook = alc885_imac24_init_hook, |
9022 | }, | 9155 | }, |
9156 | [ALC885_IMAC91] = { | ||
9157 | .mixers = { alc885_imac91_mixer, alc882_chmode_mixer }, | ||
9158 | .init_verbs = { alc885_imac91_init_verbs, | ||
9159 | alc880_gpio1_init_verbs }, | ||
9160 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
9161 | .dac_nids = alc882_dac_nids, | ||
9162 | .channel_mode = alc885_mbp_4ch_modes, | ||
9163 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), | ||
9164 | .input_mux = &alc882_capture_source, | ||
9165 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
9166 | .dig_in_nid = ALC882_DIGIN_NID, | ||
9167 | .unsol_event = alc885_imac91_unsol_event, | ||
9168 | .init_hook = alc885_imac91_automute, | ||
9169 | }, | ||
9023 | [ALC882_TARGA] = { | 9170 | [ALC882_TARGA] = { |
9024 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, | 9171 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, |
9025 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | 9172 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, |
@@ -9186,6 +9333,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9186 | .dac_nids = alc883_dac_nids, | 9333 | .dac_nids = alc883_dac_nids, |
9187 | .adc_nids = alc883_adc_nids_alt, | 9334 | .adc_nids = alc883_adc_nids_alt, |
9188 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), | 9335 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), |
9336 | .capsrc_nids = alc883_capsrc_nids, | ||
9189 | .dig_out_nid = ALC883_DIGOUT_NID, | 9337 | .dig_out_nid = ALC883_DIGOUT_NID, |
9190 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9338 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9191 | .channel_mode = alc883_3ST_2ch_modes, | 9339 | .channel_mode = alc883_3ST_2ch_modes, |
@@ -9282,10 +9430,11 @@ static struct alc_config_preset alc882_presets[] = { | |||
9282 | .init_hook = alc_automute_amp, | 9430 | .init_hook = alc_automute_amp, |
9283 | }, | 9431 | }, |
9284 | [ALC888_ACER_ASPIRE_8930G] = { | 9432 | [ALC888_ACER_ASPIRE_8930G] = { |
9285 | .mixers = { alc888_base_mixer, | 9433 | .mixers = { alc889_acer_aspire_8930g_mixer, |
9286 | alc883_chmode_mixer }, | 9434 | alc883_chmode_mixer }, |
9287 | .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, | 9435 | .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, |
9288 | alc889_acer_aspire_8930g_verbs }, | 9436 | alc889_acer_aspire_8930g_verbs, |
9437 | alc889_eapd_verbs}, | ||
9289 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 9438 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
9290 | .dac_nids = alc883_dac_nids, | 9439 | .dac_nids = alc883_dac_nids, |
9291 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | 9440 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), |
@@ -9302,6 +9451,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
9302 | .unsol_event = alc_automute_amp_unsol_event, | 9451 | .unsol_event = alc_automute_amp_unsol_event, |
9303 | .setup = alc889_acer_aspire_8930g_setup, | 9452 | .setup = alc889_acer_aspire_8930g_setup, |
9304 | .init_hook = alc_automute_amp, | 9453 | .init_hook = alc_automute_amp, |
9454 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
9455 | .power_hook = alc889_power_eapd, | ||
9456 | #endif | ||
9305 | }, | 9457 | }, |
9306 | [ALC888_ACER_ASPIRE_7730G] = { | 9458 | [ALC888_ACER_ASPIRE_7730G] = { |
9307 | .mixers = { alc883_3ST_6ch_mixer, | 9459 | .mixers = { alc883_3ST_6ch_mixer, |
@@ -9332,6 +9484,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9332 | .dac_nids = alc883_dac_nids, | 9484 | .dac_nids = alc883_dac_nids, |
9333 | .adc_nids = alc883_adc_nids_alt, | 9485 | .adc_nids = alc883_adc_nids_alt, |
9334 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), | 9486 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), |
9487 | .capsrc_nids = alc883_capsrc_nids, | ||
9335 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | 9488 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), |
9336 | .channel_mode = alc883_sixstack_modes, | 9489 | .channel_mode = alc883_sixstack_modes, |
9337 | .input_mux = &alc883_capture_source, | 9490 | .input_mux = &alc883_capture_source, |
@@ -9393,6 +9546,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9393 | .dac_nids = alc883_dac_nids, | 9546 | .dac_nids = alc883_dac_nids, |
9394 | .adc_nids = alc883_adc_nids_alt, | 9547 | .adc_nids = alc883_adc_nids_alt, |
9395 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), | 9548 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), |
9549 | .capsrc_nids = alc883_capsrc_nids, | ||
9396 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9550 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9397 | .channel_mode = alc883_3ST_2ch_modes, | 9551 | .channel_mode = alc883_3ST_2ch_modes, |
9398 | .input_mux = &alc883_lenovo_101e_capture_source, | 9552 | .input_mux = &alc883_lenovo_101e_capture_source, |
@@ -9572,6 +9726,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9572 | alc880_gpio1_init_verbs }, | 9726 | alc880_gpio1_init_verbs }, |
9573 | .adc_nids = alc883_adc_nids, | 9727 | .adc_nids = alc883_adc_nids, |
9574 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | 9728 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), |
9729 | .capsrc_nids = alc883_capsrc_nids, | ||
9575 | .dac_nids = alc883_dac_nids, | 9730 | .dac_nids = alc883_dac_nids, |
9576 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 9731 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
9577 | .channel_mode = alc889A_mb31_6ch_modes, | 9732 | .channel_mode = alc889A_mb31_6ch_modes, |
@@ -9813,9 +9968,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
9813 | spec->multiout.dig_out_nid = dig_nid; | 9968 | spec->multiout.dig_out_nid = dig_nid; |
9814 | else { | 9969 | else { |
9815 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | 9970 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; |
9816 | spec->slave_dig_outs[i - 1] = dig_nid; | 9971 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) |
9817 | if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
9818 | break; | 9972 | break; |
9973 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
9819 | } | 9974 | } |
9820 | } | 9975 | } |
9821 | if (spec->autocfg.dig_in_pin) | 9976 | if (spec->autocfg.dig_in_pin) |
@@ -9926,10 +10081,12 @@ static int patch_alc882(struct hda_codec *codec) | |||
9926 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ | 10081 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ |
9927 | 10082 | ||
9928 | if (!spec->adc_nids && spec->input_mux) { | 10083 | if (!spec->adc_nids && spec->input_mux) { |
9929 | int i; | 10084 | int i, j; |
9930 | spec->num_adc_nids = 0; | 10085 | spec->num_adc_nids = 0; |
9931 | for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { | 10086 | for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { |
10087 | const struct hda_input_mux *imux = spec->input_mux; | ||
9932 | hda_nid_t cap; | 10088 | hda_nid_t cap; |
10089 | hda_nid_t items[16]; | ||
9933 | hda_nid_t nid = alc882_adc_nids[i]; | 10090 | hda_nid_t nid = alc882_adc_nids[i]; |
9934 | unsigned int wcap = get_wcaps(codec, nid); | 10091 | unsigned int wcap = get_wcaps(codec, nid); |
9935 | /* get type */ | 10092 | /* get type */ |
@@ -9940,6 +10097,15 @@ static int patch_alc882(struct hda_codec *codec) | |||
9940 | err = snd_hda_get_connections(codec, nid, &cap, 1); | 10097 | err = snd_hda_get_connections(codec, nid, &cap, 1); |
9941 | if (err < 0) | 10098 | if (err < 0) |
9942 | continue; | 10099 | continue; |
10100 | err = snd_hda_get_connections(codec, cap, items, | ||
10101 | ARRAY_SIZE(items)); | ||
10102 | if (err < 0) | ||
10103 | continue; | ||
10104 | for (j = 0; j < imux->num_items; j++) | ||
10105 | if (imux->items[j].index >= err) | ||
10106 | break; | ||
10107 | if (j < imux->num_items) | ||
10108 | continue; | ||
9943 | spec->private_capsrc_nids[spec->num_adc_nids] = cap; | 10109 | spec->private_capsrc_nids[spec->num_adc_nids] = cap; |
9944 | spec->num_adc_nids++; | 10110 | spec->num_adc_nids++; |
9945 | } | 10111 | } |
@@ -10031,10 +10197,8 @@ static void alc262_hp_master_update(struct hda_codec *codec) | |||
10031 | static void alc262_hp_bpc_automute(struct hda_codec *codec) | 10197 | static void alc262_hp_bpc_automute(struct hda_codec *codec) |
10032 | { | 10198 | { |
10033 | struct alc_spec *spec = codec->spec; | 10199 | struct alc_spec *spec = codec->spec; |
10034 | unsigned int presence; | 10200 | |
10035 | presence = snd_hda_codec_read(codec, 0x1b, 0, | 10201 | spec->jack_present = snd_hda_jack_detect(codec, 0x1b); |
10036 | AC_VERB_GET_PIN_SENSE, 0); | ||
10037 | spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); | ||
10038 | alc262_hp_master_update(codec); | 10202 | alc262_hp_master_update(codec); |
10039 | } | 10203 | } |
10040 | 10204 | ||
@@ -10048,10 +10212,8 @@ static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) | |||
10048 | static void alc262_hp_wildwest_automute(struct hda_codec *codec) | 10212 | static void alc262_hp_wildwest_automute(struct hda_codec *codec) |
10049 | { | 10213 | { |
10050 | struct alc_spec *spec = codec->spec; | 10214 | struct alc_spec *spec = codec->spec; |
10051 | unsigned int presence; | 10215 | |
10052 | presence = snd_hda_codec_read(codec, 0x15, 0, | 10216 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); |
10053 | AC_VERB_GET_PIN_SENSE, 0); | ||
10054 | spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); | ||
10055 | alc262_hp_master_update(codec); | 10217 | alc262_hp_master_update(codec); |
10056 | } | 10218 | } |
10057 | 10219 | ||
@@ -10285,13 +10447,8 @@ static void alc262_hippo_automute(struct hda_codec *codec) | |||
10285 | { | 10447 | { |
10286 | struct alc_spec *spec = codec->spec; | 10448 | struct alc_spec *spec = codec->spec; |
10287 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | 10449 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; |
10288 | unsigned int present; | ||
10289 | 10450 | ||
10290 | /* need to execute and sync at first */ | 10451 | spec->jack_present = snd_hda_jack_detect(codec, hp_nid); |
10291 | snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10292 | present = snd_hda_codec_read(codec, hp_nid, 0, | ||
10293 | AC_VERB_GET_PIN_SENSE, 0); | ||
10294 | spec->jack_present = (present & 0x80000000) != 0; | ||
10295 | alc262_hippo_master_update(codec); | 10452 | alc262_hippo_master_update(codec); |
10296 | } | 10453 | } |
10297 | 10454 | ||
@@ -10580,6 +10737,13 @@ static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { | |||
10580 | {} | 10737 | {} |
10581 | }; | 10738 | }; |
10582 | 10739 | ||
10740 | static struct hda_verb alc262_lenovo_3000_init_verbs[] = { | ||
10741 | /* Front Mic pin: input vref at 50% */ | ||
10742 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
10743 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
10744 | {} | ||
10745 | }; | ||
10746 | |||
10583 | static struct hda_input_mux alc262_fujitsu_capture_source = { | 10747 | static struct hda_input_mux alc262_fujitsu_capture_source = { |
10584 | .num_items = 3, | 10748 | .num_items = 3, |
10585 | .items = { | 10749 | .items = { |
@@ -10617,21 +10781,8 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | |||
10617 | unsigned int mute; | 10781 | unsigned int mute; |
10618 | 10782 | ||
10619 | if (force || !spec->sense_updated) { | 10783 | if (force || !spec->sense_updated) { |
10620 | unsigned int present; | 10784 | spec->jack_present = snd_hda_jack_detect(codec, 0x14) || |
10621 | /* need to execute and sync at first */ | 10785 | snd_hda_jack_detect(codec, 0x1b); |
10622 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10623 | /* check laptop HP jack */ | ||
10624 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
10625 | AC_VERB_GET_PIN_SENSE, 0); | ||
10626 | /* need to execute and sync at first */ | ||
10627 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10628 | /* check docking HP jack */ | ||
10629 | present |= snd_hda_codec_read(codec, 0x1b, 0, | ||
10630 | AC_VERB_GET_PIN_SENSE, 0); | ||
10631 | if (present & AC_PINSENSE_PRESENCE) | ||
10632 | spec->jack_present = 1; | ||
10633 | else | ||
10634 | spec->jack_present = 0; | ||
10635 | spec->sense_updated = 1; | 10786 | spec->sense_updated = 1; |
10636 | } | 10787 | } |
10637 | /* unmute internal speaker only if both HPs are unplugged and | 10788 | /* unmute internal speaker only if both HPs are unplugged and |
@@ -10676,12 +10827,7 @@ static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) | |||
10676 | unsigned int mute; | 10827 | unsigned int mute; |
10677 | 10828 | ||
10678 | if (force || !spec->sense_updated) { | 10829 | if (force || !spec->sense_updated) { |
10679 | unsigned int present_int_hp; | 10830 | spec->jack_present = snd_hda_jack_detect(codec, 0x1b); |
10680 | /* need to execute and sync at first */ | ||
10681 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10682 | present_int_hp = snd_hda_codec_read(codec, 0x1b, 0, | ||
10683 | AC_VERB_GET_PIN_SENSE, 0); | ||
10684 | spec->jack_present = (present_int_hp & 0x80000000) != 0; | ||
10685 | spec->sense_updated = 1; | 10831 | spec->sense_updated = 1; |
10686 | } | 10832 | } |
10687 | if (spec->jack_present) { | 10833 | if (spec->jack_present) { |
@@ -10873,12 +11019,7 @@ static void alc262_ultra_automute(struct hda_codec *codec) | |||
10873 | mute = 0; | 11019 | mute = 0; |
10874 | /* auto-mute only when HP is used as HP */ | 11020 | /* auto-mute only when HP is used as HP */ |
10875 | if (!spec->cur_mux[0]) { | 11021 | if (!spec->cur_mux[0]) { |
10876 | unsigned int present; | 11022 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); |
10877 | /* need to execute and sync at first */ | ||
10878 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10879 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
10880 | AC_VERB_GET_PIN_SENSE, 0); | ||
10881 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | ||
10882 | if (spec->jack_present) | 11023 | if (spec->jack_present) |
10883 | mute = HDA_AMP_MUTE; | 11024 | mute = HDA_AMP_MUTE; |
10884 | } | 11025 | } |
@@ -10955,7 +11096,6 @@ static int alc262_check_volbit(hda_nid_t nid) | |||
10955 | static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, | 11096 | static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, |
10956 | const char *pfx, int *vbits) | 11097 | const char *pfx, int *vbits) |
10957 | { | 11098 | { |
10958 | char name[32]; | ||
10959 | unsigned long val; | 11099 | unsigned long val; |
10960 | int vbit; | 11100 | int vbit; |
10961 | 11101 | ||
@@ -10965,28 +11105,25 @@ static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, | |||
10965 | if (*vbits & vbit) /* a volume control for this mixer already there */ | 11105 | if (*vbits & vbit) /* a volume control for this mixer already there */ |
10966 | return 0; | 11106 | return 0; |
10967 | *vbits |= vbit; | 11107 | *vbits |= vbit; |
10968 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | ||
10969 | if (vbit == 2) | 11108 | if (vbit == 2) |
10970 | val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); | 11109 | val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); |
10971 | else | 11110 | else |
10972 | val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); | 11111 | val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); |
10973 | return add_control(spec, ALC_CTL_WIDGET_VOL, name, val); | 11112 | return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); |
10974 | } | 11113 | } |
10975 | 11114 | ||
10976 | static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, | 11115 | static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, |
10977 | const char *pfx) | 11116 | const char *pfx) |
10978 | { | 11117 | { |
10979 | char name[32]; | ||
10980 | unsigned long val; | 11118 | unsigned long val; |
10981 | 11119 | ||
10982 | if (!nid) | 11120 | if (!nid) |
10983 | return 0; | 11121 | return 0; |
10984 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | ||
10985 | if (nid == 0x16) | 11122 | if (nid == 0x16) |
10986 | val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); | 11123 | val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); |
10987 | else | 11124 | else |
10988 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | 11125 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); |
10989 | return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val); | 11126 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); |
10990 | } | 11127 | } |
10991 | 11128 | ||
10992 | /* add playback controls from the parsed DAC table */ | 11129 | /* add playback controls from the parsed DAC table */ |
@@ -11460,8 +11597,12 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
11460 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 11597 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
11461 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ | 11598 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ |
11462 | SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), | 11599 | SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), |
11600 | SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), | ||
11601 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), | ||
11602 | #if 0 /* disable the quirk since model=auto works better in recent versions */ | ||
11463 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", | 11603 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", |
11464 | ALC262_SONY_ASSAMD), | 11604 | ALC262_SONY_ASSAMD), |
11605 | #endif | ||
11465 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | 11606 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", |
11466 | ALC262_TOSHIBA_RX1), | 11607 | ALC262_TOSHIBA_RX1), |
11467 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), | 11608 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), |
@@ -11645,7 +11786,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11645 | [ALC262_LENOVO_3000] = { | 11786 | [ALC262_LENOVO_3000] = { |
11646 | .mixers = { alc262_lenovo_3000_mixer }, | 11787 | .mixers = { alc262_lenovo_3000_mixer }, |
11647 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, | 11788 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, |
11648 | alc262_lenovo_3000_unsol_verbs }, | 11789 | alc262_lenovo_3000_unsol_verbs, |
11790 | alc262_lenovo_3000_init_verbs }, | ||
11649 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11791 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
11650 | .dac_nids = alc262_dac_nids, | 11792 | .dac_nids = alc262_dac_nids, |
11651 | .hp_nid = 0x03, | 11793 | .hp_nid = 0x03, |
@@ -11920,10 +12062,7 @@ static void alc268_acer_automute(struct hda_codec *codec, int force) | |||
11920 | unsigned int mute; | 12062 | unsigned int mute; |
11921 | 12063 | ||
11922 | if (force || !spec->sense_updated) { | 12064 | if (force || !spec->sense_updated) { |
11923 | unsigned int present; | 12065 | spec->jack_present = snd_hda_jack_detect(codec, 0x14); |
11924 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
11925 | AC_VERB_GET_PIN_SENSE, 0); | ||
11926 | spec->jack_present = (present & 0x80000000) != 0; | ||
11927 | spec->sense_updated = 1; | 12066 | spec->sense_updated = 1; |
11928 | } | 12067 | } |
11929 | if (spec->jack_present) | 12068 | if (spec->jack_present) |
@@ -12042,8 +12181,7 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) | |||
12042 | unsigned int present; | 12181 | unsigned int present; |
12043 | unsigned char bits; | 12182 | unsigned char bits; |
12044 | 12183 | ||
12045 | present = snd_hda_codec_read(codec, 0x15, 0, | 12184 | present = snd_hda_jack_detect(codec, 0x15); |
12046 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
12047 | bits = present ? AMP_IN_MUTE(0) : 0; | 12185 | bits = present ? AMP_IN_MUTE(0) : 0; |
12048 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, | 12186 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, |
12049 | AMP_IN_MUTE(0), bits); | 12187 | AMP_IN_MUTE(0), bits); |
@@ -12324,11 +12462,9 @@ static struct snd_kcontrol_new alc268_test_mixer[] = { | |||
12324 | static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | 12462 | static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, |
12325 | const char *ctlname, int idx) | 12463 | const char *ctlname, int idx) |
12326 | { | 12464 | { |
12327 | char name[32]; | ||
12328 | hda_nid_t dac; | 12465 | hda_nid_t dac; |
12329 | int err; | 12466 | int err; |
12330 | 12467 | ||
12331 | sprintf(name, "%s Playback Volume", ctlname); | ||
12332 | switch (nid) { | 12468 | switch (nid) { |
12333 | case 0x14: | 12469 | case 0x14: |
12334 | case 0x16: | 12470 | case 0x16: |
@@ -12342,7 +12478,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12342 | } | 12478 | } |
12343 | if (spec->multiout.dac_nids[0] != dac && | 12479 | if (spec->multiout.dac_nids[0] != dac && |
12344 | spec->multiout.dac_nids[1] != dac) { | 12480 | spec->multiout.dac_nids[1] != dac) { |
12345 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 12481 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, |
12346 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, | 12482 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, |
12347 | HDA_OUTPUT)); | 12483 | HDA_OUTPUT)); |
12348 | if (err < 0) | 12484 | if (err < 0) |
@@ -12350,12 +12486,11 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12350 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | 12486 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; |
12351 | } | 12487 | } |
12352 | 12488 | ||
12353 | sprintf(name, "%s Playback Switch", ctlname); | ||
12354 | if (nid != 0x16) | 12489 | if (nid != 0x16) |
12355 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 12490 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, |
12356 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | 12491 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); |
12357 | else /* mono */ | 12492 | else /* mono */ |
12358 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 12493 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, |
12359 | HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); | 12494 | HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); |
12360 | if (err < 0) | 12495 | if (err < 0) |
12361 | return err; | 12496 | return err; |
@@ -12385,8 +12520,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12385 | 12520 | ||
12386 | nid = cfg->speaker_pins[0]; | 12521 | nid = cfg->speaker_pins[0]; |
12387 | if (nid == 0x1d) { | 12522 | if (nid == 0x1d) { |
12388 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 12523 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", |
12389 | "Speaker Playback Volume", | ||
12390 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 12524 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
12391 | if (err < 0) | 12525 | if (err < 0) |
12392 | return err; | 12526 | return err; |
@@ -12404,8 +12538,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12404 | 12538 | ||
12405 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; | 12539 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; |
12406 | if (nid == 0x16) { | 12540 | if (nid == 0x16) { |
12407 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | 12541 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", |
12408 | "Mono Playback Switch", | ||
12409 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); | 12542 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); |
12410 | if (err < 0) | 12543 | if (err < 0) |
12411 | return err; | 12544 | return err; |
@@ -12791,7 +12924,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
12791 | int board_config; | 12924 | int board_config; |
12792 | int i, has_beep, err; | 12925 | int i, has_beep, err; |
12793 | 12926 | ||
12794 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 12927 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
12795 | if (spec == NULL) | 12928 | if (spec == NULL) |
12796 | return -ENOMEM; | 12929 | return -ENOMEM; |
12797 | 12930 | ||
@@ -13031,8 +13164,7 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | |||
13031 | unsigned int present; | 13164 | unsigned int present; |
13032 | unsigned char bits; | 13165 | unsigned char bits; |
13033 | 13166 | ||
13034 | present = snd_hda_codec_read(codec, 0x15, 0, | 13167 | present = snd_hda_jack_detect(codec, 0x15); |
13035 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13036 | bits = present ? AMP_IN_MUTE(0) : 0; | 13168 | bits = present ? AMP_IN_MUTE(0) : 0; |
13037 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13169 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13038 | AMP_IN_MUTE(0), bits); | 13170 | AMP_IN_MUTE(0), bits); |
@@ -13057,12 +13189,10 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) | |||
13057 | unsigned char bits; | 13189 | unsigned char bits; |
13058 | 13190 | ||
13059 | /* Check laptop headphone socket */ | 13191 | /* Check laptop headphone socket */ |
13060 | present = snd_hda_codec_read(codec, 0x15, 0, | 13192 | present = snd_hda_jack_detect(codec, 0x15); |
13061 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13062 | 13193 | ||
13063 | /* Check port replicator headphone socket */ | 13194 | /* Check port replicator headphone socket */ |
13064 | present |= snd_hda_codec_read(codec, 0x1a, 0, | 13195 | present |= snd_hda_jack_detect(codec, 0x1a); |
13065 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13066 | 13196 | ||
13067 | bits = present ? AMP_IN_MUTE(0) : 0; | 13197 | bits = present ? AMP_IN_MUTE(0) : 0; |
13068 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13198 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
@@ -13086,11 +13216,8 @@ static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | |||
13086 | unsigned int present_laptop; | 13216 | unsigned int present_laptop; |
13087 | unsigned int present_dock; | 13217 | unsigned int present_dock; |
13088 | 13218 | ||
13089 | present_laptop = snd_hda_codec_read(codec, 0x18, 0, | 13219 | present_laptop = snd_hda_jack_detect(codec, 0x18); |
13090 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 13220 | present_dock = snd_hda_jack_detect(codec, 0x1b); |
13091 | |||
13092 | present_dock = snd_hda_codec_read(codec, 0x1b, 0, | ||
13093 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13094 | 13221 | ||
13095 | /* Laptop mic port overrides dock mic port, design decision */ | 13222 | /* Laptop mic port overrides dock mic port, design decision */ |
13096 | if (present_dock) | 13223 | if (present_dock) |
@@ -13172,11 +13299,12 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = { | |||
13172 | /* toggle speaker-output according to the hp-jack state */ | 13299 | /* toggle speaker-output according to the hp-jack state */ |
13173 | static void alc269_speaker_automute(struct hda_codec *codec) | 13300 | static void alc269_speaker_automute(struct hda_codec *codec) |
13174 | { | 13301 | { |
13302 | struct alc_spec *spec = codec->spec; | ||
13303 | unsigned int nid = spec->autocfg.hp_pins[0]; | ||
13175 | unsigned int present; | 13304 | unsigned int present; |
13176 | unsigned char bits; | 13305 | unsigned char bits; |
13177 | 13306 | ||
13178 | present = snd_hda_codec_read(codec, 0x15, 0, | 13307 | present = snd_hda_jack_detect(codec, nid); |
13179 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13180 | bits = present ? AMP_IN_MUTE(0) : 0; | 13308 | bits = present ? AMP_IN_MUTE(0) : 0; |
13181 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13309 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13182 | AMP_IN_MUTE(0), bits); | 13310 | AMP_IN_MUTE(0), bits); |
@@ -13401,8 +13529,8 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
13401 | static const char *alc269_models[ALC269_MODEL_LAST] = { | 13529 | static const char *alc269_models[ALC269_MODEL_LAST] = { |
13402 | [ALC269_BASIC] = "basic", | 13530 | [ALC269_BASIC] = "basic", |
13403 | [ALC269_QUANTA_FL1] = "quanta", | 13531 | [ALC269_QUANTA_FL1] = "quanta", |
13404 | [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", | 13532 | [ALC269_ASUS_AMIC] = "asus-amic", |
13405 | [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", | 13533 | [ALC269_ASUS_DMIC] = "asus-dmic", |
13406 | [ALC269_FUJITSU] = "fujitsu", | 13534 | [ALC269_FUJITSU] = "fujitsu", |
13407 | [ALC269_LIFEBOOK] = "lifebook", | 13535 | [ALC269_LIFEBOOK] = "lifebook", |
13408 | [ALC269_AUTO] = "auto", | 13536 | [ALC269_AUTO] = "auto", |
@@ -13411,18 +13539,41 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { | |||
13411 | static struct snd_pci_quirk alc269_cfg_tbl[] = { | 13539 | static struct snd_pci_quirk alc269_cfg_tbl[] = { |
13412 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | 13540 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), |
13413 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 13541 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
13414 | ALC269_ASUS_EEEPC_P703), | 13542 | ALC269_ASUS_AMIC), |
13415 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), | 13543 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), |
13416 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), | 13544 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), |
13417 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), | 13545 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), |
13418 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), | 13546 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), |
13419 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), | 13547 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), |
13420 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), | 13548 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), |
13549 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), | ||
13550 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), | ||
13551 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), | ||
13552 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), | ||
13553 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), | ||
13554 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), | ||
13555 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), | ||
13556 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), | ||
13557 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), | ||
13558 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), | ||
13559 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), | ||
13560 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), | ||
13561 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), | ||
13562 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), | ||
13563 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), | ||
13564 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), | ||
13565 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), | ||
13566 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), | ||
13567 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), | ||
13568 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), | ||
13569 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), | ||
13570 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), | ||
13421 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", | 13571 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", |
13422 | ALC269_ASUS_EEEPC_P901), | 13572 | ALC269_ASUS_DMIC), |
13423 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", | 13573 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", |
13424 | ALC269_ASUS_EEEPC_P901), | 13574 | ALC269_ASUS_DMIC), |
13425 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), | 13575 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), |
13576 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), | ||
13426 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | 13577 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), |
13427 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | 13578 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), |
13428 | {} | 13579 | {} |
@@ -13452,7 +13603,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
13452 | .setup = alc269_quanta_fl1_setup, | 13603 | .setup = alc269_quanta_fl1_setup, |
13453 | .init_hook = alc269_quanta_fl1_init_hook, | 13604 | .init_hook = alc269_quanta_fl1_init_hook, |
13454 | }, | 13605 | }, |
13455 | [ALC269_ASUS_EEEPC_P703] = { | 13606 | [ALC269_ASUS_AMIC] = { |
13456 | .mixers = { alc269_eeepc_mixer }, | 13607 | .mixers = { alc269_eeepc_mixer }, |
13457 | .cap_mixer = alc269_epc_capture_mixer, | 13608 | .cap_mixer = alc269_epc_capture_mixer, |
13458 | .init_verbs = { alc269_init_verbs, | 13609 | .init_verbs = { alc269_init_verbs, |
@@ -13466,7 +13617,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
13466 | .setup = alc269_eeepc_amic_setup, | 13617 | .setup = alc269_eeepc_amic_setup, |
13467 | .init_hook = alc269_eeepc_inithook, | 13618 | .init_hook = alc269_eeepc_inithook, |
13468 | }, | 13619 | }, |
13469 | [ALC269_ASUS_EEEPC_P901] = { | 13620 | [ALC269_ASUS_DMIC] = { |
13470 | .mixers = { alc269_eeepc_mixer }, | 13621 | .mixers = { alc269_eeepc_mixer }, |
13471 | .cap_mixer = alc269_epc_capture_mixer, | 13622 | .cap_mixer = alc269_epc_capture_mixer, |
13472 | .init_verbs = { alc269_init_verbs, | 13623 | .init_verbs = { alc269_init_verbs, |
@@ -13522,6 +13673,15 @@ static int patch_alc269(struct hda_codec *codec) | |||
13522 | 13673 | ||
13523 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 13674 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
13524 | 13675 | ||
13676 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ | ||
13677 | kfree(codec->chip_name); | ||
13678 | codec->chip_name = kstrdup("ALC259", GFP_KERNEL); | ||
13679 | if (!codec->chip_name) { | ||
13680 | alc_free(codec); | ||
13681 | return -ENOMEM; | ||
13682 | } | ||
13683 | } | ||
13684 | |||
13525 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 13685 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
13526 | alc269_models, | 13686 | alc269_models, |
13527 | alc269_cfg_tbl); | 13687 | alc269_cfg_tbl); |
@@ -14154,10 +14314,8 @@ static struct hda_verb alc861_toshiba_init_verbs[] = { | |||
14154 | /* toggle speaker-output according to the hp-jack state */ | 14314 | /* toggle speaker-output according to the hp-jack state */ |
14155 | static void alc861_toshiba_automute(struct hda_codec *codec) | 14315 | static void alc861_toshiba_automute(struct hda_codec *codec) |
14156 | { | 14316 | { |
14157 | unsigned int present; | 14317 | unsigned int present = snd_hda_jack_detect(codec, 0x0f); |
14158 | 14318 | ||
14159 | present = snd_hda_codec_read(codec, 0x0f, 0, | ||
14160 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
14161 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, | 14319 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, |
14162 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 14320 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
14163 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, | 14321 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, |
@@ -14257,9 +14415,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec, | |||
14257 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, | 14415 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, |
14258 | hda_nid_t nid, unsigned int chs) | 14416 | hda_nid_t nid, unsigned int chs) |
14259 | { | 14417 | { |
14260 | char name[32]; | 14418 | return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, |
14261 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | ||
14262 | return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name, | ||
14263 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 14419 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
14264 | } | 14420 | } |
14265 | 14421 | ||
@@ -14624,6 +14780,27 @@ static struct alc_config_preset alc861_presets[] = { | |||
14624 | }, | 14780 | }, |
14625 | }; | 14781 | }; |
14626 | 14782 | ||
14783 | /* Pin config fixes */ | ||
14784 | enum { | ||
14785 | PINFIX_FSC_AMILO_PI1505, | ||
14786 | }; | ||
14787 | |||
14788 | static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = { | ||
14789 | { 0x0b, 0x0221101f }, /* HP */ | ||
14790 | { 0x0f, 0x90170310 }, /* speaker */ | ||
14791 | { } | ||
14792 | }; | ||
14793 | |||
14794 | static const struct alc_fixup alc861_fixups[] = { | ||
14795 | [PINFIX_FSC_AMILO_PI1505] = { | ||
14796 | .pins = alc861_fsc_amilo_pi1505_pinfix | ||
14797 | }, | ||
14798 | }; | ||
14799 | |||
14800 | static struct snd_pci_quirk alc861_fixup_tbl[] = { | ||
14801 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | ||
14802 | {} | ||
14803 | }; | ||
14627 | 14804 | ||
14628 | static int patch_alc861(struct hda_codec *codec) | 14805 | static int patch_alc861(struct hda_codec *codec) |
14629 | { | 14806 | { |
@@ -14647,6 +14824,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14647 | board_config = ALC861_AUTO; | 14824 | board_config = ALC861_AUTO; |
14648 | } | 14825 | } |
14649 | 14826 | ||
14827 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); | ||
14828 | |||
14650 | if (board_config == ALC861_AUTO) { | 14829 | if (board_config == ALC861_AUTO) { |
14651 | /* automatic parse from the BIOS config */ | 14830 | /* automatic parse from the BIOS config */ |
14652 | err = alc861_parse_auto_config(codec); | 14831 | err = alc861_parse_auto_config(codec); |
@@ -15064,9 +15243,9 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | |||
15064 | unsigned int present; | 15243 | unsigned int present; |
15065 | unsigned char bits; | 15244 | unsigned char bits; |
15066 | 15245 | ||
15067 | present = snd_hda_codec_read(codec, 0x18, 0, | 15246 | present = snd_hda_jack_detect(codec, 0x18); |
15068 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
15069 | bits = present ? HDA_AMP_MUTE : 0; | 15247 | bits = present ? HDA_AMP_MUTE : 0; |
15248 | |||
15070 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, | 15249 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, |
15071 | HDA_AMP_MUTE, bits); | 15250 | HDA_AMP_MUTE, bits); |
15072 | } | 15251 | } |
@@ -15383,7 +15562,6 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) | |||
15383 | static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | 15562 | static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, |
15384 | const struct auto_pin_cfg *cfg) | 15563 | const struct auto_pin_cfg *cfg) |
15385 | { | 15564 | { |
15386 | char name[32]; | ||
15387 | static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; | 15565 | static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; |
15388 | hda_nid_t nid_v, nid_s; | 15566 | hda_nid_t nid_v, nid_s; |
15389 | int i, err; | 15567 | int i, err; |
@@ -15400,26 +15578,26 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
15400 | 15578 | ||
15401 | if (i == 2) { | 15579 | if (i == 2) { |
15402 | /* Center/LFE */ | 15580 | /* Center/LFE */ |
15403 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 15581 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
15404 | "Center Playback Volume", | 15582 | "Center", |
15405 | HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, | 15583 | HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, |
15406 | HDA_OUTPUT)); | 15584 | HDA_OUTPUT)); |
15407 | if (err < 0) | 15585 | if (err < 0) |
15408 | return err; | 15586 | return err; |
15409 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 15587 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, |
15410 | "LFE Playback Volume", | 15588 | "LFE", |
15411 | HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, | 15589 | HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, |
15412 | HDA_OUTPUT)); | 15590 | HDA_OUTPUT)); |
15413 | if (err < 0) | 15591 | if (err < 0) |
15414 | return err; | 15592 | return err; |
15415 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 15593 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
15416 | "Center Playback Switch", | 15594 | "Center", |
15417 | HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, | 15595 | HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, |
15418 | HDA_INPUT)); | 15596 | HDA_INPUT)); |
15419 | if (err < 0) | 15597 | if (err < 0) |
15420 | return err; | 15598 | return err; |
15421 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 15599 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, |
15422 | "LFE Playback Switch", | 15600 | "LFE", |
15423 | HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, | 15601 | HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, |
15424 | HDA_INPUT)); | 15602 | HDA_INPUT)); |
15425 | if (err < 0) | 15603 | if (err < 0) |
@@ -15434,8 +15612,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
15434 | pfx = "PCM"; | 15612 | pfx = "PCM"; |
15435 | } else | 15613 | } else |
15436 | pfx = chname[i]; | 15614 | pfx = chname[i]; |
15437 | sprintf(name, "%s Playback Volume", pfx); | 15615 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, |
15438 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
15439 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, | 15616 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, |
15440 | HDA_OUTPUT)); | 15617 | HDA_OUTPUT)); |
15441 | if (err < 0) | 15618 | if (err < 0) |
@@ -15443,8 +15620,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
15443 | if (cfg->line_outs == 1 && | 15620 | if (cfg->line_outs == 1 && |
15444 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | 15621 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) |
15445 | pfx = "Speaker"; | 15622 | pfx = "Speaker"; |
15446 | sprintf(name, "%s Playback Switch", pfx); | 15623 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, |
15447 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
15448 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, | 15624 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, |
15449 | HDA_INPUT)); | 15625 | HDA_INPUT)); |
15450 | if (err < 0) | 15626 | if (err < 0) |
@@ -15462,7 +15638,6 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
15462 | { | 15638 | { |
15463 | hda_nid_t nid_v, nid_s; | 15639 | hda_nid_t nid_v, nid_s; |
15464 | int err; | 15640 | int err; |
15465 | char name[32]; | ||
15466 | 15641 | ||
15467 | if (!pin) | 15642 | if (!pin) |
15468 | return 0; | 15643 | return 0; |
@@ -15480,21 +15655,18 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
15480 | nid_s = alc861vd_idx_to_mixer_switch( | 15655 | nid_s = alc861vd_idx_to_mixer_switch( |
15481 | alc880_fixed_pin_idx(pin)); | 15656 | alc880_fixed_pin_idx(pin)); |
15482 | 15657 | ||
15483 | sprintf(name, "%s Playback Volume", pfx); | 15658 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, |
15484 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
15485 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); | 15659 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); |
15486 | if (err < 0) | 15660 | if (err < 0) |
15487 | return err; | 15661 | return err; |
15488 | sprintf(name, "%s Playback Switch", pfx); | 15662 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, |
15489 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
15490 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); | 15663 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); |
15491 | if (err < 0) | 15664 | if (err < 0) |
15492 | return err; | 15665 | return err; |
15493 | } else if (alc880_is_multi_pin(pin)) { | 15666 | } else if (alc880_is_multi_pin(pin)) { |
15494 | /* set manual connection */ | 15667 | /* set manual connection */ |
15495 | /* we have only a switch on HP-out PIN */ | 15668 | /* we have only a switch on HP-out PIN */ |
15496 | sprintf(name, "%s Playback Switch", pfx); | 15669 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, |
15497 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
15498 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | 15670 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
15499 | if (err < 0) | 15671 | if (err < 0) |
15500 | return err; | 15672 | return err; |
@@ -16080,6 +16252,52 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { | |||
16080 | { } /* end */ | 16252 | { } /* end */ |
16081 | }; | 16253 | }; |
16082 | 16254 | ||
16255 | static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { | ||
16256 | .ops = &snd_hda_bind_sw, | ||
16257 | .values = { | ||
16258 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
16259 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
16260 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
16261 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
16262 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
16263 | 0 | ||
16264 | }, | ||
16265 | }; | ||
16266 | |||
16267 | static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { | ||
16268 | .ops = &snd_hda_bind_sw, | ||
16269 | .values = { | ||
16270 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
16271 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
16272 | 0 | ||
16273 | }, | ||
16274 | }; | ||
16275 | |||
16276 | static struct snd_kcontrol_new alc663_mode7_mixer[] = { | ||
16277 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | ||
16278 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | ||
16279 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | ||
16280 | HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
16281 | HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
16282 | HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
16283 | HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
16284 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
16285 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
16286 | { } /* end */ | ||
16287 | }; | ||
16288 | |||
16289 | static struct snd_kcontrol_new alc663_mode8_mixer[] = { | ||
16290 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | ||
16291 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | ||
16292 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | ||
16293 | HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
16294 | HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
16295 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
16296 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
16297 | { } /* end */ | ||
16298 | }; | ||
16299 | |||
16300 | |||
16083 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { | 16301 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { |
16084 | { | 16302 | { |
16085 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 16303 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -16367,6 +16585,45 @@ static struct hda_verb alc272_dell_init_verbs[] = { | |||
16367 | {} | 16585 | {} |
16368 | }; | 16586 | }; |
16369 | 16587 | ||
16588 | static struct hda_verb alc663_mode7_init_verbs[] = { | ||
16589 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
16590 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
16591 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
16592 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16593 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
16594 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16595 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
16596 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
16597 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16598 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
16599 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
16600 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
16601 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
16602 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
16603 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
16604 | {} | ||
16605 | }; | ||
16606 | |||
16607 | static struct hda_verb alc663_mode8_init_verbs[] = { | ||
16608 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
16609 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
16610 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16611 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
16612 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
16613 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
16614 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16615 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
16616 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
16617 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
16618 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
16619 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
16620 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
16621 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
16622 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
16623 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
16624 | {} | ||
16625 | }; | ||
16626 | |||
16370 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { | 16627 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { |
16371 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 16628 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
16372 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 16629 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
@@ -16384,9 +16641,9 @@ static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | |||
16384 | unsigned int present; | 16641 | unsigned int present; |
16385 | unsigned char bits; | 16642 | unsigned char bits; |
16386 | 16643 | ||
16387 | present = snd_hda_codec_read(codec, 0x14, 0, | 16644 | present = snd_hda_jack_detect(codec, 0x14); |
16388 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
16389 | bits = present ? HDA_AMP_MUTE : 0; | 16645 | bits = present ? HDA_AMP_MUTE : 0; |
16646 | |||
16390 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 16647 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
16391 | HDA_AMP_MUTE, bits); | 16648 | HDA_AMP_MUTE, bits); |
16392 | } | 16649 | } |
@@ -16396,9 +16653,9 @@ static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) | |||
16396 | unsigned int present; | 16653 | unsigned int present; |
16397 | unsigned char bits; | 16654 | unsigned char bits; |
16398 | 16655 | ||
16399 | present = snd_hda_codec_read(codec, 0x1b, 0, | 16656 | present = snd_hda_jack_detect(codec, 0x1b); |
16400 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
16401 | bits = present ? HDA_AMP_MUTE : 0; | 16657 | bits = present ? HDA_AMP_MUTE : 0; |
16658 | |||
16402 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 16659 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
16403 | HDA_AMP_MUTE, bits); | 16660 | HDA_AMP_MUTE, bits); |
16404 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 16661 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, |
@@ -16457,9 +16714,7 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) | |||
16457 | unsigned int present; | 16714 | unsigned int present; |
16458 | unsigned char bits; | 16715 | unsigned char bits; |
16459 | 16716 | ||
16460 | present = snd_hda_codec_read(codec, 0x21, 0, | 16717 | present = snd_hda_jack_detect(codec, 0x21); |
16461 | AC_VERB_GET_PIN_SENSE, 0) | ||
16462 | & AC_PINSENSE_PRESENCE; | ||
16463 | bits = present ? HDA_AMP_MUTE : 0; | 16718 | bits = present ? HDA_AMP_MUTE : 0; |
16464 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 16719 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
16465 | AMP_IN_MUTE(0), bits); | 16720 | AMP_IN_MUTE(0), bits); |
@@ -16472,9 +16727,7 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | |||
16472 | unsigned int present; | 16727 | unsigned int present; |
16473 | unsigned char bits; | 16728 | unsigned char bits; |
16474 | 16729 | ||
16475 | present = snd_hda_codec_read(codec, 0x21, 0, | 16730 | present = snd_hda_jack_detect(codec, 0x21); |
16476 | AC_VERB_GET_PIN_SENSE, 0) | ||
16477 | & AC_PINSENSE_PRESENCE; | ||
16478 | bits = present ? HDA_AMP_MUTE : 0; | 16731 | bits = present ? HDA_AMP_MUTE : 0; |
16479 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 16732 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
16480 | AMP_IN_MUTE(0), bits); | 16733 | AMP_IN_MUTE(0), bits); |
@@ -16491,9 +16744,7 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | |||
16491 | unsigned int present; | 16744 | unsigned int present; |
16492 | unsigned char bits; | 16745 | unsigned char bits; |
16493 | 16746 | ||
16494 | present = snd_hda_codec_read(codec, 0x15, 0, | 16747 | present = snd_hda_jack_detect(codec, 0x15); |
16495 | AC_VERB_GET_PIN_SENSE, 0) | ||
16496 | & AC_PINSENSE_PRESENCE; | ||
16497 | bits = present ? HDA_AMP_MUTE : 0; | 16748 | bits = present ? HDA_AMP_MUTE : 0; |
16498 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 16749 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
16499 | AMP_IN_MUTE(0), bits); | 16750 | AMP_IN_MUTE(0), bits); |
@@ -16510,9 +16761,7 @@ static void alc662_f5z_speaker_automute(struct hda_codec *codec) | |||
16510 | unsigned int present; | 16761 | unsigned int present; |
16511 | unsigned char bits; | 16762 | unsigned char bits; |
16512 | 16763 | ||
16513 | present = snd_hda_codec_read(codec, 0x1b, 0, | 16764 | present = snd_hda_jack_detect(codec, 0x1b); |
16514 | AC_VERB_GET_PIN_SENSE, 0) | ||
16515 | & AC_PINSENSE_PRESENCE; | ||
16516 | bits = present ? 0 : PIN_OUT; | 16765 | bits = present ? 0 : PIN_OUT; |
16517 | snd_hda_codec_write(codec, 0x14, 0, | 16766 | snd_hda_codec_write(codec, 0x14, 0, |
16518 | AC_VERB_SET_PIN_WIDGET_CONTROL, bits); | 16767 | AC_VERB_SET_PIN_WIDGET_CONTROL, bits); |
@@ -16522,12 +16771,8 @@ static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) | |||
16522 | { | 16771 | { |
16523 | unsigned int present1, present2; | 16772 | unsigned int present1, present2; |
16524 | 16773 | ||
16525 | present1 = snd_hda_codec_read(codec, 0x21, 0, | 16774 | present1 = snd_hda_jack_detect(codec, 0x21); |
16526 | AC_VERB_GET_PIN_SENSE, 0) | 16775 | present2 = snd_hda_jack_detect(codec, 0x15); |
16527 | & AC_PINSENSE_PRESENCE; | ||
16528 | present2 = snd_hda_codec_read(codec, 0x15, 0, | ||
16529 | AC_VERB_GET_PIN_SENSE, 0) | ||
16530 | & AC_PINSENSE_PRESENCE; | ||
16531 | 16776 | ||
16532 | if (present1 || present2) { | 16777 | if (present1 || present2) { |
16533 | snd_hda_codec_write_cache(codec, 0x14, 0, | 16778 | snd_hda_codec_write_cache(codec, 0x14, 0, |
@@ -16542,12 +16787,8 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | |||
16542 | { | 16787 | { |
16543 | unsigned int present1, present2; | 16788 | unsigned int present1, present2; |
16544 | 16789 | ||
16545 | present1 = snd_hda_codec_read(codec, 0x1b, 0, | 16790 | present1 = snd_hda_jack_detect(codec, 0x1b); |
16546 | AC_VERB_GET_PIN_SENSE, 0) | 16791 | present2 = snd_hda_jack_detect(codec, 0x15); |
16547 | & AC_PINSENSE_PRESENCE; | ||
16548 | present2 = snd_hda_codec_read(codec, 0x15, 0, | ||
16549 | AC_VERB_GET_PIN_SENSE, 0) | ||
16550 | & AC_PINSENSE_PRESENCE; | ||
16551 | 16792 | ||
16552 | if (present1 || present2) { | 16793 | if (present1 || present2) { |
16553 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 16794 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
@@ -16562,6 +16803,54 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | |||
16562 | } | 16803 | } |
16563 | } | 16804 | } |
16564 | 16805 | ||
16806 | static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) | ||
16807 | { | ||
16808 | unsigned int present1, present2; | ||
16809 | |||
16810 | present1 = snd_hda_codec_read(codec, 0x1b, 0, | ||
16811 | AC_VERB_GET_PIN_SENSE, 0) | ||
16812 | & AC_PINSENSE_PRESENCE; | ||
16813 | present2 = snd_hda_codec_read(codec, 0x21, 0, | ||
16814 | AC_VERB_GET_PIN_SENSE, 0) | ||
16815 | & AC_PINSENSE_PRESENCE; | ||
16816 | |||
16817 | if (present1 || present2) { | ||
16818 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
16819 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
16820 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
16821 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
16822 | } else { | ||
16823 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
16824 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
16825 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
16826 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
16827 | } | ||
16828 | } | ||
16829 | |||
16830 | static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) | ||
16831 | { | ||
16832 | unsigned int present1, present2; | ||
16833 | |||
16834 | present1 = snd_hda_codec_read(codec, 0x21, 0, | ||
16835 | AC_VERB_GET_PIN_SENSE, 0) | ||
16836 | & AC_PINSENSE_PRESENCE; | ||
16837 | present2 = snd_hda_codec_read(codec, 0x15, 0, | ||
16838 | AC_VERB_GET_PIN_SENSE, 0) | ||
16839 | & AC_PINSENSE_PRESENCE; | ||
16840 | |||
16841 | if (present1 || present2) { | ||
16842 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
16843 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
16844 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
16845 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
16846 | } else { | ||
16847 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
16848 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
16849 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
16850 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
16851 | } | ||
16852 | } | ||
16853 | |||
16565 | static void alc663_m51va_unsol_event(struct hda_codec *codec, | 16854 | static void alc663_m51va_unsol_event(struct hda_codec *codec, |
16566 | unsigned int res) | 16855 | unsigned int res) |
16567 | { | 16856 | { |
@@ -16581,7 +16870,7 @@ static void alc663_m51va_setup(struct hda_codec *codec) | |||
16581 | spec->ext_mic.pin = 0x18; | 16870 | spec->ext_mic.pin = 0x18; |
16582 | spec->ext_mic.mux_idx = 0; | 16871 | spec->ext_mic.mux_idx = 0; |
16583 | spec->int_mic.pin = 0x12; | 16872 | spec->int_mic.pin = 0x12; |
16584 | spec->int_mic.mux_idx = 1; | 16873 | spec->int_mic.mux_idx = 9; |
16585 | spec->auto_mic = 1; | 16874 | spec->auto_mic = 1; |
16586 | } | 16875 | } |
16587 | 16876 | ||
@@ -16593,7 +16882,17 @@ static void alc663_m51va_inithook(struct hda_codec *codec) | |||
16593 | 16882 | ||
16594 | /* ***************** Mode1 ******************************/ | 16883 | /* ***************** Mode1 ******************************/ |
16595 | #define alc663_mode1_unsol_event alc663_m51va_unsol_event | 16884 | #define alc663_mode1_unsol_event alc663_m51va_unsol_event |
16596 | #define alc663_mode1_setup alc663_m51va_setup | 16885 | |
16886 | static void alc663_mode1_setup(struct hda_codec *codec) | ||
16887 | { | ||
16888 | struct alc_spec *spec = codec->spec; | ||
16889 | spec->ext_mic.pin = 0x18; | ||
16890 | spec->ext_mic.mux_idx = 0; | ||
16891 | spec->int_mic.pin = 0x19; | ||
16892 | spec->int_mic.mux_idx = 1; | ||
16893 | spec->auto_mic = 1; | ||
16894 | } | ||
16895 | |||
16597 | #define alc663_mode1_inithook alc663_m51va_inithook | 16896 | #define alc663_mode1_inithook alc663_m51va_inithook |
16598 | 16897 | ||
16599 | /* ***************** Mode2 ******************************/ | 16898 | /* ***************** Mode2 ******************************/ |
@@ -16610,7 +16909,7 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec, | |||
16610 | } | 16909 | } |
16611 | } | 16910 | } |
16612 | 16911 | ||
16613 | #define alc662_mode2_setup alc663_m51va_setup | 16912 | #define alc662_mode2_setup alc663_mode1_setup |
16614 | 16913 | ||
16615 | static void alc662_mode2_inithook(struct hda_codec *codec) | 16914 | static void alc662_mode2_inithook(struct hda_codec *codec) |
16616 | { | 16915 | { |
@@ -16631,7 +16930,7 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec, | |||
16631 | } | 16930 | } |
16632 | } | 16931 | } |
16633 | 16932 | ||
16634 | #define alc663_mode3_setup alc663_m51va_setup | 16933 | #define alc663_mode3_setup alc663_mode1_setup |
16635 | 16934 | ||
16636 | static void alc663_mode3_inithook(struct hda_codec *codec) | 16935 | static void alc663_mode3_inithook(struct hda_codec *codec) |
16637 | { | 16936 | { |
@@ -16652,7 +16951,7 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec, | |||
16652 | } | 16951 | } |
16653 | } | 16952 | } |
16654 | 16953 | ||
16655 | #define alc663_mode4_setup alc663_m51va_setup | 16954 | #define alc663_mode4_setup alc663_mode1_setup |
16656 | 16955 | ||
16657 | static void alc663_mode4_inithook(struct hda_codec *codec) | 16956 | static void alc663_mode4_inithook(struct hda_codec *codec) |
16658 | { | 16957 | { |
@@ -16673,7 +16972,7 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec, | |||
16673 | } | 16972 | } |
16674 | } | 16973 | } |
16675 | 16974 | ||
16676 | #define alc663_mode5_setup alc663_m51va_setup | 16975 | #define alc663_mode5_setup alc663_mode1_setup |
16677 | 16976 | ||
16678 | static void alc663_mode5_inithook(struct hda_codec *codec) | 16977 | static void alc663_mode5_inithook(struct hda_codec *codec) |
16679 | { | 16978 | { |
@@ -16694,7 +16993,7 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec, | |||
16694 | } | 16993 | } |
16695 | } | 16994 | } |
16696 | 16995 | ||
16697 | #define alc663_mode6_setup alc663_m51va_setup | 16996 | #define alc663_mode6_setup alc663_mode1_setup |
16698 | 16997 | ||
16699 | static void alc663_mode6_inithook(struct hda_codec *codec) | 16998 | static void alc663_mode6_inithook(struct hda_codec *codec) |
16700 | { | 16999 | { |
@@ -16702,14 +17001,56 @@ static void alc663_mode6_inithook(struct hda_codec *codec) | |||
16702 | alc_mic_automute(codec); | 17001 | alc_mic_automute(codec); |
16703 | } | 17002 | } |
16704 | 17003 | ||
17004 | /* ***************** Mode7 ******************************/ | ||
17005 | static void alc663_mode7_unsol_event(struct hda_codec *codec, | ||
17006 | unsigned int res) | ||
17007 | { | ||
17008 | switch (res >> 26) { | ||
17009 | case ALC880_HP_EVENT: | ||
17010 | alc663_two_hp_m7_speaker_automute(codec); | ||
17011 | break; | ||
17012 | case ALC880_MIC_EVENT: | ||
17013 | alc_mic_automute(codec); | ||
17014 | break; | ||
17015 | } | ||
17016 | } | ||
17017 | |||
17018 | #define alc663_mode7_setup alc663_mode1_setup | ||
17019 | |||
17020 | static void alc663_mode7_inithook(struct hda_codec *codec) | ||
17021 | { | ||
17022 | alc663_two_hp_m7_speaker_automute(codec); | ||
17023 | alc_mic_automute(codec); | ||
17024 | } | ||
17025 | |||
17026 | /* ***************** Mode8 ******************************/ | ||
17027 | static void alc663_mode8_unsol_event(struct hda_codec *codec, | ||
17028 | unsigned int res) | ||
17029 | { | ||
17030 | switch (res >> 26) { | ||
17031 | case ALC880_HP_EVENT: | ||
17032 | alc663_two_hp_m8_speaker_automute(codec); | ||
17033 | break; | ||
17034 | case ALC880_MIC_EVENT: | ||
17035 | alc_mic_automute(codec); | ||
17036 | break; | ||
17037 | } | ||
17038 | } | ||
17039 | |||
17040 | #define alc663_mode8_setup alc663_m51va_setup | ||
17041 | |||
17042 | static void alc663_mode8_inithook(struct hda_codec *codec) | ||
17043 | { | ||
17044 | alc663_two_hp_m8_speaker_automute(codec); | ||
17045 | alc_mic_automute(codec); | ||
17046 | } | ||
17047 | |||
16705 | static void alc663_g71v_hp_automute(struct hda_codec *codec) | 17048 | static void alc663_g71v_hp_automute(struct hda_codec *codec) |
16706 | { | 17049 | { |
16707 | unsigned int present; | 17050 | unsigned int present; |
16708 | unsigned char bits; | 17051 | unsigned char bits; |
16709 | 17052 | ||
16710 | present = snd_hda_codec_read(codec, 0x21, 0, | 17053 | present = snd_hda_jack_detect(codec, 0x21); |
16711 | AC_VERB_GET_PIN_SENSE, 0) | ||
16712 | & AC_PINSENSE_PRESENCE; | ||
16713 | bits = present ? HDA_AMP_MUTE : 0; | 17054 | bits = present ? HDA_AMP_MUTE : 0; |
16714 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 17055 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
16715 | HDA_AMP_MUTE, bits); | 17056 | HDA_AMP_MUTE, bits); |
@@ -16722,9 +17063,7 @@ static void alc663_g71v_front_automute(struct hda_codec *codec) | |||
16722 | unsigned int present; | 17063 | unsigned int present; |
16723 | unsigned char bits; | 17064 | unsigned char bits; |
16724 | 17065 | ||
16725 | present = snd_hda_codec_read(codec, 0x15, 0, | 17066 | present = snd_hda_jack_detect(codec, 0x15); |
16726 | AC_VERB_GET_PIN_SENSE, 0) | ||
16727 | & AC_PINSENSE_PRESENCE; | ||
16728 | bits = present ? HDA_AMP_MUTE : 0; | 17067 | bits = present ? HDA_AMP_MUTE : 0; |
16729 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 17068 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, |
16730 | HDA_AMP_MUTE, bits); | 17069 | HDA_AMP_MUTE, bits); |
@@ -16840,6 +17179,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
16840 | [ALC663_ASUS_MODE4] = "asus-mode4", | 17179 | [ALC663_ASUS_MODE4] = "asus-mode4", |
16841 | [ALC663_ASUS_MODE5] = "asus-mode5", | 17180 | [ALC663_ASUS_MODE5] = "asus-mode5", |
16842 | [ALC663_ASUS_MODE6] = "asus-mode6", | 17181 | [ALC663_ASUS_MODE6] = "asus-mode6", |
17182 | [ALC663_ASUS_MODE7] = "asus-mode7", | ||
17183 | [ALC663_ASUS_MODE8] = "asus-mode8", | ||
16843 | [ALC272_DELL] = "dell", | 17184 | [ALC272_DELL] = "dell", |
16844 | [ALC272_DELL_ZM1] = "dell-zm1", | 17185 | [ALC272_DELL_ZM1] = "dell-zm1", |
16845 | [ALC272_SAMSUNG_NC10] = "samsung-nc10", | 17186 | [ALC272_SAMSUNG_NC10] = "samsung-nc10", |
@@ -16856,12 +17197,22 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16856 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), | 17197 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), |
16857 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), | 17198 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), |
16858 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), | 17199 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), |
17200 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), | ||
17201 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), | ||
16859 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), | 17202 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), |
17203 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), | ||
17204 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), | ||
17205 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), | ||
17206 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), | ||
17207 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), | ||
16860 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), | 17208 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), |
17209 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), | ||
17210 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), | ||
16861 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), | 17211 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), |
16862 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | 17212 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), |
16863 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | 17213 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), |
16864 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | 17214 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), |
17215 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), | ||
16865 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), | 17216 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), |
16866 | SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), | 17217 | SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), |
16867 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), | 17218 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), |
@@ -16911,6 +17262,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16911 | ALC662_3ST_6ch_DIG), | 17262 | ALC662_3ST_6ch_DIG), |
16912 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", | 17263 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", |
16913 | ALC663_ASUS_H13), | 17264 | ALC663_ASUS_H13), |
17265 | SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG), | ||
16914 | {} | 17266 | {} |
16915 | }; | 17267 | }; |
16916 | 17268 | ||
@@ -17144,6 +17496,36 @@ static struct alc_config_preset alc662_presets[] = { | |||
17144 | .setup = alc663_mode6_setup, | 17496 | .setup = alc663_mode6_setup, |
17145 | .init_hook = alc663_mode6_inithook, | 17497 | .init_hook = alc663_mode6_inithook, |
17146 | }, | 17498 | }, |
17499 | [ALC663_ASUS_MODE7] = { | ||
17500 | .mixers = { alc663_mode7_mixer }, | ||
17501 | .cap_mixer = alc662_auto_capture_mixer, | ||
17502 | .init_verbs = { alc662_init_verbs, | ||
17503 | alc663_mode7_init_verbs }, | ||
17504 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
17505 | .hp_nid = 0x03, | ||
17506 | .dac_nids = alc662_dac_nids, | ||
17507 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
17508 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
17509 | .channel_mode = alc662_3ST_2ch_modes, | ||
17510 | .unsol_event = alc663_mode7_unsol_event, | ||
17511 | .setup = alc663_mode7_setup, | ||
17512 | .init_hook = alc663_mode7_inithook, | ||
17513 | }, | ||
17514 | [ALC663_ASUS_MODE8] = { | ||
17515 | .mixers = { alc663_mode8_mixer }, | ||
17516 | .cap_mixer = alc662_auto_capture_mixer, | ||
17517 | .init_verbs = { alc662_init_verbs, | ||
17518 | alc663_mode8_init_verbs }, | ||
17519 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
17520 | .hp_nid = 0x03, | ||
17521 | .dac_nids = alc662_dac_nids, | ||
17522 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
17523 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
17524 | .channel_mode = alc662_3ST_2ch_modes, | ||
17525 | .unsol_event = alc663_mode8_unsol_event, | ||
17526 | .setup = alc663_mode8_setup, | ||
17527 | .init_hook = alc663_mode8_inithook, | ||
17528 | }, | ||
17147 | [ALC272_DELL] = { | 17529 | [ALC272_DELL] = { |
17148 | .mixers = { alc663_m51va_mixer }, | 17530 | .mixers = { alc663_m51va_mixer }, |
17149 | .cap_mixer = alc272_auto_capture_mixer, | 17531 | .cap_mixer = alc272_auto_capture_mixer, |
@@ -17261,21 +17643,17 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec, | |||
17261 | return 0; | 17643 | return 0; |
17262 | } | 17644 | } |
17263 | 17645 | ||
17264 | static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, | 17646 | static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, |
17265 | hda_nid_t nid, unsigned int chs) | 17647 | hda_nid_t nid, unsigned int chs) |
17266 | { | 17648 | { |
17267 | char name[32]; | 17649 | return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, |
17268 | sprintf(name, "%s Playback Volume", pfx); | ||
17269 | return add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
17270 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 17650 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
17271 | } | 17651 | } |
17272 | 17652 | ||
17273 | static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, | 17653 | static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, |
17274 | hda_nid_t nid, unsigned int chs) | 17654 | hda_nid_t nid, unsigned int chs) |
17275 | { | 17655 | { |
17276 | char name[32]; | 17656 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, |
17277 | sprintf(name, "%s Playback Switch", pfx); | ||
17278 | return add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
17279 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); | 17657 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); |
17280 | } | 17658 | } |
17281 | 17659 | ||
@@ -17353,13 +17731,11 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
17353 | return 0; | 17731 | return 0; |
17354 | nid = alc662_look_for_dac(codec, pin); | 17732 | nid = alc662_look_for_dac(codec, pin); |
17355 | if (!nid) { | 17733 | if (!nid) { |
17356 | char name[32]; | ||
17357 | /* the corresponding DAC is already occupied */ | 17734 | /* the corresponding DAC is already occupied */ |
17358 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) | 17735 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) |
17359 | return 0; /* no way */ | 17736 | return 0; /* no way */ |
17360 | /* create a switch only */ | 17737 | /* create a switch only */ |
17361 | sprintf(name, "%s Playback Switch", pfx); | 17738 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, |
17362 | return add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
17363 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | 17739 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
17364 | } | 17740 | } |
17365 | 17741 | ||
@@ -17535,6 +17911,15 @@ static int patch_alc662(struct hda_codec *codec) | |||
17535 | 17911 | ||
17536 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 17912 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
17537 | 17913 | ||
17914 | if (alc_read_coef_idx(codec, 0)==0x8020){ | ||
17915 | kfree(codec->chip_name); | ||
17916 | codec->chip_name = kstrdup("ALC661", GFP_KERNEL); | ||
17917 | if (!codec->chip_name) { | ||
17918 | alc_free(codec); | ||
17919 | return -ENOMEM; | ||
17920 | } | ||
17921 | } | ||
17922 | |||
17538 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | 17923 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, |
17539 | alc662_models, | 17924 | alc662_models, |
17540 | alc662_cfg_tbl); | 17925 | alc662_cfg_tbl); |
@@ -17601,6 +17986,20 @@ static int patch_alc662(struct hda_codec *codec) | |||
17601 | return 0; | 17986 | return 0; |
17602 | } | 17987 | } |
17603 | 17988 | ||
17989 | static int patch_alc888(struct hda_codec *codec) | ||
17990 | { | ||
17991 | if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ | ||
17992 | kfree(codec->chip_name); | ||
17993 | codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); | ||
17994 | if (!codec->chip_name) { | ||
17995 | alc_free(codec); | ||
17996 | return -ENOMEM; | ||
17997 | } | ||
17998 | return patch_alc662(codec); | ||
17999 | } | ||
18000 | return patch_alc882(codec); | ||
18001 | } | ||
18002 | |||
17604 | /* | 18003 | /* |
17605 | * patch entries | 18004 | * patch entries |
17606 | */ | 18005 | */ |
@@ -17610,7 +18009,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
17610 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, | 18009 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
17611 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, | 18010 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, |
17612 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, | 18011 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, |
18012 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, | ||
17613 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 18013 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
18014 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | ||
17614 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 18015 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
17615 | .patch = patch_alc861 }, | 18016 | .patch = patch_alc861 }, |
17616 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 18017 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
@@ -17632,8 +18033,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
17632 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, | 18033 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
17633 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 18034 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
17634 | .patch = patch_alc882 }, | 18035 | .patch = patch_alc882 }, |
17635 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, | 18036 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, |
17636 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 18037 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
18038 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | ||
17637 | {} /* terminator */ | 18039 | {} /* terminator */ |
17638 | }; | 18040 | }; |
17639 | 18041 | ||