diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:58:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 15:58:37 -0400 |
commit | 0a3fd051c7036ef71b58863f8e5da7c3dabd9d3f (patch) | |
tree | 43388a81494ded94008afff66777f9f6e8cb5484 /sound/pci/hda/patch_realtek.c | |
parent | 57a44415beee38d1afcd8e1b5fad66f3414d2dac (diff) | |
parent | c911d1e16dfc1f0338bbc245ff724322c0113395 (diff) |
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (122 commits)
[ALSA] version 1.0.14rc4
[ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config()
[ALSA] hda-codec - Add ALC861VD Lenovo support
[ALSA] hda-codec - Fix connection list in generic parser
[ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U
[ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware
[ALSA] usb-audio: explicitly match Logitech QuickCam
[ALSA] hda-codec - Fix a typo
[ALSA] hda-codec - Fix ALC880 uniwill auto-mutes
[ALSA] hda-codec - Fix AD1988 SPDIF playback route control
[ALSA] wm8750 typo fix
[ALSA] wavefront: only declare isapnp on CONFIG_PNP
[ALSA] hda-codec - bug fixes for stac92xx HDA codecs.
[ALSA] add MODULE_FIRMWARE entries
[ALSA] do not depend on FW_LOADER when internal firmware images are used
[ALSA] hda-codec - Fix resume of STAC92xx codecs
[ALSA] usbaudio - Revert the minimal period size fix patch
[ALSA] hda-codec - Add support for new HP DV series laptops
[ALSA] usb-audio - Fix the minimum period size per transfer mode
[ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition
...
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2269 |
1 files changed, 1908 insertions, 361 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fba3cb11bc2a..a4ede27af021 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -74,6 +74,8 @@ enum { | |||
74 | ALC260_HP_3013, | 74 | ALC260_HP_3013, |
75 | ALC260_FUJITSU_S702X, | 75 | ALC260_FUJITSU_S702X, |
76 | ALC260_ACER, | 76 | ALC260_ACER, |
77 | ALC260_WILL, | ||
78 | ALC260_REPLACER_672V, | ||
77 | #ifdef CONFIG_SND_DEBUG | 79 | #ifdef CONFIG_SND_DEBUG |
78 | ALC260_TEST, | 80 | ALC260_TEST, |
79 | #endif | 81 | #endif |
@@ -115,15 +117,28 @@ enum { | |||
115 | ALC861VD_3ST, | 117 | ALC861VD_3ST, |
116 | ALC861VD_3ST_DIG, | 118 | ALC861VD_3ST_DIG, |
117 | ALC861VD_6ST_DIG, | 119 | ALC861VD_6ST_DIG, |
120 | ALC861VD_LENOVO, | ||
118 | ALC861VD_AUTO, | 121 | ALC861VD_AUTO, |
119 | ALC861VD_MODEL_LAST, | 122 | ALC861VD_MODEL_LAST, |
120 | }; | 123 | }; |
121 | 124 | ||
125 | /* ALC662 models */ | ||
126 | enum { | ||
127 | ALC662_3ST_2ch_DIG, | ||
128 | ALC662_3ST_6ch_DIG, | ||
129 | ALC662_3ST_6ch, | ||
130 | ALC662_5ST_DIG, | ||
131 | ALC662_LENOVO_101E, | ||
132 | ALC662_AUTO, | ||
133 | ALC662_MODEL_LAST, | ||
134 | }; | ||
135 | |||
122 | /* ALC882 models */ | 136 | /* ALC882 models */ |
123 | enum { | 137 | enum { |
124 | ALC882_3ST_DIG, | 138 | ALC882_3ST_DIG, |
125 | ALC882_6ST_DIG, | 139 | ALC882_6ST_DIG, |
126 | ALC882_ARIMA, | 140 | ALC882_ARIMA, |
141 | ALC882_W2JC, | ||
127 | ALC882_AUTO, | 142 | ALC882_AUTO, |
128 | ALC885_MACPRO, | 143 | ALC885_MACPRO, |
129 | ALC882_MODEL_LAST, | 144 | ALC882_MODEL_LAST, |
@@ -141,6 +156,7 @@ enum { | |||
141 | ALC883_ACER, | 156 | ALC883_ACER, |
142 | ALC883_MEDION, | 157 | ALC883_MEDION, |
143 | ALC883_LAPTOP_EAPD, | 158 | ALC883_LAPTOP_EAPD, |
159 | ALC883_LENOVO_101E_2ch, | ||
144 | ALC883_AUTO, | 160 | ALC883_AUTO, |
145 | ALC883_MODEL_LAST, | 161 | ALC883_MODEL_LAST, |
146 | }; | 162 | }; |
@@ -163,7 +179,7 @@ struct alc_spec { | |||
163 | struct hda_pcm_stream *stream_analog_playback; | 179 | struct hda_pcm_stream *stream_analog_playback; |
164 | struct hda_pcm_stream *stream_analog_capture; | 180 | struct hda_pcm_stream *stream_analog_capture; |
165 | 181 | ||
166 | char *stream_name_digital; /* digital PCM stream */ | 182 | char *stream_name_digital; /* digital PCM stream */ |
167 | struct hda_pcm_stream *stream_digital_playback; | 183 | struct hda_pcm_stream *stream_digital_playback; |
168 | struct hda_pcm_stream *stream_digital_capture; | 184 | struct hda_pcm_stream *stream_digital_capture; |
169 | 185 | ||
@@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | |||
401 | AC_VERB_GET_PIN_WIDGET_CONTROL, | 417 | AC_VERB_GET_PIN_WIDGET_CONTROL, |
402 | 0x00); | 418 | 0x00); |
403 | 419 | ||
404 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) | 420 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) |
405 | val = alc_pin_mode_min(dir); | 421 | val = alc_pin_mode_min(dir); |
406 | 422 | ||
407 | change = pinctl != alc_pin_mode_values[val]; | 423 | change = pinctl != alc_pin_mode_values[val]; |
@@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, | |||
460 | uinfo->value.integer.min = 0; | 476 | uinfo->value.integer.min = 0; |
461 | uinfo->value.integer.max = 1; | 477 | uinfo->value.integer.max = 1; |
462 | return 0; | 478 | return 0; |
463 | } | 479 | } |
480 | |||
464 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, | 481 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, |
465 | struct snd_ctl_elem_value *ucontrol) | 482 | struct snd_ctl_elem_value *ucontrol) |
466 | { | 483 | { |
@@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, | |||
520 | uinfo->value.integer.min = 0; | 537 | uinfo->value.integer.min = 0; |
521 | uinfo->value.integer.max = 1; | 538 | uinfo->value.integer.max = 1; |
522 | return 0; | 539 | return 0; |
523 | } | 540 | } |
541 | |||
524 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, | 542 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, |
525 | struct snd_ctl_elem_value *ucontrol) | 543 | struct snd_ctl_elem_value *ucontrol) |
526 | { | 544 | { |
@@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec, | |||
592 | spec->multiout.hp_nid = preset->hp_nid; | 610 | spec->multiout.hp_nid = preset->hp_nid; |
593 | 611 | ||
594 | spec->num_mux_defs = preset->num_mux_defs; | 612 | spec->num_mux_defs = preset->num_mux_defs; |
595 | if (! spec->num_mux_defs) | 613 | if (!spec->num_mux_defs) |
596 | spec->num_mux_defs = 1; | 614 | spec->num_mux_defs = 1; |
597 | spec->input_mux = preset->input_mux; | 615 | spec->input_mux = preset->input_mux; |
598 | 616 | ||
@@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec, | |||
604 | spec->init_hook = preset->init_hook; | 622 | spec->init_hook = preset->init_hook; |
605 | } | 623 | } |
606 | 624 | ||
625 | /* Enable GPIO mask and set output */ | ||
626 | static struct hda_verb alc_gpio1_init_verbs[] = { | ||
627 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
628 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
629 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
630 | { } | ||
631 | }; | ||
632 | |||
633 | static struct hda_verb alc_gpio2_init_verbs[] = { | ||
634 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
635 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
636 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | ||
637 | { } | ||
638 | }; | ||
639 | |||
640 | static struct hda_verb alc_gpio3_init_verbs[] = { | ||
641 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
642 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
643 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
644 | { } | ||
645 | }; | ||
646 | |||
647 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | ||
648 | * 31 ~ 16 : Manufacture ID | ||
649 | * 15 ~ 8 : SKU ID | ||
650 | * 7 ~ 0 : Assembly ID | ||
651 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | ||
652 | */ | ||
653 | static void alc_subsystem_id(struct hda_codec *codec, | ||
654 | unsigned int porta, unsigned int porte, | ||
655 | unsigned int portd) | ||
656 | { | ||
657 | unsigned int ass, tmp; | ||
658 | |||
659 | ass = codec->subsystem_id; | ||
660 | if (!(ass & 1)) | ||
661 | return; | ||
662 | |||
663 | /* Override */ | ||
664 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | ||
665 | switch (tmp) { | ||
666 | case 1: | ||
667 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); | ||
668 | break; | ||
669 | case 3: | ||
670 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | ||
671 | break; | ||
672 | case 7: | ||
673 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | ||
674 | break; | ||
675 | case 5: | ||
676 | switch (codec->vendor_id) { | ||
677 | case 0x10ec0862: | ||
678 | case 0x10ec0660: | ||
679 | case 0x10ec0662: | ||
680 | case 0x10ec0267: | ||
681 | case 0x10ec0268: | ||
682 | snd_hda_codec_write(codec, 0x14, 0, | ||
683 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
684 | snd_hda_codec_write(codec, 0x15, 0, | ||
685 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
686 | return; | ||
687 | } | ||
688 | case 6: | ||
689 | if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ | ||
690 | hda_nid_t port = 0; | ||
691 | tmp = (ass & 0x1800) >> 11; | ||
692 | switch (tmp) { | ||
693 | case 0: port = porta; break; | ||
694 | case 1: port = porte; break; | ||
695 | case 2: port = portd; break; | ||
696 | } | ||
697 | if (port) | ||
698 | snd_hda_codec_write(codec, port, 0, | ||
699 | AC_VERB_SET_EAPD_BTLENABLE, | ||
700 | 2); | ||
701 | } | ||
702 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
703 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, | ||
704 | (tmp == 5 ? 0x3040 : 0x3050)); | ||
705 | break; | ||
706 | } | ||
707 | } | ||
708 | |||
607 | /* | 709 | /* |
608 | * ALC880 3-stack model | 710 | * ALC880 3-stack model |
609 | * | 711 | * |
@@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { | |||
801 | static hda_nid_t alc880_6st_dac_nids[4] = { | 903 | static hda_nid_t alc880_6st_dac_nids[4] = { |
802 | /* front, rear, clfe, rear_surr */ | 904 | /* front, rear, clfe, rear_surr */ |
803 | 0x02, 0x03, 0x04, 0x05 | 905 | 0x02, 0x03, 0x04, 0x05 |
804 | }; | 906 | }; |
805 | 907 | ||
806 | static struct hda_input_mux alc880_6stack_capture_source = { | 908 | static struct hda_input_mux alc880_6stack_capture_source = { |
807 | .num_items = 4, | 909 | .num_items = 4, |
@@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = { | |||
1409 | }; | 1511 | }; |
1410 | 1512 | ||
1411 | /* toggle speaker-output according to the hp-jack state */ | 1513 | /* toggle speaker-output according to the hp-jack state */ |
1412 | static void alc880_uniwill_automute(struct hda_codec *codec) | 1514 | static void alc880_uniwill_hp_automute(struct hda_codec *codec) |
1413 | { | 1515 | { |
1414 | unsigned int present; | 1516 | unsigned int present; |
1517 | unsigned char bits; | ||
1415 | 1518 | ||
1416 | present = snd_hda_codec_read(codec, 0x14, 0, | 1519 | present = snd_hda_codec_read(codec, 0x14, 0, |
1417 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1520 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1521 | bits = present ? 0x80 : 0; | ||
1418 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | 1522 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, |
1419 | 0x80, present ? 0x80 : 0); | 1523 | 0x80, bits); |
1420 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | 1524 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, |
1421 | 0x80, present ? 0x80 : 0); | 1525 | 0x80, bits); |
1422 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, | 1526 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, |
1423 | 0x80, present ? 0x80 : 0); | 1527 | 0x80, bits); |
1424 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, | 1528 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, |
1425 | 0x80, present ? 0x80 : 0); | 1529 | 0x80, bits); |
1530 | } | ||
1531 | |||
1532 | /* auto-toggle front mic */ | ||
1533 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) | ||
1534 | { | ||
1535 | unsigned int present; | ||
1536 | unsigned char bits; | ||
1426 | 1537 | ||
1427 | present = snd_hda_codec_read(codec, 0x18, 0, | 1538 | present = snd_hda_codec_read(codec, 0x18, 0, |
1428 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1539 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1429 | snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1540 | bits = present ? 0x80 : 0; |
1430 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | 1541 | snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, |
1542 | 0x80, bits); | ||
1543 | snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, | ||
1544 | 0x80, bits); | ||
1545 | } | ||
1546 | |||
1547 | static void alc880_uniwill_automute(struct hda_codec *codec) | ||
1548 | { | ||
1549 | alc880_uniwill_hp_automute(codec); | ||
1550 | alc880_uniwill_mic_automute(codec); | ||
1431 | } | 1551 | } |
1432 | 1552 | ||
1433 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | 1553 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, |
@@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
1436 | /* Looks like the unsol event is incompatible with the standard | 1556 | /* Looks like the unsol event is incompatible with the standard |
1437 | * definition. 4bit tag is placed at 28 bit! | 1557 | * definition. 4bit tag is placed at 28 bit! |
1438 | */ | 1558 | */ |
1439 | if ((res >> 28) == ALC880_HP_EVENT || | 1559 | switch (res >> 28) { |
1440 | (res >> 28) == ALC880_MIC_EVENT) | 1560 | case ALC880_HP_EVENT: |
1441 | alc880_uniwill_automute(codec); | 1561 | alc880_uniwill_hp_automute(codec); |
1562 | break; | ||
1563 | case ALC880_MIC_EVENT: | ||
1564 | alc880_uniwill_mic_automute(codec); | ||
1565 | break; | ||
1566 | } | ||
1442 | } | 1567 | } |
1443 | 1568 | ||
1444 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) | 1569 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) |
1445 | { | 1570 | { |
1446 | unsigned int present; | 1571 | unsigned int present; |
1572 | unsigned char bits; | ||
1447 | 1573 | ||
1448 | present = snd_hda_codec_read(codec, 0x14, 0, | 1574 | present = snd_hda_codec_read(codec, 0x14, 0, |
1449 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1575 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1450 | 1576 | bits = present ? 0x80 : 0; | |
1451 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, | 1577 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, |
1452 | 0x80, present ? 0x80 : 0); | 1578 | 0x80, bits); |
1453 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, | 1579 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, |
1454 | 0x80, present ? 0x80 : 0); | 1580 | 0x80, bits); |
1455 | } | 1581 | } |
1456 | 1582 | ||
1457 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 1583 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
1480 | */ | 1606 | */ |
1481 | if ((res >> 28) == ALC880_HP_EVENT) | 1607 | if ((res >> 28) == ALC880_HP_EVENT) |
1482 | alc880_uniwill_p53_hp_automute(codec); | 1608 | alc880_uniwill_p53_hp_automute(codec); |
1483 | if ((res >> 28) == ALC880_DCVOL_EVENT) | 1609 | if ((res >> 28) == ALC880_DCVOL_EVENT) |
1484 | alc880_uniwill_p53_dcvol_automute(codec); | 1610 | alc880_uniwill_p53_dcvol_automute(codec); |
1485 | } | 1611 | } |
1486 | 1612 | ||
@@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { | |||
1547 | }; | 1673 | }; |
1548 | 1674 | ||
1549 | /* Enable GPIO mask and set output */ | 1675 | /* Enable GPIO mask and set output */ |
1550 | static struct hda_verb alc880_gpio1_init_verbs[] = { | 1676 | #define alc880_gpio1_init_verbs alc_gpio1_init_verbs |
1551 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | 1677 | #define alc880_gpio2_init_verbs alc_gpio2_init_verbs |
1552 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
1553 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
1554 | |||
1555 | { } | ||
1556 | }; | ||
1557 | |||
1558 | /* Enable GPIO mask and set output */ | ||
1559 | static struct hda_verb alc880_gpio2_init_verbs[] = { | ||
1560 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
1561 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
1562 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | ||
1563 | |||
1564 | { } | ||
1565 | }; | ||
1566 | 1678 | ||
1567 | /* Clevo m520g init */ | 1679 | /* Clevo m520g init */ |
1568 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { | 1680 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { |
@@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = { | |||
1734 | static void alc880_lg_automute(struct hda_codec *codec) | 1846 | static void alc880_lg_automute(struct hda_codec *codec) |
1735 | { | 1847 | { |
1736 | unsigned int present; | 1848 | unsigned int present; |
1849 | unsigned char bits; | ||
1737 | 1850 | ||
1738 | present = snd_hda_codec_read(codec, 0x1b, 0, | 1851 | present = snd_hda_codec_read(codec, 0x1b, 0, |
1739 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1852 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1853 | bits = present ? 0x80 : 0; | ||
1740 | snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, | 1854 | snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, |
1741 | 0x80, present ? 0x80 : 0); | 1855 | 0x80, bits); |
1742 | snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, | 1856 | snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, |
1743 | 0x80, present ? 0x80 : 0); | 1857 | 0x80, bits); |
1744 | } | 1858 | } |
1745 | 1859 | ||
1746 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | 1860 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
1810 | static void alc880_lg_lw_automute(struct hda_codec *codec) | 1924 | static void alc880_lg_lw_automute(struct hda_codec *codec) |
1811 | { | 1925 | { |
1812 | unsigned int present; | 1926 | unsigned int present; |
1927 | unsigned char bits; | ||
1813 | 1928 | ||
1814 | present = snd_hda_codec_read(codec, 0x1b, 0, | 1929 | present = snd_hda_codec_read(codec, 0x1b, 0, |
1815 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1930 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
1931 | bits = present ? 0x80 : 0; | ||
1816 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | 1932 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, |
1817 | 0x80, present ? 0x80 : 0); | 1933 | 0x80, bits); |
1818 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | 1934 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, |
1819 | 0x80, present ? 0x80 : 0); | 1935 | 0x80, bits); |
1820 | } | 1936 | } |
1821 | 1937 | ||
1822 | static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) | 1938 | static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
1916 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | 2032 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); |
1917 | } | 2033 | } |
1918 | 2034 | ||
2035 | static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2036 | struct hda_codec *codec, | ||
2037 | unsigned int stream_tag, | ||
2038 | unsigned int format, | ||
2039 | struct snd_pcm_substream *substream) | ||
2040 | { | ||
2041 | struct alc_spec *spec = codec->spec; | ||
2042 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
2043 | stream_tag, format, substream); | ||
2044 | } | ||
2045 | |||
1919 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | 2046 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
1920 | struct hda_codec *codec, | 2047 | struct hda_codec *codec, |
1921 | struct snd_pcm_substream *substream) | 2048 | struct snd_pcm_substream *substream) |
@@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { | |||
1984 | /* NID is set in alc_build_pcms */ | 2111 | /* NID is set in alc_build_pcms */ |
1985 | .ops = { | 2112 | .ops = { |
1986 | .open = alc880_dig_playback_pcm_open, | 2113 | .open = alc880_dig_playback_pcm_open, |
1987 | .close = alc880_dig_playback_pcm_close | 2114 | .close = alc880_dig_playback_pcm_close, |
2115 | .prepare = alc880_dig_playback_pcm_prepare | ||
1988 | }, | 2116 | }, |
1989 | }; | 2117 | }; |
1990 | 2118 | ||
@@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec) | |||
2075 | struct alc_spec *spec = codec->spec; | 2203 | struct alc_spec *spec = codec->spec; |
2076 | unsigned int i; | 2204 | unsigned int i; |
2077 | 2205 | ||
2078 | if (! spec) | 2206 | if (!spec) |
2079 | return; | 2207 | return; |
2080 | 2208 | ||
2081 | if (spec->kctl_alloc) { | 2209 | if (spec->kctl_alloc) { |
@@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
2477 | static struct alc_config_preset alc880_presets[] = { | 2605 | static struct alc_config_preset alc880_presets[] = { |
2478 | [ALC880_3ST] = { | 2606 | [ALC880_3ST] = { |
2479 | .mixers = { alc880_three_stack_mixer }, | 2607 | .mixers = { alc880_three_stack_mixer }, |
2480 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, | 2608 | .init_verbs = { alc880_volume_init_verbs, |
2609 | alc880_pin_3stack_init_verbs }, | ||
2481 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2610 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2482 | .dac_nids = alc880_dac_nids, | 2611 | .dac_nids = alc880_dac_nids, |
2483 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 2612 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
@@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2487 | }, | 2616 | }, |
2488 | [ALC880_3ST_DIG] = { | 2617 | [ALC880_3ST_DIG] = { |
2489 | .mixers = { alc880_three_stack_mixer }, | 2618 | .mixers = { alc880_three_stack_mixer }, |
2490 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, | 2619 | .init_verbs = { alc880_volume_init_verbs, |
2620 | alc880_pin_3stack_init_verbs }, | ||
2491 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2621 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2492 | .dac_nids = alc880_dac_nids, | 2622 | .dac_nids = alc880_dac_nids, |
2493 | .dig_out_nid = ALC880_DIGOUT_NID, | 2623 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = { | |||
2509 | .input_mux = &alc880_capture_source, | 2639 | .input_mux = &alc880_capture_source, |
2510 | }, | 2640 | }, |
2511 | [ALC880_5ST] = { | 2641 | [ALC880_5ST] = { |
2512 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, | 2642 | .mixers = { alc880_three_stack_mixer, |
2513 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, | 2643 | alc880_five_stack_mixer}, |
2644 | .init_verbs = { alc880_volume_init_verbs, | ||
2645 | alc880_pin_5stack_init_verbs }, | ||
2514 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2646 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2515 | .dac_nids = alc880_dac_nids, | 2647 | .dac_nids = alc880_dac_nids, |
2516 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | 2648 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), |
@@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = { | |||
2518 | .input_mux = &alc880_capture_source, | 2650 | .input_mux = &alc880_capture_source, |
2519 | }, | 2651 | }, |
2520 | [ALC880_5ST_DIG] = { | 2652 | [ALC880_5ST_DIG] = { |
2521 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, | 2653 | .mixers = { alc880_three_stack_mixer, |
2522 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, | 2654 | alc880_five_stack_mixer }, |
2655 | .init_verbs = { alc880_volume_init_verbs, | ||
2656 | alc880_pin_5stack_init_verbs }, | ||
2523 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 2657 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2524 | .dac_nids = alc880_dac_nids, | 2658 | .dac_nids = alc880_dac_nids, |
2525 | .dig_out_nid = ALC880_DIGOUT_NID, | 2659 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2529 | }, | 2663 | }, |
2530 | [ALC880_6ST] = { | 2664 | [ALC880_6ST] = { |
2531 | .mixers = { alc880_six_stack_mixer }, | 2665 | .mixers = { alc880_six_stack_mixer }, |
2532 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | 2666 | .init_verbs = { alc880_volume_init_verbs, |
2667 | alc880_pin_6stack_init_verbs }, | ||
2533 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | 2668 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), |
2534 | .dac_nids = alc880_6st_dac_nids, | 2669 | .dac_nids = alc880_6st_dac_nids, |
2535 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | 2670 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), |
@@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2538 | }, | 2673 | }, |
2539 | [ALC880_6ST_DIG] = { | 2674 | [ALC880_6ST_DIG] = { |
2540 | .mixers = { alc880_six_stack_mixer }, | 2675 | .mixers = { alc880_six_stack_mixer }, |
2541 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | 2676 | .init_verbs = { alc880_volume_init_verbs, |
2677 | alc880_pin_6stack_init_verbs }, | ||
2542 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | 2678 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), |
2543 | .dac_nids = alc880_6st_dac_nids, | 2679 | .dac_nids = alc880_6st_dac_nids, |
2544 | .dig_out_nid = ALC880_DIGOUT_NID, | 2680 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2548 | }, | 2684 | }, |
2549 | [ALC880_W810] = { | 2685 | [ALC880_W810] = { |
2550 | .mixers = { alc880_w810_base_mixer }, | 2686 | .mixers = { alc880_w810_base_mixer }, |
2551 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, | 2687 | .init_verbs = { alc880_volume_init_verbs, |
2688 | alc880_pin_w810_init_verbs, | ||
2552 | alc880_gpio2_init_verbs }, | 2689 | alc880_gpio2_init_verbs }, |
2553 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 2690 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), |
2554 | .dac_nids = alc880_w810_dac_nids, | 2691 | .dac_nids = alc880_w810_dac_nids, |
@@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2559 | }, | 2696 | }, |
2560 | [ALC880_Z71V] = { | 2697 | [ALC880_Z71V] = { |
2561 | .mixers = { alc880_z71v_mixer }, | 2698 | .mixers = { alc880_z71v_mixer }, |
2562 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, | 2699 | .init_verbs = { alc880_volume_init_verbs, |
2700 | alc880_pin_z71v_init_verbs }, | ||
2563 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), | 2701 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), |
2564 | .dac_nids = alc880_z71v_dac_nids, | 2702 | .dac_nids = alc880_z71v_dac_nids, |
2565 | .dig_out_nid = ALC880_DIGOUT_NID, | 2703 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2570 | }, | 2708 | }, |
2571 | [ALC880_F1734] = { | 2709 | [ALC880_F1734] = { |
2572 | .mixers = { alc880_f1734_mixer }, | 2710 | .mixers = { alc880_f1734_mixer }, |
2573 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, | 2711 | .init_verbs = { alc880_volume_init_verbs, |
2712 | alc880_pin_f1734_init_verbs }, | ||
2574 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), | 2713 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), |
2575 | .dac_nids = alc880_f1734_dac_nids, | 2714 | .dac_nids = alc880_f1734_dac_nids, |
2576 | .hp_nid = 0x02, | 2715 | .hp_nid = 0x02, |
@@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2580 | }, | 2719 | }, |
2581 | [ALC880_ASUS] = { | 2720 | [ALC880_ASUS] = { |
2582 | .mixers = { alc880_asus_mixer }, | 2721 | .mixers = { alc880_asus_mixer }, |
2583 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2722 | .init_verbs = { alc880_volume_init_verbs, |
2723 | alc880_pin_asus_init_verbs, | ||
2584 | alc880_gpio1_init_verbs }, | 2724 | alc880_gpio1_init_verbs }, |
2585 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2725 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2586 | .dac_nids = alc880_asus_dac_nids, | 2726 | .dac_nids = alc880_asus_dac_nids, |
@@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2591 | }, | 2731 | }, |
2592 | [ALC880_ASUS_DIG] = { | 2732 | [ALC880_ASUS_DIG] = { |
2593 | .mixers = { alc880_asus_mixer }, | 2733 | .mixers = { alc880_asus_mixer }, |
2594 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2734 | .init_verbs = { alc880_volume_init_verbs, |
2735 | alc880_pin_asus_init_verbs, | ||
2595 | alc880_gpio1_init_verbs }, | 2736 | alc880_gpio1_init_verbs }, |
2596 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2737 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2597 | .dac_nids = alc880_asus_dac_nids, | 2738 | .dac_nids = alc880_asus_dac_nids, |
@@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2603 | }, | 2744 | }, |
2604 | [ALC880_ASUS_DIG2] = { | 2745 | [ALC880_ASUS_DIG2] = { |
2605 | .mixers = { alc880_asus_mixer }, | 2746 | .mixers = { alc880_asus_mixer }, |
2606 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2747 | .init_verbs = { alc880_volume_init_verbs, |
2748 | alc880_pin_asus_init_verbs, | ||
2607 | alc880_gpio2_init_verbs }, /* use GPIO2 */ | 2749 | alc880_gpio2_init_verbs }, /* use GPIO2 */ |
2608 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2750 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2609 | .dac_nids = alc880_asus_dac_nids, | 2751 | .dac_nids = alc880_asus_dac_nids, |
@@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2615 | }, | 2757 | }, |
2616 | [ALC880_ASUS_W1V] = { | 2758 | [ALC880_ASUS_W1V] = { |
2617 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, | 2759 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, |
2618 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, | 2760 | .init_verbs = { alc880_volume_init_verbs, |
2761 | alc880_pin_asus_init_verbs, | ||
2619 | alc880_gpio1_init_verbs }, | 2762 | alc880_gpio1_init_verbs }, |
2620 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2763 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2621 | .dac_nids = alc880_asus_dac_nids, | 2764 | .dac_nids = alc880_asus_dac_nids, |
@@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2664 | .init_hook = alc880_uniwill_p53_hp_automute, | 2807 | .init_hook = alc880_uniwill_p53_hp_automute, |
2665 | }, | 2808 | }, |
2666 | [ALC880_FUJITSU] = { | 2809 | [ALC880_FUJITSU] = { |
2667 | .mixers = { alc880_fujitsu_mixer, | 2810 | .mixers = { alc880_fujitsu_mixer, |
2668 | alc880_pcbeep_mixer, }, | 2811 | alc880_pcbeep_mixer, }, |
2669 | .init_verbs = { alc880_volume_init_verbs, | 2812 | .init_verbs = { alc880_volume_init_verbs, |
2670 | alc880_uniwill_p53_init_verbs, | 2813 | alc880_uniwill_p53_init_verbs, |
@@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
2707 | .mixers = { alc880_lg_lw_mixer }, | 2850 | .mixers = { alc880_lg_lw_mixer }, |
2708 | .init_verbs = { alc880_volume_init_verbs, | 2851 | .init_verbs = { alc880_volume_init_verbs, |
2709 | alc880_lg_lw_init_verbs }, | 2852 | alc880_lg_lw_init_verbs }, |
2710 | .num_dacs = 1, | 2853 | .num_dacs = 1, |
2711 | .dac_nids = alc880_dac_nids, | 2854 | .dac_nids = alc880_dac_nids, |
2712 | .dig_out_nid = ALC880_DIGOUT_NID, | 2855 | .dig_out_nid = ALC880_DIGOUT_NID, |
2713 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | 2856 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), |
@@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = { | |||
2749 | }; | 2892 | }; |
2750 | 2893 | ||
2751 | /* add dynamic controls */ | 2894 | /* add dynamic controls */ |
2752 | static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) | 2895 | static int add_control(struct alc_spec *spec, int type, const char *name, |
2896 | unsigned long val) | ||
2753 | { | 2897 | { |
2754 | struct snd_kcontrol_new *knew; | 2898 | struct snd_kcontrol_new *knew; |
2755 | 2899 | ||
2756 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | 2900 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { |
2757 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | 2901 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; |
2758 | 2902 | ||
2759 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ | 2903 | /* array + terminator */ |
2760 | if (! knew) | 2904 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); |
2905 | if (!knew) | ||
2761 | return -ENOMEM; | 2906 | return -ENOMEM; |
2762 | if (spec->kctl_alloc) { | 2907 | if (spec->kctl_alloc) { |
2763 | memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); | 2908 | memcpy(knew, spec->kctl_alloc, |
2909 | sizeof(*knew) * spec->num_kctl_alloc); | ||
2764 | kfree(spec->kctl_alloc); | 2910 | kfree(spec->kctl_alloc); |
2765 | } | 2911 | } |
2766 | spec->kctl_alloc = knew; | 2912 | spec->kctl_alloc = knew; |
@@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign | |||
2770 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | 2916 | knew = &spec->kctl_alloc[spec->num_kctl_used]; |
2771 | *knew = alc880_control_templates[type]; | 2917 | *knew = alc880_control_templates[type]; |
2772 | knew->name = kstrdup(name, GFP_KERNEL); | 2918 | knew->name = kstrdup(name, GFP_KERNEL); |
2773 | if (! knew->name) | 2919 | if (!knew->name) |
2774 | return -ENOMEM; | 2920 | return -ENOMEM; |
2775 | knew->private_value = val; | 2921 | knew->private_value = val; |
2776 | spec->num_kctl_used++; | 2922 | spec->num_kctl_used++; |
@@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign | |||
2790 | #define ALC880_PIN_CD_NID 0x1c | 2936 | #define ALC880_PIN_CD_NID 0x1c |
2791 | 2937 | ||
2792 | /* fill in the dac_nids table from the parsed pin configuration */ | 2938 | /* fill in the dac_nids table from the parsed pin configuration */ |
2793 | static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 2939 | static int alc880_auto_fill_dac_nids(struct alc_spec *spec, |
2940 | const struct auto_pin_cfg *cfg) | ||
2794 | { | 2941 | { |
2795 | hda_nid_t nid; | 2942 | hda_nid_t nid; |
2796 | int assigned[4]; | 2943 | int assigned[4]; |
@@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi | |||
2815 | continue; | 2962 | continue; |
2816 | /* search for an empty channel */ | 2963 | /* search for an empty channel */ |
2817 | for (j = 0; j < cfg->line_outs; j++) { | 2964 | for (j = 0; j < cfg->line_outs; j++) { |
2818 | if (! assigned[j]) { | 2965 | if (!assigned[j]) { |
2819 | spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); | 2966 | spec->multiout.dac_nids[i] = |
2967 | alc880_idx_to_dac(j); | ||
2820 | assigned[j] = 1; | 2968 | assigned[j] = 1; |
2821 | break; | 2969 | break; |
2822 | } | 2970 | } |
@@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
2831 | const struct auto_pin_cfg *cfg) | 2979 | const struct auto_pin_cfg *cfg) |
2832 | { | 2980 | { |
2833 | char name[32]; | 2981 | char name[32]; |
2834 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 2982 | static const char *chname[4] = { |
2983 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
2984 | }; | ||
2835 | hda_nid_t nid; | 2985 | hda_nid_t nid; |
2836 | int i, err; | 2986 | int i, err; |
2837 | 2987 | ||
2838 | for (i = 0; i < cfg->line_outs; i++) { | 2988 | for (i = 0; i < cfg->line_outs; i++) { |
2839 | if (! spec->multiout.dac_nids[i]) | 2989 | if (!spec->multiout.dac_nids[i]) |
2840 | continue; | 2990 | continue; |
2841 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | 2991 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); |
2842 | if (i == 2) { | 2992 | if (i == 2) { |
2843 | /* Center/LFE */ | 2993 | /* Center/LFE */ |
2844 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", | 2994 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
2845 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | 2995 | "Center Playback Volume", |
2996 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
2997 | HDA_OUTPUT)); | ||
2998 | if (err < 0) | ||
2846 | return err; | 2999 | return err; |
2847 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", | 3000 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
2848 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 3001 | "LFE Playback Volume", |
3002 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
3003 | HDA_OUTPUT)); | ||
3004 | if (err < 0) | ||
2849 | return err; | 3005 | return err; |
2850 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", | 3006 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
2851 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) | 3007 | "Center Playback Switch", |
3008 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | ||
3009 | HDA_INPUT)); | ||
3010 | if (err < 0) | ||
2852 | return err; | 3011 | return err; |
2853 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", | 3012 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
2854 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) | 3013 | "LFE Playback Switch", |
3014 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | ||
3015 | HDA_INPUT)); | ||
3016 | if (err < 0) | ||
2855 | return err; | 3017 | return err; |
2856 | } else { | 3018 | } else { |
2857 | sprintf(name, "%s Playback Volume", chname[i]); | 3019 | sprintf(name, "%s Playback Volume", chname[i]); |
2858 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3020 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2859 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 3021 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
3022 | HDA_OUTPUT)); | ||
3023 | if (err < 0) | ||
2860 | return err; | 3024 | return err; |
2861 | sprintf(name, "%s Playback Switch", chname[i]); | 3025 | sprintf(name, "%s Playback Switch", chname[i]); |
2862 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 3026 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
2863 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | 3027 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, |
3028 | HDA_INPUT)); | ||
3029 | if (err < 0) | ||
2864 | return err; | 3030 | return err; |
2865 | } | 3031 | } |
2866 | } | 3032 | } |
@@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2875 | int err; | 3041 | int err; |
2876 | char name[32]; | 3042 | char name[32]; |
2877 | 3043 | ||
2878 | if (! pin) | 3044 | if (!pin) |
2879 | return 0; | 3045 | return 0; |
2880 | 3046 | ||
2881 | if (alc880_is_fixed_pin(pin)) { | 3047 | if (alc880_is_fixed_pin(pin)) { |
2882 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 3048 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
2883 | /* specify the DAC as the extra output */ | 3049 | /* specify the DAC as the extra output */ |
2884 | if (! spec->multiout.hp_nid) | 3050 | if (!spec->multiout.hp_nid) |
2885 | spec->multiout.hp_nid = nid; | 3051 | spec->multiout.hp_nid = nid; |
2886 | else | 3052 | else |
2887 | spec->multiout.extra_out_nid[0] = nid; | 3053 | spec->multiout.extra_out_nid[0] = nid; |
2888 | /* control HP volume/switch on the output mixer amp */ | 3054 | /* control HP volume/switch on the output mixer amp */ |
2889 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | 3055 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); |
2890 | sprintf(name, "%s Playback Volume", pfx); | 3056 | sprintf(name, "%s Playback Volume", pfx); |
2891 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3057 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2892 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 3058 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); |
3059 | if (err < 0) | ||
2893 | return err; | 3060 | return err; |
2894 | sprintf(name, "%s Playback Switch", pfx); | 3061 | sprintf(name, "%s Playback Switch", pfx); |
2895 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 3062 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
2896 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | 3063 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); |
3064 | if (err < 0) | ||
2897 | return err; | 3065 | return err; |
2898 | } else if (alc880_is_multi_pin(pin)) { | 3066 | } else if (alc880_is_multi_pin(pin)) { |
2899 | /* set manual connection */ | 3067 | /* set manual connection */ |
2900 | /* we have only a switch on HP-out PIN */ | 3068 | /* we have only a switch on HP-out PIN */ |
2901 | sprintf(name, "%s Playback Switch", pfx); | 3069 | sprintf(name, "%s Playback Switch", pfx); |
2902 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 3070 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
2903 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) | 3071 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
3072 | if (err < 0) | ||
2904 | return err; | 3073 | return err; |
2905 | } | 3074 | } |
2906 | return 0; | 3075 | return 0; |
2907 | } | 3076 | } |
2908 | 3077 | ||
2909 | /* create input playback/capture controls for the given pin */ | 3078 | /* create input playback/capture controls for the given pin */ |
2910 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, | 3079 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
3080 | const char *ctlname, | ||
2911 | int idx, hda_nid_t mix_nid) | 3081 | int idx, hda_nid_t mix_nid) |
2912 | { | 3082 | { |
2913 | char name[32]; | 3083 | char name[32]; |
2914 | int err; | 3084 | int err; |
2915 | 3085 | ||
2916 | sprintf(name, "%s Playback Volume", ctlname); | 3086 | sprintf(name, "%s Playback Volume", ctlname); |
2917 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 3087 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
2918 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) | 3088 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
3089 | if (err < 0) | ||
2919 | return err; | 3090 | return err; |
2920 | sprintf(name, "%s Playback Switch", ctlname); | 3091 | sprintf(name, "%s Playback Switch", ctlname); |
2921 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 3092 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
2922 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) | 3093 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
3094 | if (err < 0) | ||
2923 | return err; | 3095 | return err; |
2924 | return 0; | 3096 | return 0; |
2925 | } | 3097 | } |
@@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
2939 | idx, 0x0b); | 3111 | idx, 0x0b); |
2940 | if (err < 0) | 3112 | if (err < 0) |
2941 | return err; | 3113 | return err; |
2942 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 3114 | imux->items[imux->num_items].label = |
2943 | imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); | 3115 | auto_pin_cfg_labels[i]; |
3116 | imux->items[imux->num_items].index = | ||
3117 | alc880_input_pin_idx(cfg->input_pins[i]); | ||
2944 | imux->num_items++; | 3118 | imux->num_items++; |
2945 | } | 3119 | } |
2946 | } | 3120 | } |
@@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, | |||
2952 | int dac_idx) | 3126 | int dac_idx) |
2953 | { | 3127 | { |
2954 | /* set as output */ | 3128 | /* set as output */ |
2955 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 3129 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2956 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 3130 | pin_type); |
3131 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3132 | AMP_OUT_UNMUTE); | ||
2957 | /* need the manual connection? */ | 3133 | /* need the manual connection? */ |
2958 | if (alc880_is_multi_pin(nid)) { | 3134 | if (alc880_is_multi_pin(nid)) { |
2959 | struct alc_spec *spec = codec->spec; | 3135 | struct alc_spec *spec = codec->spec; |
@@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, | |||
2964 | } | 3140 | } |
2965 | } | 3141 | } |
2966 | 3142 | ||
3143 | static int get_pin_type(int line_out_type) | ||
3144 | { | ||
3145 | if (line_out_type == AUTO_PIN_HP_OUT) | ||
3146 | return PIN_HP; | ||
3147 | else | ||
3148 | return PIN_OUT; | ||
3149 | } | ||
3150 | |||
2967 | static void alc880_auto_init_multi_out(struct hda_codec *codec) | 3151 | static void alc880_auto_init_multi_out(struct hda_codec *codec) |
2968 | { | 3152 | { |
2969 | struct alc_spec *spec = codec->spec; | 3153 | struct alc_spec *spec = codec->spec; |
2970 | int i; | 3154 | int i; |
2971 | 3155 | ||
3156 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
2972 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 3157 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
2973 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 3158 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
2974 | alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 3159 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
3160 | alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); | ||
2975 | } | 3161 | } |
2976 | } | 3162 | } |
2977 | 3163 | ||
@@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
2996 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 3182 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
2997 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 3183 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
2998 | if (alc880_is_input_pin(nid)) { | 3184 | if (alc880_is_input_pin(nid)) { |
2999 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3185 | snd_hda_codec_write(codec, nid, 0, |
3000 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 3186 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
3187 | i <= AUTO_PIN_FRONT_MIC ? | ||
3188 | PIN_VREF80 : PIN_IN); | ||
3001 | if (nid != ALC880_PIN_CD_NID) | 3189 | if (nid != ALC880_PIN_CD_NID) |
3002 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 3190 | snd_hda_codec_write(codec, nid, 0, |
3191 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
3003 | AMP_OUT_MUTE); | 3192 | AMP_OUT_MUTE); |
3004 | } | 3193 | } |
3005 | } | 3194 | } |
3006 | } | 3195 | } |
3007 | 3196 | ||
3008 | /* parse the BIOS configuration and set up the alc_spec */ | 3197 | /* parse the BIOS configuration and set up the alc_spec */ |
3009 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | 3198 | /* return 1 if successful, 0 if the proper config is not found, |
3199 | * or a negative error code | ||
3200 | */ | ||
3010 | static int alc880_parse_auto_config(struct hda_codec *codec) | 3201 | static int alc880_parse_auto_config(struct hda_codec *codec) |
3011 | { | 3202 | { |
3012 | struct alc_spec *spec = codec->spec; | 3203 | struct alc_spec *spec = codec->spec; |
3013 | int err; | 3204 | int err; |
3014 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 3205 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
3015 | 3206 | ||
3016 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 3207 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
3017 | alc880_ignore)) < 0) | 3208 | alc880_ignore); |
3209 | if (err < 0) | ||
3018 | return err; | 3210 | return err; |
3019 | if (! spec->autocfg.line_outs) | 3211 | if (!spec->autocfg.line_outs) |
3020 | return 0; /* can't find valid BIOS pin config */ | 3212 | return 0; /* can't find valid BIOS pin config */ |
3021 | 3213 | ||
3022 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 3214 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
3023 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 3215 | if (err < 0) |
3024 | (err = alc880_auto_create_extra_out(spec, | 3216 | return err; |
3025 | spec->autocfg.speaker_pins[0], | 3217 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); |
3026 | "Speaker")) < 0 || | 3218 | if (err < 0) |
3027 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | 3219 | return err; |
3028 | "Headphone")) < 0 || | 3220 | err = alc880_auto_create_extra_out(spec, |
3029 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 3221 | spec->autocfg.speaker_pins[0], |
3222 | "Speaker"); | ||
3223 | if (err < 0) | ||
3224 | return err; | ||
3225 | err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | ||
3226 | "Headphone"); | ||
3227 | if (err < 0) | ||
3228 | return err; | ||
3229 | err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
3230 | if (err < 0) | ||
3030 | return err; | 3231 | return err; |
3031 | 3232 | ||
3032 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3233 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
3086 | if (err < 0) { | 3287 | if (err < 0) { |
3087 | alc_free(codec); | 3288 | alc_free(codec); |
3088 | return err; | 3289 | return err; |
3089 | } else if (! err) { | 3290 | } else if (!err) { |
3090 | printk(KERN_INFO | 3291 | printk(KERN_INFO |
3091 | "hda_codec: Cannot set up configuration " | 3292 | "hda_codec: Cannot set up configuration " |
3092 | "from BIOS. Using 3-stack mode...\n"); | 3293 | "from BIOS. Using 3-stack mode...\n"); |
@@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec) | |||
3105 | spec->stream_digital_playback = &alc880_pcm_digital_playback; | 3306 | spec->stream_digital_playback = &alc880_pcm_digital_playback; |
3106 | spec->stream_digital_capture = &alc880_pcm_digital_capture; | 3307 | spec->stream_digital_capture = &alc880_pcm_digital_capture; |
3107 | 3308 | ||
3108 | if (! spec->adc_nids && spec->input_mux) { | 3309 | if (!spec->adc_nids && spec->input_mux) { |
3109 | /* check whether NID 0x07 is valid */ | 3310 | /* check whether NID 0x07 is valid */ |
3110 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); | 3311 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); |
3111 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 3312 | /* get type */ |
3313 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
3112 | if (wcap != AC_WID_AUD_IN) { | 3314 | if (wcap != AC_WID_AUD_IN) { |
3113 | spec->adc_nids = alc880_adc_nids_alt; | 3315 | spec->adc_nids = alc880_adc_nids_alt; |
3114 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); | 3316 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); |
3115 | spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; | 3317 | spec->mixers[spec->num_mixers] = |
3318 | alc880_capture_alt_mixer; | ||
3116 | spec->num_mixers++; | 3319 | spec->num_mixers++; |
3117 | } else { | 3320 | } else { |
3118 | spec->adc_nids = alc880_adc_nids; | 3321 | spec->adc_nids = alc880_adc_nids; |
@@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { | |||
3254 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 3457 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
3255 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 3458 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
3256 | { } /* end */ | 3459 | { } /* end */ |
3257 | }; | 3460 | }; |
3258 | 3461 | ||
3259 | static struct snd_kcontrol_new alc260_input_mixer[] = { | 3462 | static struct snd_kcontrol_new alc260_input_mixer[] = { |
3260 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 3463 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
@@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { | |||
3349 | { } /* end */ | 3552 | { } /* end */ |
3350 | }; | 3553 | }; |
3351 | 3554 | ||
3555 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, | ||
3556 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. | ||
3557 | */ | ||
3558 | static struct snd_kcontrol_new alc260_will_mixer[] = { | ||
3559 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
3560 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
3561 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
3562 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
3563 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
3564 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
3565 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
3566 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
3567 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
3568 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
3569 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
3570 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
3571 | { } /* end */ | ||
3572 | }; | ||
3573 | |||
3574 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, | ||
3575 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | ||
3576 | */ | ||
3577 | static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | ||
3578 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
3579 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
3580 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
3581 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
3582 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
3583 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), | ||
3584 | HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), | ||
3585 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
3586 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
3587 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
3588 | { } /* end */ | ||
3589 | }; | ||
3590 | |||
3352 | /* capture mixer elements */ | 3591 | /* capture mixer elements */ |
3353 | static struct snd_kcontrol_new alc260_capture_mixer[] = { | 3592 | static struct snd_kcontrol_new alc260_capture_mixer[] = { |
3354 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 3593 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
@@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = { | |||
3434 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3673 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3435 | /* unmute LINE-2 out pin */ | 3674 | /* unmute LINE-2 out pin */ |
3436 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3675 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3437 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3676 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3677 | * Line In 2 = 0x03 | ||
3678 | */ | ||
3438 | /* mute CD */ | 3679 | /* mute CD */ |
3439 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 3680 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
3440 | /* mute Line In */ | 3681 | /* mute Line In */ |
@@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = { | |||
3482 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 3723 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
3483 | /* mute pin widget amp left and right (no gain on this amp) */ | 3724 | /* mute pin widget amp left and right (no gain on this amp) */ |
3484 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | 3725 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, |
3485 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3726 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3727 | * Line In 2 = 0x03 | ||
3728 | */ | ||
3486 | /* unmute CD */ | 3729 | /* unmute CD */ |
3487 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 3730 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, |
3488 | /* unmute Line In */ | 3731 | /* unmute Line In */ |
@@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { | |||
3530 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 3773 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
3531 | /* mute pin widget amp left and right (no gain on this amp) */ | 3774 | /* mute pin widget amp left and right (no gain on this amp) */ |
3532 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | 3775 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, |
3533 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 3776 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & |
3777 | * Line In 2 = 0x03 | ||
3778 | */ | ||
3534 | /* unmute CD */ | 3779 | /* unmute CD */ |
3535 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 3780 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, |
3536 | /* unmute Line In */ | 3781 | /* unmute Line In */ |
@@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3680 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 3925 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
3681 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 3926 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
3682 | 3927 | ||
3683 | /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ | 3928 | /* Unmute Line-out pin widget amp left and right |
3929 | * (no equiv mixer ctrl) | ||
3930 | */ | ||
3684 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3931 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3685 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ | 3932 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ |
3686 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3933 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3719 | { } | 3966 | { } |
3720 | }; | 3967 | }; |
3721 | 3968 | ||
3969 | static struct hda_verb alc260_will_verbs[] = { | ||
3970 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3971 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3972 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3973 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
3974 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
3975 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, | ||
3976 | {} | ||
3977 | }; | ||
3978 | |||
3979 | static struct hda_verb alc260_replacer_672v_verbs[] = { | ||
3980 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
3981 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
3982 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, | ||
3983 | |||
3984 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
3985 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
3986 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
3987 | |||
3988 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
3989 | {} | ||
3990 | }; | ||
3991 | |||
3992 | /* toggle speaker-output according to the hp-jack state */ | ||
3993 | static void alc260_replacer_672v_automute(struct hda_codec *codec) | ||
3994 | { | ||
3995 | unsigned int present; | ||
3996 | |||
3997 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | ||
3998 | present = snd_hda_codec_read(codec, 0x0f, 0, | ||
3999 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
4000 | if (present) { | ||
4001 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); | ||
4002 | snd_hda_codec_write(codec, 0x0f, 0, | ||
4003 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
4004 | } else { | ||
4005 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | ||
4006 | snd_hda_codec_write(codec, 0x0f, 0, | ||
4007 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
4008 | } | ||
4009 | } | ||
4010 | |||
4011 | static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | ||
4012 | unsigned int res) | ||
4013 | { | ||
4014 | if ((res >> 26) == ALC880_HP_EVENT) | ||
4015 | alc260_replacer_672v_automute(codec); | ||
4016 | } | ||
4017 | |||
3722 | /* Test configuration for debugging, modelled after the ALC880 test | 4018 | /* Test configuration for debugging, modelled after the ALC880 test |
3723 | * configuration. | 4019 | * configuration. |
3724 | */ | 4020 | */ |
@@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | |||
3946 | return 0; /* N/A */ | 4242 | return 0; /* N/A */ |
3947 | 4243 | ||
3948 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | 4244 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); |
3949 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) | 4245 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); |
4246 | if (err < 0) | ||
3950 | return err; | 4247 | return err; |
3951 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | 4248 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); |
3952 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) | 4249 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); |
4250 | if (err < 0) | ||
3953 | return err; | 4251 | return err; |
3954 | return 1; | 4252 | return 1; |
3955 | } | 4253 | } |
@@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
3985 | if (err < 0) | 4283 | if (err < 0) |
3986 | return err; | 4284 | return err; |
3987 | } | 4285 | } |
3988 | return 0; | 4286 | return 0; |
3989 | } | 4287 | } |
3990 | 4288 | ||
3991 | /* create playback/capture controls for input pins */ | 4289 | /* create playback/capture controls for input pins */ |
@@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
3999 | if (cfg->input_pins[i] >= 0x12) { | 4297 | if (cfg->input_pins[i] >= 0x12) { |
4000 | idx = cfg->input_pins[i] - 0x12; | 4298 | idx = cfg->input_pins[i] - 0x12; |
4001 | err = new_analog_input(spec, cfg->input_pins[i], | 4299 | err = new_analog_input(spec, cfg->input_pins[i], |
4002 | auto_pin_cfg_labels[i], idx, 0x07); | 4300 | auto_pin_cfg_labels[i], idx, |
4301 | 0x07); | ||
4003 | if (err < 0) | 4302 | if (err < 0) |
4004 | return err; | 4303 | return err; |
4005 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 4304 | imux->items[imux->num_items].label = |
4305 | auto_pin_cfg_labels[i]; | ||
4006 | imux->items[imux->num_items].index = idx; | 4306 | imux->items[imux->num_items].index = idx; |
4007 | imux->num_items++; | 4307 | imux->num_items++; |
4008 | } | 4308 | } |
4009 | if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ | 4309 | if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ |
4010 | idx = cfg->input_pins[i] - 0x09; | 4310 | idx = cfg->input_pins[i] - 0x09; |
4011 | err = new_analog_input(spec, cfg->input_pins[i], | 4311 | err = new_analog_input(spec, cfg->input_pins[i], |
4012 | auto_pin_cfg_labels[i], idx, 0x07); | 4312 | auto_pin_cfg_labels[i], idx, |
4313 | 0x07); | ||
4013 | if (err < 0) | 4314 | if (err < 0) |
4014 | return err; | 4315 | return err; |
4015 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 4316 | imux->items[imux->num_items].label = |
4317 | auto_pin_cfg_labels[i]; | ||
4016 | imux->items[imux->num_items].index = idx; | 4318 | imux->items[imux->num_items].index = idx; |
4017 | imux->num_items++; | 4319 | imux->num_items++; |
4018 | } | 4320 | } |
@@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, | |||
4025 | int sel_idx) | 4327 | int sel_idx) |
4026 | { | 4328 | { |
4027 | /* set as output */ | 4329 | /* set as output */ |
4028 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 4330 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
4029 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 4331 | pin_type); |
4332 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
4333 | AMP_OUT_UNMUTE); | ||
4030 | /* need the manual connection? */ | 4334 | /* need the manual connection? */ |
4031 | if (nid >= 0x12) { | 4335 | if (nid >= 0x12) { |
4032 | int idx = nid - 0x12; | 4336 | int idx = nid - 0x12; |
4033 | snd_hda_codec_write(codec, idx + 0x0b, 0, | 4337 | snd_hda_codec_write(codec, idx + 0x0b, 0, |
4034 | AC_VERB_SET_CONNECT_SEL, sel_idx); | 4338 | AC_VERB_SET_CONNECT_SEL, sel_idx); |
4035 | |||
4036 | } | 4339 | } |
4037 | } | 4340 | } |
4038 | 4341 | ||
@@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
4041 | struct alc_spec *spec = codec->spec; | 4344 | struct alc_spec *spec = codec->spec; |
4042 | hda_nid_t nid; | 4345 | hda_nid_t nid; |
4043 | 4346 | ||
4044 | nid = spec->autocfg.line_out_pins[0]; | 4347 | alc_subsystem_id(codec, 0x10, 0x15, 0x0f); |
4045 | if (nid) | 4348 | nid = spec->autocfg.line_out_pins[0]; |
4046 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 4349 | if (nid) { |
4350 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
4351 | alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); | ||
4352 | } | ||
4047 | 4353 | ||
4048 | nid = spec->autocfg.speaker_pins[0]; | 4354 | nid = spec->autocfg.speaker_pins[0]; |
4049 | if (nid) | 4355 | if (nid) |
@@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
4051 | 4357 | ||
4052 | nid = spec->autocfg.hp_pins[0]; | 4358 | nid = spec->autocfg.hp_pins[0]; |
4053 | if (nid) | 4359 | if (nid) |
4054 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 4360 | alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); |
4055 | } | 4361 | } |
4056 | 4362 | ||
4057 | #define ALC260_PIN_CD_NID 0x16 | 4363 | #define ALC260_PIN_CD_NID 0x16 |
4058 | static void alc260_auto_init_analog_input(struct hda_codec *codec) | 4364 | static void alc260_auto_init_analog_input(struct hda_codec *codec) |
@@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
4063 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4369 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4064 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 4370 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
4065 | if (nid >= 0x12) { | 4371 | if (nid >= 0x12) { |
4066 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 4372 | snd_hda_codec_write(codec, nid, 0, |
4067 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 4373 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
4374 | i <= AUTO_PIN_FRONT_MIC ? | ||
4375 | PIN_VREF80 : PIN_IN); | ||
4068 | if (nid != ALC260_PIN_CD_NID) | 4376 | if (nid != ALC260_PIN_CD_NID) |
4069 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 4377 | snd_hda_codec_write(codec, nid, 0, |
4378 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4070 | AMP_OUT_MUTE); | 4379 | AMP_OUT_MUTE); |
4071 | } | 4380 | } |
4072 | } | 4381 | } |
@@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = { | |||
4086 | 4395 | ||
4087 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 4396 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
4088 | * mixer widget | 4397 | * mixer widget |
4089 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 4398 | * Note: PASD motherboards uses the Line In 2 as the input for |
4090 | * mic (mic 2) | 4399 | * front panel mic (mic 2) |
4091 | */ | 4400 | */ |
4092 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 4401 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
4093 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4402 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
4122 | int err; | 4431 | int err; |
4123 | static hda_nid_t alc260_ignore[] = { 0x17, 0 }; | 4432 | static hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
4124 | 4433 | ||
4125 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 4434 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
4126 | alc260_ignore)) < 0) | 4435 | alc260_ignore); |
4436 | if (err < 0) | ||
4127 | return err; | 4437 | return err; |
4128 | if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) | 4438 | err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); |
4439 | if (err < 0) | ||
4129 | return err; | 4440 | return err; |
4130 | if (! spec->kctl_alloc) | 4441 | if (!spec->kctl_alloc) |
4131 | return 0; /* can't find valid BIOS pin config */ | 4442 | return 0; /* can't find valid BIOS pin config */ |
4132 | if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 4443 | err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); |
4444 | if (err < 0) | ||
4133 | return err; | 4445 | return err; |
4134 | 4446 | ||
4135 | spec->multiout.max_channels = 2; | 4447 | spec->multiout.max_channels = 2; |
@@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { | |||
4177 | [ALC260_HP_3013] = "hp-3013", | 4489 | [ALC260_HP_3013] = "hp-3013", |
4178 | [ALC260_FUJITSU_S702X] = "fujitsu", | 4490 | [ALC260_FUJITSU_S702X] = "fujitsu", |
4179 | [ALC260_ACER] = "acer", | 4491 | [ALC260_ACER] = "acer", |
4492 | [ALC260_WILL] = "will", | ||
4493 | [ALC260_REPLACER_672V] = "replacer", | ||
4180 | #ifdef CONFIG_SND_DEBUG | 4494 | #ifdef CONFIG_SND_DEBUG |
4181 | [ALC260_TEST] = "test", | 4495 | [ALC260_TEST] = "test", |
4182 | #endif | 4496 | #endif |
@@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
4200 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | 4514 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), |
4201 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | 4515 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), |
4202 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | 4516 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), |
4517 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), | ||
4518 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), | ||
4203 | {} | 4519 | {} |
4204 | }; | 4520 | }; |
4205 | 4521 | ||
@@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = { | |||
4270 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), | 4586 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), |
4271 | .input_mux = alc260_acer_capture_sources, | 4587 | .input_mux = alc260_acer_capture_sources, |
4272 | }, | 4588 | }, |
4589 | [ALC260_WILL] = { | ||
4590 | .mixers = { alc260_will_mixer, | ||
4591 | alc260_capture_mixer }, | ||
4592 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, | ||
4593 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
4594 | .dac_nids = alc260_dac_nids, | ||
4595 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
4596 | .adc_nids = alc260_adc_nids, | ||
4597 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
4598 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
4599 | .channel_mode = alc260_modes, | ||
4600 | .input_mux = &alc260_capture_source, | ||
4601 | }, | ||
4602 | [ALC260_REPLACER_672V] = { | ||
4603 | .mixers = { alc260_replacer_672v_mixer, | ||
4604 | alc260_capture_mixer }, | ||
4605 | .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, | ||
4606 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
4607 | .dac_nids = alc260_dac_nids, | ||
4608 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
4609 | .adc_nids = alc260_adc_nids, | ||
4610 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
4611 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
4612 | .channel_mode = alc260_modes, | ||
4613 | .input_mux = &alc260_capture_source, | ||
4614 | .unsol_event = alc260_replacer_672v_unsol_event, | ||
4615 | .init_hook = alc260_replacer_672v_automute, | ||
4616 | }, | ||
4273 | #ifdef CONFIG_SND_DEBUG | 4617 | #ifdef CONFIG_SND_DEBUG |
4274 | [ALC260_TEST] = { | 4618 | [ALC260_TEST] = { |
4275 | .mixers = { alc260_test_mixer, | 4619 | .mixers = { alc260_test_mixer, |
@@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
4313 | if (err < 0) { | 4657 | if (err < 0) { |
4314 | alc_free(codec); | 4658 | alc_free(codec); |
4315 | return err; | 4659 | return err; |
4316 | } else if (! err) { | 4660 | } else if (!err) { |
4317 | printk(KERN_INFO | 4661 | printk(KERN_INFO |
4318 | "hda_codec: Cannot set up configuration " | 4662 | "hda_codec: Cannot set up configuration " |
4319 | "from BIOS. Using base mode...\n"); | 4663 | "from BIOS. Using base mode...\n"); |
@@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = { | |||
4382 | #define alc882_mux_enum_info alc_mux_enum_info | 4726 | #define alc882_mux_enum_info alc_mux_enum_info |
4383 | #define alc882_mux_enum_get alc_mux_enum_get | 4727 | #define alc882_mux_enum_get alc_mux_enum_get |
4384 | 4728 | ||
4385 | static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 4729 | static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, |
4730 | struct snd_ctl_elem_value *ucontrol) | ||
4386 | { | 4731 | { |
4387 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 4732 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
4388 | struct alc_spec *spec = codec->spec; | 4733 | struct alc_spec *spec = codec->spec; |
@@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
4396 | idx = ucontrol->value.enumerated.item[0]; | 4741 | idx = ucontrol->value.enumerated.item[0]; |
4397 | if (idx >= imux->num_items) | 4742 | if (idx >= imux->num_items) |
4398 | idx = imux->num_items - 1; | 4743 | idx = imux->num_items - 1; |
4399 | if (*cur_val == idx && ! codec->in_resume) | 4744 | if (*cur_val == idx && !codec->in_resume) |
4400 | return 0; | 4745 | return 0; |
4401 | for (i = 0; i < imux->num_items; i++) { | 4746 | for (i = 0; i < imux->num_items; i++) { |
4402 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 4747 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { | |||
4464 | { } /* end */ | 4809 | { } /* end */ |
4465 | }; | 4810 | }; |
4466 | 4811 | ||
4812 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | ||
4813 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4814 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4815 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4816 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4817 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4818 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4819 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4820 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4821 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4822 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4823 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4824 | { } /* end */ | ||
4825 | }; | ||
4826 | |||
4467 | static struct snd_kcontrol_new alc882_chmode_mixer[] = { | 4827 | static struct snd_kcontrol_new alc882_chmode_mixer[] = { |
4468 | { | 4828 | { |
4469 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 4829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = { | |||
4559 | /* change to EAPD mode */ | 4919 | /* change to EAPD mode */ |
4560 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 4920 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
4561 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | 4921 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, |
4562 | { } | 4922 | { } |
4563 | }; | 4923 | }; |
4564 | 4924 | ||
4565 | /* Mac Pro test */ | 4925 | /* Mac Pro test */ |
@@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
4624 | 4984 | ||
4625 | { } | 4985 | { } |
4626 | }; | 4986 | }; |
4987 | |||
4627 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | 4988 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) |
4628 | { | 4989 | { |
4629 | unsigned int gpiostate, gpiomask, gpiodir; | 4990 | unsigned int gpiostate, gpiomask, gpiodir; |
@@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = { | |||
4672 | 5033 | ||
4673 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 5034 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
4674 | * mixer widget | 5035 | * mixer widget |
4675 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 5036 | * Note: PASD motherboards uses the Line In 2 as the input for |
4676 | * mic (mic 2) | 5037 | * front panel mic (mic 2) |
4677 | */ | 5038 | */ |
4678 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 5039 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
4679 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5040 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
4782 | [ALC882_3ST_DIG] = "3stack-dig", | 5143 | [ALC882_3ST_DIG] = "3stack-dig", |
4783 | [ALC882_6ST_DIG] = "6stack-dig", | 5144 | [ALC882_6ST_DIG] = "6stack-dig", |
4784 | [ALC882_ARIMA] = "arima", | 5145 | [ALC882_ARIMA] = "arima", |
5146 | [ALC882_W2JC] = "w2jc", | ||
4785 | [ALC885_MACPRO] = "macpro", | 5147 | [ALC885_MACPRO] = "macpro", |
4786 | [ALC882_AUTO] = "auto", | 5148 | [ALC882_AUTO] = "auto", |
4787 | }; | 5149 | }; |
@@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
4792 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), | 5154 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), |
4793 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), | 5155 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), |
4794 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | 5156 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), |
5157 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), | ||
4795 | {} | 5158 | {} |
4796 | }; | 5159 | }; |
4797 | 5160 | ||
@@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = { | |||
4828 | .channel_mode = alc882_sixstack_modes, | 5191 | .channel_mode = alc882_sixstack_modes, |
4829 | .input_mux = &alc882_capture_source, | 5192 | .input_mux = &alc882_capture_source, |
4830 | }, | 5193 | }, |
5194 | [ALC882_W2JC] = { | ||
5195 | .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, | ||
5196 | .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, | ||
5197 | alc880_gpio1_init_verbs }, | ||
5198 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
5199 | .dac_nids = alc882_dac_nids, | ||
5200 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
5201 | .channel_mode = alc880_threestack_modes, | ||
5202 | .need_dac_fix = 1, | ||
5203 | .input_mux = &alc882_capture_source, | ||
5204 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
5205 | }, | ||
4831 | [ALC885_MACPRO] = { | 5206 | [ALC885_MACPRO] = { |
4832 | .mixers = { alc882_macpro_mixer }, | 5207 | .mixers = { alc882_macpro_mixer }, |
4833 | .init_verbs = { alc882_macpro_init_verbs }, | 5208 | .init_verbs = { alc882_macpro_init_verbs }, |
@@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | |||
4851 | { | 5226 | { |
4852 | /* set as output */ | 5227 | /* set as output */ |
4853 | struct alc_spec *spec = codec->spec; | 5228 | struct alc_spec *spec = codec->spec; |
4854 | int idx; | 5229 | int idx; |
4855 | 5230 | ||
4856 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 5231 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
4857 | idx = 4; | 5232 | idx = 4; |
4858 | else | 5233 | else |
4859 | idx = spec->multiout.dac_nids[dac_idx] - 2; | 5234 | idx = spec->multiout.dac_nids[dac_idx] - 2; |
4860 | 5235 | ||
4861 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 5236 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
4862 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 5237 | pin_type); |
5238 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5239 | AMP_OUT_UNMUTE); | ||
4863 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | 5240 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); |
4864 | 5241 | ||
4865 | } | 5242 | } |
@@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) | |||
4869 | struct alc_spec *spec = codec->spec; | 5246 | struct alc_spec *spec = codec->spec; |
4870 | int i; | 5247 | int i; |
4871 | 5248 | ||
5249 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
4872 | for (i = 0; i <= HDA_SIDE; i++) { | 5250 | for (i = 0; i <= HDA_SIDE; i++) { |
4873 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 5251 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
5252 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
4874 | if (nid) | 5253 | if (nid) |
4875 | alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 5254 | alc882_auto_set_output_and_unmute(codec, nid, pin_type, |
5255 | i); | ||
4876 | } | 5256 | } |
4877 | } | 5257 | } |
4878 | 5258 | ||
@@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) | |||
4883 | 5263 | ||
4884 | pin = spec->autocfg.hp_pins[0]; | 5264 | pin = spec->autocfg.hp_pins[0]; |
4885 | if (pin) /* connect to front */ | 5265 | if (pin) /* connect to front */ |
4886 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ | 5266 | /* use dac 0 */ |
5267 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
4887 | } | 5268 | } |
4888 | 5269 | ||
4889 | #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) | 5270 | #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) |
@@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) | |||
4897 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5278 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4898 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5279 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
4899 | if (alc882_is_input_pin(nid)) { | 5280 | if (alc882_is_input_pin(nid)) { |
4900 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 5281 | snd_hda_codec_write(codec, nid, 0, |
4901 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 5282 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
5283 | i <= AUTO_PIN_FRONT_MIC ? | ||
5284 | PIN_VREF80 : PIN_IN); | ||
4902 | if (nid != ALC882_PIN_CD_NID) | 5285 | if (nid != ALC882_PIN_CD_NID) |
4903 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 5286 | snd_hda_codec_write(codec, nid, 0, |
5287 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4904 | AMP_OUT_MUTE); | 5288 | AMP_OUT_MUTE); |
4905 | } | 5289 | } |
4906 | } | 5290 | } |
@@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
4962 | if (err < 0) { | 5346 | if (err < 0) { |
4963 | alc_free(codec); | 5347 | alc_free(codec); |
4964 | return err; | 5348 | return err; |
4965 | } else if (! err) { | 5349 | } else if (!err) { |
4966 | printk(KERN_INFO | 5350 | printk(KERN_INFO |
4967 | "hda_codec: Cannot set up configuration " | 5351 | "hda_codec: Cannot set up configuration " |
4968 | "from BIOS. Using base mode...\n"); | 5352 | "from BIOS. Using base mode...\n"); |
@@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec) | |||
4986 | spec->stream_digital_playback = &alc882_pcm_digital_playback; | 5370 | spec->stream_digital_playback = &alc882_pcm_digital_playback; |
4987 | spec->stream_digital_capture = &alc882_pcm_digital_capture; | 5371 | spec->stream_digital_capture = &alc882_pcm_digital_capture; |
4988 | 5372 | ||
4989 | if (! spec->adc_nids && spec->input_mux) { | 5373 | if (!spec->adc_nids && spec->input_mux) { |
4990 | /* check whether NID 0x07 is valid */ | 5374 | /* check whether NID 0x07 is valid */ |
4991 | unsigned int wcap = get_wcaps(codec, 0x07); | 5375 | unsigned int wcap = get_wcaps(codec, 0x07); |
4992 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 5376 | /* get type */ |
5377 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
4993 | if (wcap != AC_WID_AUD_IN) { | 5378 | if (wcap != AC_WID_AUD_IN) { |
4994 | spec->adc_nids = alc882_adc_nids_alt; | 5379 | spec->adc_nids = alc882_adc_nids_alt; |
4995 | spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); | 5380 | spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); |
4996 | spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; | 5381 | spec->mixers[spec->num_mixers] = |
5382 | alc882_capture_alt_mixer; | ||
4997 | spec->num_mixers++; | 5383 | spec->num_mixers++; |
4998 | } else { | 5384 | } else { |
4999 | spec->adc_nids = alc882_adc_nids; | 5385 | spec->adc_nids = alc882_adc_nids; |
@@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = { | |||
5033 | /* ADC1-2 */ | 5419 | /* ADC1-2 */ |
5034 | 0x08, 0x09, | 5420 | 0x08, 0x09, |
5035 | }; | 5421 | }; |
5422 | |||
5036 | /* input MUX */ | 5423 | /* input MUX */ |
5037 | /* FIXME: should be a matrix-type input source selection */ | 5424 | /* FIXME: should be a matrix-type input source selection */ |
5038 | 5425 | ||
@@ -5045,6 +5432,15 @@ static struct hda_input_mux alc883_capture_source = { | |||
5045 | { "CD", 0x4 }, | 5432 | { "CD", 0x4 }, |
5046 | }, | 5433 | }, |
5047 | }; | 5434 | }; |
5435 | |||
5436 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | ||
5437 | .num_items = 2, | ||
5438 | .items = { | ||
5439 | { "Mic", 0x1 }, | ||
5440 | { "Line", 0x2 }, | ||
5441 | }, | ||
5442 | }; | ||
5443 | |||
5048 | #define alc883_mux_enum_info alc_mux_enum_info | 5444 | #define alc883_mux_enum_info alc_mux_enum_info |
5049 | #define alc883_mux_enum_get alc_mux_enum_get | 5445 | #define alc883_mux_enum_get alc_mux_enum_get |
5050 | 5446 | ||
@@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
5063 | idx = ucontrol->value.enumerated.item[0]; | 5459 | idx = ucontrol->value.enumerated.item[0]; |
5064 | if (idx >= imux->num_items) | 5460 | if (idx >= imux->num_items) |
5065 | idx = imux->num_items - 1; | 5461 | idx = imux->num_items - 1; |
5066 | if (*cur_val == idx && ! codec->in_resume) | 5462 | if (*cur_val == idx && !codec->in_resume) |
5067 | return 0; | 5463 | return 0; |
5068 | for (i = 0; i < imux->num_items; i++) { | 5464 | for (i = 0; i < imux->num_items; i++) { |
5069 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 5465 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
5073 | *cur_val = idx; | 5469 | *cur_val = idx; |
5074 | return 1; | 5470 | return 1; |
5075 | } | 5471 | } |
5472 | |||
5076 | /* | 5473 | /* |
5077 | * 2ch mode | 5474 | * 2ch mode |
5078 | */ | 5475 | */ |
@@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { | |||
5325 | .put = alc883_mux_enum_put, | 5722 | .put = alc883_mux_enum_put, |
5326 | }, | 5723 | }, |
5327 | { } /* end */ | 5724 | { } /* end */ |
5328 | }; | 5725 | }; |
5329 | 5726 | ||
5330 | static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { | 5727 | static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { |
5331 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 5728 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { | |||
5350 | .put = alc883_mux_enum_put, | 5747 | .put = alc883_mux_enum_put, |
5351 | }, | 5748 | }, |
5352 | { } /* end */ | 5749 | { } /* end */ |
5353 | }; | 5750 | }; |
5751 | |||
5752 | static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { | ||
5753 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5754 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
5755 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
5756 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
5757 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5758 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
5759 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
5760 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
5761 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
5762 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
5763 | { | ||
5764 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5765 | /* .name = "Capture Source", */ | ||
5766 | .name = "Input Source", | ||
5767 | .count = 1, | ||
5768 | .info = alc883_mux_enum_info, | ||
5769 | .get = alc883_mux_enum_get, | ||
5770 | .put = alc883_mux_enum_put, | ||
5771 | }, | ||
5772 | { } /* end */ | ||
5773 | }; | ||
5354 | 5774 | ||
5355 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 5775 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { |
5356 | { | 5776 | { |
@@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = { | |||
5452 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 5872 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
5453 | 5873 | ||
5454 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 5874 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
5455 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5875 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
5456 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | 5876 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, |
5457 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | 5877 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, |
5878 | |||
5879 | { } /* end */ | ||
5880 | }; | ||
5458 | 5881 | ||
5882 | static struct hda_verb alc883_lenovo_101e_verbs[] = { | ||
5883 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5884 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, | ||
5885 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, | ||
5459 | { } /* end */ | 5886 | { } /* end */ |
5460 | }; | 5887 | }; |
5461 | 5888 | ||
@@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = { | |||
5463 | static void alc883_tagra_automute(struct hda_codec *codec) | 5890 | static void alc883_tagra_automute(struct hda_codec *codec) |
5464 | { | 5891 | { |
5465 | unsigned int present; | 5892 | unsigned int present; |
5893 | unsigned char bits; | ||
5466 | 5894 | ||
5467 | present = snd_hda_codec_read(codec, 0x14, 0, | 5895 | present = snd_hda_codec_read(codec, 0x14, 0, |
5468 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 5896 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
5897 | bits = present ? 0x80 : 0; | ||
5469 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | 5898 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, |
5470 | 0x80, present ? 0x80 : 0); | 5899 | 0x80, bits); |
5471 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | 5900 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, |
5472 | 0x80, present ? 0x80 : 0); | 5901 | 0x80, bits); |
5473 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); | 5902 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
5903 | present ? 1 : 3); | ||
5474 | } | 5904 | } |
5475 | 5905 | ||
5476 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | 5906 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | |||
5479 | alc883_tagra_automute(codec); | 5909 | alc883_tagra_automute(codec); |
5480 | } | 5910 | } |
5481 | 5911 | ||
5912 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | ||
5913 | { | ||
5914 | unsigned int present; | ||
5915 | unsigned char bits; | ||
5916 | |||
5917 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
5918 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5919 | bits = present ? 0x80 : 0; | ||
5920 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
5921 | 0x80, bits); | ||
5922 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
5923 | 0x80, bits); | ||
5924 | } | ||
5925 | |||
5926 | static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) | ||
5927 | { | ||
5928 | unsigned int present; | ||
5929 | unsigned char bits; | ||
5930 | |||
5931 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
5932 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5933 | bits = present ? 0x80 : 0; | ||
5934 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
5935 | 0x80, bits); | ||
5936 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
5937 | 0x80, bits); | ||
5938 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
5939 | 0x80, bits); | ||
5940 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
5941 | 0x80, bits); | ||
5942 | } | ||
5943 | |||
5944 | static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | ||
5945 | unsigned int res) | ||
5946 | { | ||
5947 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5948 | alc883_lenovo_101e_all_automute(codec); | ||
5949 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
5950 | alc883_lenovo_101e_ispeaker_automute(codec); | ||
5951 | } | ||
5952 | |||
5482 | /* | 5953 | /* |
5483 | * generic initialization of ADC, input mixers and output mixers | 5954 | * generic initialization of ADC, input mixers and output mixers |
5484 | */ | 5955 | */ |
@@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = { | |||
5493 | 5964 | ||
5494 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 5965 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
5495 | * mixer widget | 5966 | * mixer widget |
5496 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 5967 | * Note: PASD motherboards uses the Line In 2 as the input for |
5497 | * mic (mic 2) | 5968 | * front panel mic (mic 2) |
5498 | */ | 5969 | */ |
5499 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 5970 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
5500 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5971 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = { | |||
5530 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6001 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5531 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 6002 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
5532 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 6003 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
5533 | //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 6004 | /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ |
5534 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 6005 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
5535 | /* Input mixer2 */ | 6006 | /* Input mixer2 */ |
5536 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6007 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5537 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 6008 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
5538 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 6009 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
5539 | //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 6010 | /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ |
5540 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 6011 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
5541 | 6012 | ||
5542 | { } | 6013 | { } |
@@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
5584 | [ALC883_ACER] = "acer", | 6055 | [ALC883_ACER] = "acer", |
5585 | [ALC883_MEDION] = "medion", | 6056 | [ALC883_MEDION] = "medion", |
5586 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", | 6057 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
6058 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", | ||
5587 | [ALC883_AUTO] = "auto", | 6059 | [ALC883_AUTO] = "auto", |
5588 | }; | 6060 | }; |
5589 | 6061 | ||
@@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
5592 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), | 6064 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
5593 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), | 6065 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), |
5594 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 6066 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
6067 | SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), | ||
5595 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), | 6068 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), |
5596 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), | 6069 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), |
5597 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), | 6070 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), |
@@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
5609 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 6082 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
5610 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 6083 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
5611 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 6084 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
6085 | SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch), | ||
5612 | {} | 6086 | {} |
5613 | }; | 6087 | }; |
5614 | 6088 | ||
@@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5639 | .channel_mode = alc883_3ST_6ch_modes, | 6113 | .channel_mode = alc883_3ST_6ch_modes, |
5640 | .need_dac_fix = 1, | 6114 | .need_dac_fix = 1, |
5641 | .input_mux = &alc883_capture_source, | 6115 | .input_mux = &alc883_capture_source, |
5642 | }, | 6116 | }, |
5643 | [ALC883_3ST_6ch] = { | 6117 | [ALC883_3ST_6ch] = { |
5644 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 6118 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
5645 | .init_verbs = { alc883_init_verbs }, | 6119 | .init_verbs = { alc883_init_verbs }, |
@@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
5651 | .channel_mode = alc883_3ST_6ch_modes, | 6125 | .channel_mode = alc883_3ST_6ch_modes, |
5652 | .need_dac_fix = 1, | 6126 | .need_dac_fix = 1, |
5653 | .input_mux = &alc883_capture_source, | 6127 | .input_mux = &alc883_capture_source, |
5654 | }, | 6128 | }, |
5655 | [ALC883_6ST_DIG] = { | 6129 | [ALC883_6ST_DIG] = { |
5656 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 6130 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
5657 | .init_verbs = { alc883_init_verbs }, | 6131 | .init_verbs = { alc883_init_verbs }, |
@@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = { | |||
5749 | .channel_mode = alc883_3ST_2ch_modes, | 6223 | .channel_mode = alc883_3ST_2ch_modes, |
5750 | .input_mux = &alc883_capture_source, | 6224 | .input_mux = &alc883_capture_source, |
5751 | }, | 6225 | }, |
6226 | [ALC883_LENOVO_101E_2ch] = { | ||
6227 | .mixers = { alc883_lenovo_101e_2ch_mixer}, | ||
6228 | .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, | ||
6229 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
6230 | .dac_nids = alc883_dac_nids, | ||
6231 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
6232 | .adc_nids = alc883_adc_nids, | ||
6233 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
6234 | .channel_mode = alc883_3ST_2ch_modes, | ||
6235 | .input_mux = &alc883_lenovo_101e_capture_source, | ||
6236 | .unsol_event = alc883_lenovo_101e_unsol_event, | ||
6237 | .init_hook = alc883_lenovo_101e_all_automute, | ||
6238 | }, | ||
5752 | }; | 6239 | }; |
5753 | 6240 | ||
5754 | 6241 | ||
@@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | |||
5761 | { | 6248 | { |
5762 | /* set as output */ | 6249 | /* set as output */ |
5763 | struct alc_spec *spec = codec->spec; | 6250 | struct alc_spec *spec = codec->spec; |
5764 | int idx; | 6251 | int idx; |
5765 | 6252 | ||
5766 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 6253 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
5767 | idx = 4; | 6254 | idx = 4; |
5768 | else | 6255 | else |
@@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) | |||
5781 | struct alc_spec *spec = codec->spec; | 6268 | struct alc_spec *spec = codec->spec; |
5782 | int i; | 6269 | int i; |
5783 | 6270 | ||
6271 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
5784 | for (i = 0; i <= HDA_SIDE; i++) { | 6272 | for (i = 0; i <= HDA_SIDE; i++) { |
5785 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 6273 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
6274 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
5786 | if (nid) | 6275 | if (nid) |
5787 | alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | 6276 | alc883_auto_set_output_and_unmute(codec, nid, pin_type, |
6277 | i); | ||
5788 | } | 6278 | } |
5789 | } | 6279 | } |
5790 | 6280 | ||
@@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) | |||
5833 | else if (err > 0) | 6323 | else if (err > 0) |
5834 | /* hack - override the init verbs */ | 6324 | /* hack - override the init verbs */ |
5835 | spec->init_verbs[0] = alc883_auto_init_verbs; | 6325 | spec->init_verbs[0] = alc883_auto_init_verbs; |
5836 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; | 6326 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; |
5837 | spec->num_mixers++; | 6327 | spec->num_mixers++; |
5838 | return err; | 6328 | return err; |
5839 | } | 6329 | } |
5840 | 6330 | ||
@@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec) | |||
5872 | if (err < 0) { | 6362 | if (err < 0) { |
5873 | alc_free(codec); | 6363 | alc_free(codec); |
5874 | return err; | 6364 | return err; |
5875 | } else if (! err) { | 6365 | } else if (!err) { |
5876 | printk(KERN_INFO | 6366 | printk(KERN_INFO |
5877 | "hda_codec: Cannot set up configuration " | 6367 | "hda_codec: Cannot set up configuration " |
5878 | "from BIOS. Using base mode...\n"); | 6368 | "from BIOS. Using base mode...\n"); |
@@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec) | |||
5891 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | 6381 | spec->stream_digital_playback = &alc883_pcm_digital_playback; |
5892 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | 6382 | spec->stream_digital_capture = &alc883_pcm_digital_capture; |
5893 | 6383 | ||
5894 | if (! spec->adc_nids && spec->input_mux) { | 6384 | if (!spec->adc_nids && spec->input_mux) { |
5895 | spec->adc_nids = alc883_adc_nids; | 6385 | spec->adc_nids = alc883_adc_nids; |
5896 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 6386 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
5897 | } | 6387 | } |
@@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = { | |||
6028 | 6518 | ||
6029 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6519 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6030 | * mixer widget | 6520 | * mixer widget |
6031 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6521 | * Note: PASD motherboards uses the Line In 2 as the input for |
6032 | * mic (mic 2) | 6522 | * front panel mic (mic 2) |
6033 | */ | 6523 | */ |
6034 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6524 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6035 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6525 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = { | |||
6086 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 6576 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
6087 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | 6577 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
6088 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, | 6578 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, |
6089 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | 6579 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, |
6090 | 6580 | ||
6091 | { } | 6581 | { } |
6092 | }; | 6582 | }; |
@@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force) | |||
6113 | struct alc_spec *spec = codec->spec; | 6603 | struct alc_spec *spec = codec->spec; |
6114 | unsigned int mute; | 6604 | unsigned int mute; |
6115 | 6605 | ||
6116 | if (force || ! spec->sense_updated) { | 6606 | if (force || !spec->sense_updated) { |
6117 | unsigned int present; | 6607 | unsigned int present; |
6118 | /* need to execute and sync at first */ | 6608 | /* need to execute and sync at first */ |
6119 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); | 6609 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force) | |||
6153 | struct alc_spec *spec = codec->spec; | 6643 | struct alc_spec *spec = codec->spec; |
6154 | unsigned int mute; | 6644 | unsigned int mute; |
6155 | 6645 | ||
6156 | if (force || ! spec->sense_updated) { | 6646 | if (force || !spec->sense_updated) { |
6157 | unsigned int present; | 6647 | unsigned int present; |
6158 | /* need to execute and sync at first */ | 6648 | /* need to execute and sync at first */ |
6159 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 6649 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | |||
6226 | struct alc_spec *spec = codec->spec; | 6716 | struct alc_spec *spec = codec->spec; |
6227 | unsigned int mute; | 6717 | unsigned int mute; |
6228 | 6718 | ||
6229 | if (force || ! spec->sense_updated) { | 6719 | if (force || !spec->sense_updated) { |
6230 | unsigned int present; | 6720 | unsigned int present; |
6231 | /* need to execute and sync at first */ | 6721 | /* need to execute and sync at first */ |
6232 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | 6722 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); |
@@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = { | |||
6331 | }; | 6821 | }; |
6332 | 6822 | ||
6333 | /* add playback controls from the parsed DAC table */ | 6823 | /* add playback controls from the parsed DAC table */ |
6334 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 6824 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, |
6825 | const struct auto_pin_cfg *cfg) | ||
6335 | { | 6826 | { |
6336 | hda_nid_t nid; | 6827 | hda_nid_t nid; |
6337 | int err; | 6828 | int err; |
@@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
6342 | 6833 | ||
6343 | nid = cfg->line_out_pins[0]; | 6834 | nid = cfg->line_out_pins[0]; |
6344 | if (nid) { | 6835 | if (nid) { |
6345 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", | 6836 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6346 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | 6837 | "Front Playback Volume", |
6838 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); | ||
6839 | if (err < 0) | ||
6347 | return err; | 6840 | return err; |
6348 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", | 6841 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6349 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6842 | "Front Playback Switch", |
6843 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
6844 | if (err < 0) | ||
6350 | return err; | 6845 | return err; |
6351 | } | 6846 | } |
6352 | 6847 | ||
6353 | nid = cfg->speaker_pins[0]; | 6848 | nid = cfg->speaker_pins[0]; |
6354 | if (nid) { | 6849 | if (nid) { |
6355 | if (nid == 0x16) { | 6850 | if (nid == 0x16) { |
6356 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | 6851 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6357 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) | 6852 | "Speaker Playback Volume", |
6853 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, | ||
6854 | HDA_OUTPUT)); | ||
6855 | if (err < 0) | ||
6358 | return err; | 6856 | return err; |
6359 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 6857 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6360 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 6858 | "Speaker Playback Switch", |
6859 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
6860 | HDA_OUTPUT)); | ||
6861 | if (err < 0) | ||
6361 | return err; | 6862 | return err; |
6362 | } else { | 6863 | } else { |
6363 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 6864 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6364 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6865 | "Speaker Playback Switch", |
6866 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
6867 | HDA_OUTPUT)); | ||
6868 | if (err < 0) | ||
6365 | return err; | 6869 | return err; |
6366 | } | 6870 | } |
6367 | } | 6871 | } |
@@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
6369 | if (nid) { | 6873 | if (nid) { |
6370 | /* spec->multiout.hp_nid = 2; */ | 6874 | /* spec->multiout.hp_nid = 2; */ |
6371 | if (nid == 0x16) { | 6875 | if (nid == 0x16) { |
6372 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", | 6876 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
6373 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) | 6877 | "Headphone Playback Volume", |
6878 | HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, | ||
6879 | HDA_OUTPUT)); | ||
6880 | if (err < 0) | ||
6374 | return err; | 6881 | return err; |
6375 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 6882 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6376 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 6883 | "Headphone Playback Switch", |
6884 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
6885 | HDA_OUTPUT)); | ||
6886 | if (err < 0) | ||
6377 | return err; | 6887 | return err; |
6378 | } else { | 6888 | } else { |
6379 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 6889 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
6380 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 6890 | "Headphone Playback Switch", |
6891 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
6892 | HDA_OUTPUT)); | ||
6893 | if (err < 0) | ||
6381 | return err; | 6894 | return err; |
6382 | } | 6895 | } |
6383 | } | 6896 | } |
6384 | return 0; | 6897 | return 0; |
6385 | } | 6898 | } |
6386 | 6899 | ||
6387 | /* identical with ALC880 */ | 6900 | /* identical with ALC880 */ |
6388 | #define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls | 6901 | #define alc262_auto_create_analog_input_ctls \ |
6902 | alc880_auto_create_analog_input_ctls | ||
6389 | 6903 | ||
6390 | /* | 6904 | /* |
6391 | * generic initialization of ADC, input mixers and output mixers | 6905 | * generic initialization of ADC, input mixers and output mixers |
@@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = { | |||
6403 | 6917 | ||
6404 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6918 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6405 | * mixer widget | 6919 | * mixer widget |
6406 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6920 | * Note: PASD motherboards uses the Line In 2 as the input for |
6407 | * mic (mic 2) | 6921 | * front panel mic (mic 2) |
6408 | */ | 6922 | */ |
6409 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6923 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6410 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6924 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { | |||
6464 | 6978 | ||
6465 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 6979 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
6466 | * mixer widget | 6980 | * mixer widget |
6467 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 6981 | * Note: PASD motherboards uses the Line In 2 as the input for |
6468 | * mic (mic 2) | 6982 | * front panel mic (mic 2) |
6469 | */ | 6983 | */ |
6470 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 6984 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
6471 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 6985 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
6647 | int err; | 7161 | int err; |
6648 | static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 7162 | static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
6649 | 7163 | ||
6650 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 7164 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
6651 | alc262_ignore)) < 0) | 7165 | alc262_ignore); |
7166 | if (err < 0) | ||
6652 | return err; | 7167 | return err; |
6653 | if (! spec->autocfg.line_outs) | 7168 | if (!spec->autocfg.line_outs) |
6654 | return 0; /* can't find valid BIOS pin config */ | 7169 | return 0; /* can't find valid BIOS pin config */ |
6655 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 7170 | err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); |
6656 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 7171 | if (err < 0) |
7172 | return err; | ||
7173 | err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
7174 | if (err < 0) | ||
6657 | return err; | 7175 | return err; |
6658 | 7176 | ||
6659 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 7177 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6777 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7295 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6778 | .channel_mode = alc262_modes, | 7296 | .channel_mode = alc262_modes, |
6779 | .input_mux = &alc262_HP_capture_source, | 7297 | .input_mux = &alc262_HP_capture_source, |
6780 | }, | 7298 | }, |
6781 | [ALC262_HP_BPC_D7000_WF] = { | 7299 | [ALC262_HP_BPC_D7000_WF] = { |
6782 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | 7300 | .mixers = { alc262_HP_BPC_WildWest_mixer }, |
6783 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | 7301 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, |
@@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6787 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7305 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6788 | .channel_mode = alc262_modes, | 7306 | .channel_mode = alc262_modes, |
6789 | .input_mux = &alc262_HP_capture_source, | 7307 | .input_mux = &alc262_HP_capture_source, |
6790 | }, | 7308 | }, |
6791 | [ALC262_HP_BPC_D7000_WL] = { | 7309 | [ALC262_HP_BPC_D7000_WL] = { |
6792 | .mixers = { alc262_HP_BPC_WildWest_mixer, | 7310 | .mixers = { alc262_HP_BPC_WildWest_mixer, |
6793 | alc262_HP_BPC_WildWest_option_mixer }, | 7311 | alc262_HP_BPC_WildWest_option_mixer }, |
@@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6798 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7316 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6799 | .channel_mode = alc262_modes, | 7317 | .channel_mode = alc262_modes, |
6800 | .input_mux = &alc262_HP_capture_source, | 7318 | .input_mux = &alc262_HP_capture_source, |
6801 | }, | 7319 | }, |
6802 | [ALC262_BENQ_ED8] = { | 7320 | [ALC262_BENQ_ED8] = { |
6803 | .mixers = { alc262_base_mixer }, | 7321 | .mixers = { alc262_base_mixer }, |
6804 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, | 7322 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, |
@@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
6808 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 7326 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
6809 | .channel_mode = alc262_modes, | 7327 | .channel_mode = alc262_modes, |
6810 | .input_mux = &alc262_capture_source, | 7328 | .input_mux = &alc262_capture_source, |
6811 | }, | 7329 | }, |
6812 | }; | 7330 | }; |
6813 | 7331 | ||
6814 | static int patch_alc262(struct hda_codec *codec) | 7332 | static int patch_alc262(struct hda_codec *codec) |
@@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
6823 | 7341 | ||
6824 | codec->spec = spec; | 7342 | codec->spec = spec; |
6825 | #if 0 | 7343 | #if 0 |
6826 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ | 7344 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
7345 | * under-run | ||
7346 | */ | ||
6827 | { | 7347 | { |
6828 | int tmp; | 7348 | int tmp; |
6829 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 7349 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
@@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
6849 | if (err < 0) { | 7369 | if (err < 0) { |
6850 | alc_free(codec); | 7370 | alc_free(codec); |
6851 | return err; | 7371 | return err; |
6852 | } else if (! err) { | 7372 | } else if (!err) { |
6853 | printk(KERN_INFO | 7373 | printk(KERN_INFO |
6854 | "hda_codec: Cannot set up configuration " | 7374 | "hda_codec: Cannot set up configuration " |
6855 | "from BIOS. Using base mode...\n"); | 7375 | "from BIOS. Using base mode...\n"); |
@@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec) | |||
6868 | spec->stream_digital_playback = &alc262_pcm_digital_playback; | 7388 | spec->stream_digital_playback = &alc262_pcm_digital_playback; |
6869 | spec->stream_digital_capture = &alc262_pcm_digital_capture; | 7389 | spec->stream_digital_capture = &alc262_pcm_digital_capture; |
6870 | 7390 | ||
6871 | if (! spec->adc_nids && spec->input_mux) { | 7391 | if (!spec->adc_nids && spec->input_mux) { |
6872 | /* check whether NID 0x07 is valid */ | 7392 | /* check whether NID 0x07 is valid */ |
6873 | unsigned int wcap = get_wcaps(codec, 0x07); | 7393 | unsigned int wcap = get_wcaps(codec, 0x07); |
6874 | 7394 | ||
6875 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 7395 | /* get type */ |
7396 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
6876 | if (wcap != AC_WID_AUD_IN) { | 7397 | if (wcap != AC_WID_AUD_IN) { |
6877 | spec->adc_nids = alc262_adc_nids_alt; | 7398 | spec->adc_nids = alc262_adc_nids_alt; |
6878 | spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); | 7399 | spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); |
6879 | spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; | 7400 | spec->mixers[spec->num_mixers] = |
7401 | alc262_capture_alt_mixer; | ||
6880 | spec->num_mixers++; | 7402 | spec->num_mixers++; |
6881 | } else { | 7403 | } else { |
6882 | spec->adc_nids = alc262_adc_nids; | 7404 | spec->adc_nids = alc262_adc_nids; |
@@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
6904 | static struct hda_verb alc861_threestack_ch2_init[] = { | 7426 | static struct hda_verb alc861_threestack_ch2_init[] = { |
6905 | /* set pin widget 1Ah (line in) for input */ | 7427 | /* set pin widget 1Ah (line in) for input */ |
6906 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 7428 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
6907 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 7429 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
7430 | * the vref | ||
7431 | */ | ||
6908 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7432 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6909 | 7433 | ||
6910 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 7434 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
@@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { | |||
6961 | static struct hda_verb alc861_asus_ch2_init[] = { | 7485 | static struct hda_verb alc861_asus_ch2_init[] = { |
6962 | /* set pin widget 1Ah (line in) for input */ | 7486 | /* set pin widget 1Ah (line in) for input */ |
6963 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 7487 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
6964 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 7488 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
7489 | * the vref | ||
7490 | */ | ||
6965 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7491 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6966 | 7492 | ||
6967 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 7493 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
@@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { | |||
7016 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7542 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7017 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7543 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7018 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7544 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7019 | 7545 | ||
7020 | /* Capture mixer control */ | 7546 | /* Capture mixer control */ |
7021 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7547 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7022 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7548 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { | |||
7050 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7576 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7051 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7577 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7052 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7578 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7053 | 7579 | ||
7054 | /* Capture mixer control */ | 7580 | /* Capture mixer control */ |
7055 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7581 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7056 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7582 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { | |||
7092 | }, | 7618 | }, |
7093 | 7619 | ||
7094 | { } /* end */ | 7620 | { } /* end */ |
7095 | }; | 7621 | }; |
7096 | 7622 | ||
7097 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | 7623 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { |
7098 | /* output mixer control */ | 7624 | /* output mixer control */ |
@@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
7113 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7639 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7114 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7640 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7115 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | 7641 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), |
7116 | 7642 | ||
7117 | /* Capture mixer control */ | 7643 | /* Capture mixer control */ |
7118 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7644 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7119 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7645 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
7134 | .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), | 7660 | .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), |
7135 | }, | 7661 | }, |
7136 | { } /* end */ | 7662 | { } /* end */ |
7137 | }; | 7663 | }; |
7138 | 7664 | ||
7139 | static struct snd_kcontrol_new alc861_asus_mixer[] = { | 7665 | static struct snd_kcontrol_new alc861_asus_mixer[] = { |
7140 | /* output mixer control */ | 7666 | /* output mixer control */ |
@@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { | |||
7154 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | 7680 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), |
7155 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | 7681 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), |
7156 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | 7682 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), |
7157 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ | 7683 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), |
7158 | 7684 | ||
7159 | /* Capture mixer control */ | 7685 | /* Capture mixer control */ |
7160 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 7686 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
7161 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 7687 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
@@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
7239 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7765 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7240 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7766 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7241 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7767 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7242 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7768 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7243 | 7769 | ||
7244 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7770 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7245 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7771 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
7249 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7775 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7250 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7776 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7251 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7777 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7252 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7778 | /* hp used DAC 3 (Front) */ |
7779 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7253 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7780 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7254 | 7781 | ||
7255 | { } | 7782 | { } |
@@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
7300 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7827 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7301 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7828 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7302 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7829 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7303 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7830 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7304 | 7831 | ||
7305 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7832 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7306 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7833 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
7310 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7837 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7311 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7838 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7312 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7839 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7313 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7840 | /* hp used DAC 3 (Front) */ |
7841 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7314 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7842 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7315 | { } | 7843 | { } |
7316 | }; | 7844 | }; |
@@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7329 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 7857 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
7330 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7858 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7331 | /* port-E for HP out (front panel) */ | 7859 | /* port-E for HP out (front panel) */ |
7332 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 | 7860 | /* this has to be set to VREF80 */ |
7861 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7333 | /* route front PCM to HP */ | 7862 | /* route front PCM to HP */ |
7334 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7863 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7335 | /* port-F for mic-in (front panel) with vref */ | 7864 | /* port-F for mic-in (front panel) with vref */ |
@@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7360 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7889 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7361 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7890 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7362 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7891 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7363 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step | 7892 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7364 | 7893 | ||
7365 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7894 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7366 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7895 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
7370 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7899 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7371 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7900 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7372 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7901 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7373 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) | 7902 | /* hp used DAC 3 (Front) */ |
7903 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7374 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7904 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7375 | { } | 7905 | { } |
7376 | }; | 7906 | }; |
@@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7379 | /* | 7909 | /* |
7380 | * Unmute ADC0 and set the default input to mic-in | 7910 | * Unmute ADC0 and set the default input to mic-in |
7381 | */ | 7911 | */ |
7382 | /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ | 7912 | /* port-A for surround (rear panel) |
7913 | * according to codec#0 this is the HP jack | ||
7914 | */ | ||
7383 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ | 7915 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ |
7384 | /* route front PCM to HP */ | 7916 | /* route front PCM to HP */ |
7385 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7917 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
@@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7391 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 7923 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
7392 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7924 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7393 | /* port-E for HP out (front panel) */ | 7925 | /* port-E for HP out (front panel) */ |
7394 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ | 7926 | /* this has to be set to VREF80 */ |
7927 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7395 | /* route front PCM to HP */ | 7928 | /* route front PCM to HP */ |
7396 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 7929 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7397 | /* port-F for mic-in (front panel) with vref */ | 7930 | /* port-F for mic-in (front panel) with vref */ |
@@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7421 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7954 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7422 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7955 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7423 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7956 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7424 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ | 7957 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ |
7425 | 7958 | ||
7426 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7959 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7427 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7960 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
7431 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7964 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7432 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7965 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7433 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7966 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
7434 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ | 7967 | /* hp used DAC 3 (Front) */ |
7968 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7435 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 7969 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7436 | { } | 7970 | { } |
7437 | }; | 7971 | }; |
@@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
7450 | /* | 7984 | /* |
7451 | * Unmute ADC0 and set the default input to mic-in | 7985 | * Unmute ADC0 and set the default input to mic-in |
7452 | */ | 7986 | */ |
7453 | // {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 7987 | /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ |
7454 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7988 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7455 | 7989 | ||
7456 | /* Unmute DAC0~3 & spdif out*/ | 7990 | /* Unmute DAC0~3 & spdif out*/ |
@@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
7483 | 8017 | ||
7484 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8018 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
7485 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8019 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
7486 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 8020 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7487 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 8021 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, |
7488 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8022 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
7489 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8023 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
7490 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 8024 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
7491 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 8025 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, |
7492 | 8026 | ||
7493 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 | 8027 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ |
7494 | 8028 | ||
7495 | { } | 8029 | { } |
7496 | }; | 8030 | }; |
7497 | 8031 | ||
7498 | static struct hda_verb alc861_toshiba_init_verbs[] = { | 8032 | static struct hda_verb alc861_toshiba_init_verbs[] = { |
7499 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 8033 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
7500 | 8034 | ||
7501 | { } | 8035 | { } |
7502 | }; | 8036 | }; |
7503 | 8037 | ||
@@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec) | |||
7521 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, | 8055 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, |
7522 | unsigned int res) | 8056 | unsigned int res) |
7523 | { | 8057 | { |
7524 | /* Looks like the unsol event is incompatible with the standard | ||
7525 | * definition. 6bit tag is placed at 26 bit! | ||
7526 | */ | ||
7527 | if ((res >> 26) == ALC880_HP_EVENT) | 8058 | if ((res >> 26) == ALC880_HP_EVENT) |
7528 | alc861_toshiba_automute(codec); | 8059 | alc861_toshiba_automute(codec); |
7529 | } | 8060 | } |
@@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = { | |||
7568 | }; | 8099 | }; |
7569 | 8100 | ||
7570 | /* fill in the dac_nids table from the parsed pin configuration */ | 8101 | /* fill in the dac_nids table from the parsed pin configuration */ |
7571 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 8102 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, |
8103 | const struct auto_pin_cfg *cfg) | ||
7572 | { | 8104 | { |
7573 | int i; | 8105 | int i; |
7574 | hda_nid_t nid; | 8106 | hda_nid_t nid; |
@@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
7591 | const struct auto_pin_cfg *cfg) | 8123 | const struct auto_pin_cfg *cfg) |
7592 | { | 8124 | { |
7593 | char name[32]; | 8125 | char name[32]; |
7594 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 8126 | static const char *chname[4] = { |
8127 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
8128 | }; | ||
7595 | hda_nid_t nid; | 8129 | hda_nid_t nid; |
7596 | int i, idx, err; | 8130 | int i, idx, err; |
7597 | 8131 | ||
7598 | for (i = 0; i < cfg->line_outs; i++) { | 8132 | for (i = 0; i < cfg->line_outs; i++) { |
7599 | nid = spec->multiout.dac_nids[i]; | 8133 | nid = spec->multiout.dac_nids[i]; |
7600 | if (! nid) | 8134 | if (!nid) |
7601 | continue; | 8135 | continue; |
7602 | if (nid == 0x05) { | 8136 | if (nid == 0x05) { |
7603 | /* Center/LFE */ | 8137 | /* Center/LFE */ |
7604 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", | 8138 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
7605 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | 8139 | "Center Playback Switch", |
8140 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
8141 | HDA_OUTPUT)); | ||
8142 | if (err < 0) | ||
7606 | return err; | 8143 | return err; |
7607 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", | 8144 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
7608 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 8145 | "LFE Playback Switch", |
8146 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
8147 | HDA_OUTPUT)); | ||
8148 | if (err < 0) | ||
7609 | return err; | 8149 | return err; |
7610 | } else { | 8150 | } else { |
7611 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) | 8151 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; |
8152 | idx++) | ||
7612 | if (nid == alc861_dac_nids[idx]) | 8153 | if (nid == alc861_dac_nids[idx]) |
7613 | break; | 8154 | break; |
7614 | sprintf(name, "%s Playback Switch", chname[idx]); | 8155 | sprintf(name, "%s Playback Switch", chname[idx]); |
7615 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 8156 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
7616 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 8157 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
8158 | HDA_OUTPUT)); | ||
8159 | if (err < 0) | ||
7617 | return err; | 8160 | return err; |
7618 | } | 8161 | } |
7619 | } | 8162 | } |
@@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
7625 | int err; | 8168 | int err; |
7626 | hda_nid_t nid; | 8169 | hda_nid_t nid; |
7627 | 8170 | ||
7628 | if (! pin) | 8171 | if (!pin) |
7629 | return 0; | 8172 | return 0; |
7630 | 8173 | ||
7631 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { | 8174 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { |
7632 | nid = 0x03; | 8175 | nid = 0x03; |
7633 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 8176 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
7634 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 8177 | "Headphone Playback Switch", |
8178 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
8179 | if (err < 0) | ||
7635 | return err; | 8180 | return err; |
7636 | spec->multiout.hp_nid = nid; | 8181 | spec->multiout.hp_nid = nid; |
7637 | } | 8182 | } |
@@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
7639 | } | 8184 | } |
7640 | 8185 | ||
7641 | /* create playback/capture controls for input pins */ | 8186 | /* create playback/capture controls for input pins */ |
7642 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 8187 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, |
8188 | const struct auto_pin_cfg *cfg) | ||
7643 | { | 8189 | { |
7644 | struct hda_input_mux *imux = &spec->private_imux; | 8190 | struct hda_input_mux *imux = &spec->private_imux; |
7645 | int i, err, idx, idx1; | 8191 | int i, err, idx, idx1; |
7646 | 8192 | ||
7647 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 8193 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
7648 | switch(cfg->input_pins[i]) { | 8194 | switch (cfg->input_pins[i]) { |
7649 | case 0x0c: | 8195 | case 0x0c: |
7650 | idx1 = 1; | 8196 | idx1 = 1; |
7651 | idx = 2; // Line In | 8197 | idx = 2; /* Line In */ |
7652 | break; | 8198 | break; |
7653 | case 0x0f: | 8199 | case 0x0f: |
7654 | idx1 = 2; | 8200 | idx1 = 2; |
7655 | idx = 2; // Line In | 8201 | idx = 2; /* Line In */ |
7656 | break; | 8202 | break; |
7657 | case 0x0d: | 8203 | case 0x0d: |
7658 | idx1 = 0; | 8204 | idx1 = 0; |
7659 | idx = 1; // Mic In | 8205 | idx = 1; /* Mic In */ |
7660 | break; | 8206 | break; |
7661 | case 0x10: | 8207 | case 0x10: |
7662 | idx1 = 3; | 8208 | idx1 = 3; |
7663 | idx = 1; // Mic In | 8209 | idx = 1; /* Mic In */ |
7664 | break; | 8210 | break; |
7665 | case 0x11: | 8211 | case 0x11: |
7666 | idx1 = 4; | 8212 | idx1 = 4; |
7667 | idx = 0; // CD | 8213 | idx = 0; /* CD */ |
7668 | break; | 8214 | break; |
7669 | default: | 8215 | default: |
7670 | continue; | 8216 | continue; |
@@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str | |||
7677 | 8223 | ||
7678 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 8224 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; |
7679 | imux->items[imux->num_items].index = idx1; | 8225 | imux->items[imux->num_items].index = idx1; |
7680 | imux->num_items++; | 8226 | imux->num_items++; |
7681 | } | 8227 | } |
7682 | return 0; | 8228 | return 0; |
7683 | } | 8229 | } |
@@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = { | |||
7702 | { } /* end */ | 8248 | { } /* end */ |
7703 | }; | 8249 | }; |
7704 | 8250 | ||
7705 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, | 8251 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, |
8252 | hda_nid_t nid, | ||
7706 | int pin_type, int dac_idx) | 8253 | int pin_type, int dac_idx) |
7707 | { | 8254 | { |
7708 | /* set as output */ | 8255 | /* set as output */ |
7709 | 8256 | ||
7710 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 8257 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
7711 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 8258 | pin_type); |
8259 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8260 | AMP_OUT_UNMUTE); | ||
7712 | 8261 | ||
7713 | } | 8262 | } |
7714 | 8263 | ||
@@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) | |||
7717 | struct alc_spec *spec = codec->spec; | 8266 | struct alc_spec *spec = codec->spec; |
7718 | int i; | 8267 | int i; |
7719 | 8268 | ||
8269 | alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); | ||
7720 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 8270 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
7721 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 8271 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
8272 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
7722 | if (nid) | 8273 | if (nid) |
7723 | alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); | 8274 | alc861_auto_set_output_and_unmute(codec, nid, pin_type, |
8275 | spec->multiout.dac_nids[i]); | ||
7724 | } | 8276 | } |
7725 | } | 8277 | } |
7726 | 8278 | ||
@@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
7731 | 8283 | ||
7732 | pin = spec->autocfg.hp_pins[0]; | 8284 | pin = spec->autocfg.hp_pins[0]; |
7733 | if (pin) /* connect to front */ | 8285 | if (pin) /* connect to front */ |
7734 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); | 8286 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, |
8287 | spec->multiout.dac_nids[0]); | ||
7735 | } | 8288 | } |
7736 | 8289 | ||
7737 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 8290 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
@@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) | |||
7741 | 8294 | ||
7742 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 8295 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
7743 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 8296 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
7744 | if ((nid>=0x0c) && (nid <=0x11)) { | 8297 | if (nid >= 0x0c && nid <= 0x11) { |
7745 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 8298 | snd_hda_codec_write(codec, nid, 0, |
7746 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | 8299 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
8300 | i <= AUTO_PIN_FRONT_MIC ? | ||
8301 | PIN_VREF80 : PIN_IN); | ||
7747 | } | 8302 | } |
7748 | } | 8303 | } |
7749 | } | 8304 | } |
7750 | 8305 | ||
7751 | /* parse the BIOS configuration and set up the alc_spec */ | 8306 | /* parse the BIOS configuration and set up the alc_spec */ |
7752 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | 8307 | /* return 1 if successful, 0 if the proper config is not found, |
8308 | * or a negative error code | ||
8309 | */ | ||
7753 | static int alc861_parse_auto_config(struct hda_codec *codec) | 8310 | static int alc861_parse_auto_config(struct hda_codec *codec) |
7754 | { | 8311 | { |
7755 | struct alc_spec *spec = codec->spec; | 8312 | struct alc_spec *spec = codec->spec; |
7756 | int err; | 8313 | int err; |
7757 | static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 8314 | static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
7758 | 8315 | ||
7759 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 8316 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
7760 | alc861_ignore)) < 0) | 8317 | alc861_ignore); |
8318 | if (err < 0) | ||
7761 | return err; | 8319 | return err; |
7762 | if (! spec->autocfg.line_outs) | 8320 | if (!spec->autocfg.line_outs) |
7763 | return 0; /* can't find valid BIOS pin config */ | 8321 | return 0; /* can't find valid BIOS pin config */ |
7764 | 8322 | ||
7765 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 8323 | err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); |
7766 | (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 8324 | if (err < 0) |
7767 | (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 || | 8325 | return err; |
7768 | (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 8326 | err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); |
8327 | if (err < 0) | ||
8328 | return err; | ||
8329 | err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); | ||
8330 | if (err < 0) | ||
8331 | return err; | ||
8332 | err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
8333 | if (err < 0) | ||
7769 | return err; | 8334 | return err; |
7770 | 8335 | ||
7771 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 8336 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { | |||
7817 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), | 8382 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), |
7818 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 8383 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
7819 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 8384 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
8385 | SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), | ||
7820 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), | 8386 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), |
7821 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), | 8387 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), |
7822 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), | 8388 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), |
7823 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), | 8389 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), |
7824 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), | 8390 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), |
7825 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), | 8391 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), |
8392 | SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), | ||
7826 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), | 8393 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), |
7827 | {} | 8394 | {} |
7828 | }; | 8395 | }; |
@@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = { | |||
7892 | }, | 8459 | }, |
7893 | [ALC861_TOSHIBA] = { | 8460 | [ALC861_TOSHIBA] = { |
7894 | .mixers = { alc861_toshiba_mixer }, | 8461 | .mixers = { alc861_toshiba_mixer }, |
7895 | .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, | 8462 | .init_verbs = { alc861_base_init_verbs, |
8463 | alc861_toshiba_init_verbs }, | ||
7896 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | 8464 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), |
7897 | .dac_nids = alc861_dac_nids, | 8465 | .dac_nids = alc861_dac_nids, |
7898 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 8466 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
@@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
7944 | if (spec == NULL) | 8512 | if (spec == NULL) |
7945 | return -ENOMEM; | 8513 | return -ENOMEM; |
7946 | 8514 | ||
7947 | codec->spec = spec; | 8515 | codec->spec = spec; |
7948 | 8516 | ||
7949 | board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, | 8517 | board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, |
7950 | alc861_models, | 8518 | alc861_models, |
@@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
7962 | if (err < 0) { | 8530 | if (err < 0) { |
7963 | alc_free(codec); | 8531 | alc_free(codec); |
7964 | return err; | 8532 | return err; |
7965 | } else if (! err) { | 8533 | } else if (!err) { |
7966 | printk(KERN_INFO | 8534 | printk(KERN_INFO |
7967 | "hda_codec: Cannot set up configuration " | 8535 | "hda_codec: Cannot set up configuration " |
7968 | "from BIOS. Using base mode...\n"); | 8536 | "from BIOS. Using base mode...\n"); |
@@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
8049 | idx = ucontrol->value.enumerated.item[0]; | 8617 | idx = ucontrol->value.enumerated.item[0]; |
8050 | if (idx >= imux->num_items) | 8618 | if (idx >= imux->num_items) |
8051 | idx = imux->num_items - 1; | 8619 | idx = imux->num_items - 1; |
8052 | if (*cur_val == idx && ! codec->in_resume) | 8620 | if (*cur_val == idx && !codec->in_resume) |
8053 | return 0; | 8621 | return 0; |
8054 | for (i = 0; i < imux->num_items; i++) { | 8622 | for (i = 0; i < imux->num_items; i++) { |
8055 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | 8623 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; |
@@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | |||
8193 | { } /* end */ | 8761 | { } /* end */ |
8194 | }; | 8762 | }; |
8195 | 8763 | ||
8764 | static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { | ||
8765 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
8766 | /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ | ||
8767 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
8768 | |||
8769 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
8770 | |||
8771 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
8772 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
8773 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
8774 | |||
8775 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
8776 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
8777 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
8778 | |||
8779 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
8780 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
8781 | |||
8782 | { } /* end */ | ||
8783 | }; | ||
8784 | |||
8196 | /* | 8785 | /* |
8197 | * generic initialization of ADC, input mixers and output mixers | 8786 | * generic initialization of ADC, input mixers and output mixers |
8198 | */ | 8787 | */ |
@@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { | |||
8214 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 8803 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
8215 | 8804 | ||
8216 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ | 8805 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ |
8806 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8807 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8808 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
8217 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | 8809 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, |
8218 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
8219 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
8220 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, | ||
8221 | 8810 | ||
8222 | /* | 8811 | /* |
8223 | * Set up output mixers (0x02 - 0x05) | 8812 | * Set up output mixers (0x02 - 0x05) |
@@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { | |||
8318 | { } | 8907 | { } |
8319 | }; | 8908 | }; |
8320 | 8909 | ||
8910 | static struct hda_verb alc861vd_eapd_verbs[] = { | ||
8911 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
8912 | { } | ||
8913 | }; | ||
8914 | |||
8915 | static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | ||
8916 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8917 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8918 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
8919 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
8920 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
8921 | {} | ||
8922 | }; | ||
8923 | |||
8924 | /* toggle speaker-output according to the hp-jack state */ | ||
8925 | static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) | ||
8926 | { | ||
8927 | unsigned int present; | ||
8928 | unsigned char bits; | ||
8929 | |||
8930 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8931 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8932 | bits = present ? 0x80 : 0; | ||
8933 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
8934 | 0x80, bits); | ||
8935 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
8936 | 0x80, bits); | ||
8937 | } | ||
8938 | |||
8939 | static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | ||
8940 | { | ||
8941 | unsigned int present; | ||
8942 | unsigned char bits; | ||
8943 | |||
8944 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
8945 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8946 | bits = present ? 0x80 : 0; | ||
8947 | snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, | ||
8948 | 0x80, bits); | ||
8949 | snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, | ||
8950 | 0x80, bits); | ||
8951 | } | ||
8952 | |||
8953 | static void alc861vd_lenovo_automute(struct hda_codec *codec) | ||
8954 | { | ||
8955 | alc861vd_lenovo_hp_automute(codec); | ||
8956 | alc861vd_lenovo_mic_automute(codec); | ||
8957 | } | ||
8958 | |||
8959 | static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | ||
8960 | unsigned int res) | ||
8961 | { | ||
8962 | switch (res >> 26) { | ||
8963 | case ALC880_HP_EVENT: | ||
8964 | alc861vd_lenovo_hp_automute(codec); | ||
8965 | break; | ||
8966 | case ALC880_MIC_EVENT: | ||
8967 | alc861vd_lenovo_mic_automute(codec); | ||
8968 | break; | ||
8969 | } | ||
8970 | } | ||
8971 | |||
8321 | /* pcm configuration: identiacal with ALC880 */ | 8972 | /* pcm configuration: identiacal with ALC880 */ |
8322 | #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback | 8973 | #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback |
8323 | #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture | 8974 | #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture |
@@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | |||
8332 | [ALC861VD_3ST] = "3stack", | 8983 | [ALC861VD_3ST] = "3stack", |
8333 | [ALC861VD_3ST_DIG] = "3stack-digout", | 8984 | [ALC861VD_3ST_DIG] = "3stack-digout", |
8334 | [ALC861VD_6ST_DIG] = "6stack-digout", | 8985 | [ALC861VD_6ST_DIG] = "6stack-digout", |
8986 | [ALC861VD_LENOVO] = "lenovo", | ||
8335 | [ALC861VD_AUTO] = "auto", | 8987 | [ALC861VD_AUTO] = "auto", |
8336 | }; | 8988 | }; |
8337 | 8989 | ||
8338 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | 8990 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { |
8991 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | ||
8339 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), | 8992 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), |
8340 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | 8993 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), |
8341 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | 8994 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), |
8342 | 8995 | ||
8343 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), | 8996 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), |
8997 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), | ||
8344 | {} | 8998 | {} |
8345 | }; | 8999 | }; |
8346 | 9000 | ||
@@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
8389 | .channel_mode = alc861vd_6stack_modes, | 9043 | .channel_mode = alc861vd_6stack_modes, |
8390 | .input_mux = &alc861vd_capture_source, | 9044 | .input_mux = &alc861vd_capture_source, |
8391 | }, | 9045 | }, |
9046 | [ALC861VD_LENOVO] = { | ||
9047 | .mixers = { alc861vd_lenovo_mixer }, | ||
9048 | .init_verbs = { alc861vd_volume_init_verbs, | ||
9049 | alc861vd_3stack_init_verbs, | ||
9050 | alc861vd_eapd_verbs, | ||
9051 | alc861vd_lenovo_unsol_verbs }, | ||
9052 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
9053 | .dac_nids = alc660vd_dac_nids, | ||
9054 | .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), | ||
9055 | .adc_nids = alc861vd_adc_nids, | ||
9056 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
9057 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
9058 | .input_mux = &alc861vd_capture_source, | ||
9059 | .unsol_event = alc861vd_lenovo_unsol_event, | ||
9060 | .init_hook = alc861vd_lenovo_automute, | ||
9061 | }, | ||
8392 | }; | 9062 | }; |
8393 | 9063 | ||
8394 | /* | 9064 | /* |
@@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) | |||
8409 | struct alc_spec *spec = codec->spec; | 9079 | struct alc_spec *spec = codec->spec; |
8410 | int i; | 9080 | int i; |
8411 | 9081 | ||
9082 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
8412 | for (i = 0; i <= HDA_SIDE; i++) { | 9083 | for (i = 0; i <= HDA_SIDE; i++) { |
8413 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 9084 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
9085 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
8414 | if (nid) | 9086 | if (nid) |
8415 | alc861vd_auto_set_output_and_unmute(codec, nid, | 9087 | alc861vd_auto_set_output_and_unmute(codec, nid, |
8416 | PIN_OUT, i); | 9088 | pin_type, i); |
8417 | } | 9089 | } |
8418 | } | 9090 | } |
8419 | 9091 | ||
@@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
8466 | int i, err; | 9138 | int i, err; |
8467 | 9139 | ||
8468 | for (i = 0; i < cfg->line_outs; i++) { | 9140 | for (i = 0; i < cfg->line_outs; i++) { |
8469 | if (! spec->multiout.dac_nids[i]) | 9141 | if (!spec->multiout.dac_nids[i]) |
8470 | continue; | 9142 | continue; |
8471 | nid_v = alc861vd_idx_to_mixer_vol( | 9143 | nid_v = alc861vd_idx_to_mixer_vol( |
8472 | alc880_dac_to_idx( | 9144 | alc880_dac_to_idx( |
@@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
8477 | 9149 | ||
8478 | if (i == 2) { | 9150 | if (i == 2) { |
8479 | /* Center/LFE */ | 9151 | /* Center/LFE */ |
8480 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | 9152 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
8481 | "Center Playback Volume", | 9153 | "Center Playback Volume", |
8482 | HDA_COMPOSE_AMP_VAL(nid_v, 1, | 9154 | HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, |
8483 | 0, HDA_OUTPUT))) < 0) | 9155 | HDA_OUTPUT)); |
9156 | if (err < 0) | ||
8484 | return err; | 9157 | return err; |
8485 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | 9158 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
8486 | "LFE Playback Volume", | 9159 | "LFE Playback Volume", |
8487 | HDA_COMPOSE_AMP_VAL(nid_v, 2, | 9160 | HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, |
8488 | 0, HDA_OUTPUT))) < 0) | 9161 | HDA_OUTPUT)); |
9162 | if (err < 0) | ||
8489 | return err; | 9163 | return err; |
8490 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | 9164 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
8491 | "Center Playback Switch", | 9165 | "Center Playback Switch", |
8492 | HDA_COMPOSE_AMP_VAL(nid_s, 1, | 9166 | HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, |
8493 | 2, HDA_INPUT))) < 0) | 9167 | HDA_INPUT)); |
9168 | if (err < 0) | ||
8494 | return err; | 9169 | return err; |
8495 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | 9170 | err = add_control(spec, ALC_CTL_BIND_MUTE, |
8496 | "LFE Playback Switch", | 9171 | "LFE Playback Switch", |
8497 | HDA_COMPOSE_AMP_VAL(nid_s, 2, | 9172 | HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, |
8498 | 2, HDA_INPUT))) < 0) | 9173 | HDA_INPUT)); |
9174 | if (err < 0) | ||
8499 | return err; | 9175 | return err; |
8500 | } else { | 9176 | } else { |
8501 | sprintf(name, "%s Playback Volume", chname[i]); | 9177 | sprintf(name, "%s Playback Volume", chname[i]); |
8502 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 9178 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
8503 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | 9179 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, |
8504 | 0, HDA_OUTPUT))) < 0) | 9180 | HDA_OUTPUT)); |
9181 | if (err < 0) | ||
8505 | return err; | 9182 | return err; |
8506 | sprintf(name, "%s Playback Switch", chname[i]); | 9183 | sprintf(name, "%s Playback Switch", chname[i]); |
8507 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 9184 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
8508 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | 9185 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, |
8509 | 2, HDA_INPUT))) < 0) | 9186 | HDA_INPUT)); |
9187 | if (err < 0) | ||
8510 | return err; | 9188 | return err; |
8511 | } | 9189 | } |
8512 | } | 9190 | } |
@@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
8523 | int err; | 9201 | int err; |
8524 | char name[32]; | 9202 | char name[32]; |
8525 | 9203 | ||
8526 | if (! pin) | 9204 | if (!pin) |
8527 | return 0; | 9205 | return 0; |
8528 | 9206 | ||
8529 | if (alc880_is_fixed_pin(pin)) { | 9207 | if (alc880_is_fixed_pin(pin)) { |
8530 | nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 9208 | nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
8531 | /* specify the DAC as the extra output */ | 9209 | /* specify the DAC as the extra output */ |
8532 | if (! spec->multiout.hp_nid) | 9210 | if (!spec->multiout.hp_nid) |
8533 | spec->multiout.hp_nid = nid_v; | 9211 | spec->multiout.hp_nid = nid_v; |
8534 | else | 9212 | else |
8535 | spec->multiout.extra_out_nid[0] = nid_v; | 9213 | spec->multiout.extra_out_nid[0] = nid_v; |
@@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | |||
8540 | alc880_fixed_pin_idx(pin)); | 9218 | alc880_fixed_pin_idx(pin)); |
8541 | 9219 | ||
8542 | sprintf(name, "%s Playback Volume", pfx); | 9220 | sprintf(name, "%s Playback Volume", pfx); |
8543 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 9221 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
8544 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, | 9222 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); |
8545 | HDA_OUTPUT))) < 0) | 9223 | if (err < 0) |
8546 | return err; | 9224 | return err; |
8547 | sprintf(name, "%s Playback Switch", pfx); | 9225 | sprintf(name, "%s Playback Switch", pfx); |
8548 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | 9226 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, |
8549 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, | 9227 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); |
8550 | HDA_INPUT))) < 0) | 9228 | if (err < 0) |
8551 | return err; | 9229 | return err; |
8552 | } else if (alc880_is_multi_pin(pin)) { | 9230 | } else if (alc880_is_multi_pin(pin)) { |
8553 | /* set manual connection */ | 9231 | /* set manual connection */ |
8554 | /* we have only a switch on HP-out PIN */ | 9232 | /* we have only a switch on HP-out PIN */ |
8555 | sprintf(name, "%s Playback Switch", pfx); | 9233 | sprintf(name, "%s Playback Switch", pfx); |
8556 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 9234 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
8557 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, | 9235 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
8558 | HDA_OUTPUT))) < 0) | 9236 | if (err < 0) |
8559 | return err; | 9237 | return err; |
8560 | } | 9238 | } |
8561 | return 0; | 9239 | return 0; |
@@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
8572 | int err; | 9250 | int err; |
8573 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 9251 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
8574 | 9252 | ||
8575 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 9253 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
8576 | alc861vd_ignore)) < 0) | 9254 | alc861vd_ignore); |
9255 | if (err < 0) | ||
8577 | return err; | 9256 | return err; |
8578 | if (! spec->autocfg.line_outs) | 9257 | if (!spec->autocfg.line_outs) |
8579 | return 0; /* can't find valid BIOS pin config */ | 9258 | return 0; /* can't find valid BIOS pin config */ |
8580 | 9259 | ||
8581 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 9260 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
8582 | (err = alc861vd_auto_create_multi_out_ctls(spec, | 9261 | if (err < 0) |
8583 | &spec->autocfg)) < 0 || | 9262 | return err; |
8584 | (err = alc861vd_auto_create_extra_out(spec, | 9263 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); |
8585 | spec->autocfg.speaker_pins[0], "Speaker")) < 0 || | 9264 | if (err < 0) |
8586 | (err = alc861vd_auto_create_extra_out(spec, | 9265 | return err; |
8587 | spec->autocfg.hp_pins[0], "Headphone")) < 0 || | 9266 | err = alc861vd_auto_create_extra_out(spec, |
8588 | (err = alc880_auto_create_analog_input_ctls(spec, | 9267 | spec->autocfg.speaker_pins[0], |
8589 | &spec->autocfg)) < 0) | 9268 | "Speaker"); |
9269 | if (err < 0) | ||
9270 | return err; | ||
9271 | err = alc861vd_auto_create_extra_out(spec, | ||
9272 | spec->autocfg.hp_pins[0], | ||
9273 | "Headphone"); | ||
9274 | if (err < 0) | ||
9275 | return err; | ||
9276 | err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
9277 | if (err < 0) | ||
8590 | return err; | 9278 | return err; |
8591 | 9279 | ||
8592 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 9280 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
@@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
8641 | if (err < 0) { | 9329 | if (err < 0) { |
8642 | alc_free(codec); | 9330 | alc_free(codec); |
8643 | return err; | 9331 | return err; |
8644 | } else if (! err) { | 9332 | } else if (!err) { |
8645 | printk(KERN_INFO | 9333 | printk(KERN_INFO |
8646 | "hda_codec: Cannot set up configuration " | 9334 | "hda_codec: Cannot set up configuration " |
8647 | "from BIOS. Using base mode...\n"); | 9335 | "from BIOS. Using base mode...\n"); |
@@ -8675,16 +9363,875 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
8675 | } | 9363 | } |
8676 | 9364 | ||
8677 | /* | 9365 | /* |
9366 | * ALC662 support | ||
9367 | * | ||
9368 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible | ||
9369 | * configuration. Each pin widget can choose any input DACs and a mixer. | ||
9370 | * Each ADC is connected from a mixer of all inputs. This makes possible | ||
9371 | * 6-channel independent captures. | ||
9372 | * | ||
9373 | * In addition, an independent DAC for the multi-playback (not used in this | ||
9374 | * driver yet). | ||
9375 | */ | ||
9376 | #define ALC662_DIGOUT_NID 0x06 | ||
9377 | #define ALC662_DIGIN_NID 0x0a | ||
9378 | |||
9379 | static hda_nid_t alc662_dac_nids[4] = { | ||
9380 | /* front, rear, clfe, rear_surr */ | ||
9381 | 0x02, 0x03, 0x04 | ||
9382 | }; | ||
9383 | |||
9384 | static hda_nid_t alc662_adc_nids[1] = { | ||
9385 | /* ADC1-2 */ | ||
9386 | 0x09, | ||
9387 | }; | ||
9388 | /* input MUX */ | ||
9389 | /* FIXME: should be a matrix-type input source selection */ | ||
9390 | |||
9391 | static struct hda_input_mux alc662_capture_source = { | ||
9392 | .num_items = 4, | ||
9393 | .items = { | ||
9394 | { "Mic", 0x0 }, | ||
9395 | { "Front Mic", 0x1 }, | ||
9396 | { "Line", 0x2 }, | ||
9397 | { "CD", 0x4 }, | ||
9398 | }, | ||
9399 | }; | ||
9400 | |||
9401 | static struct hda_input_mux alc662_lenovo_101e_capture_source = { | ||
9402 | .num_items = 2, | ||
9403 | .items = { | ||
9404 | { "Mic", 0x1 }, | ||
9405 | { "Line", 0x2 }, | ||
9406 | }, | ||
9407 | }; | ||
9408 | #define alc662_mux_enum_info alc_mux_enum_info | ||
9409 | #define alc662_mux_enum_get alc_mux_enum_get | ||
9410 | |||
9411 | static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
9412 | struct snd_ctl_elem_value *ucontrol) | ||
9413 | { | ||
9414 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
9415 | struct alc_spec *spec = codec->spec; | ||
9416 | const struct hda_input_mux *imux = spec->input_mux; | ||
9417 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
9418 | static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; | ||
9419 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
9420 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
9421 | unsigned int i, idx; | ||
9422 | |||
9423 | idx = ucontrol->value.enumerated.item[0]; | ||
9424 | if (idx >= imux->num_items) | ||
9425 | idx = imux->num_items - 1; | ||
9426 | if (*cur_val == idx && !codec->in_resume) | ||
9427 | return 0; | ||
9428 | for (i = 0; i < imux->num_items; i++) { | ||
9429 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
9430 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
9431 | v | (imux->items[i].index << 8)); | ||
9432 | } | ||
9433 | *cur_val = idx; | ||
9434 | return 1; | ||
9435 | } | ||
9436 | /* | ||
9437 | * 2ch mode | ||
9438 | */ | ||
9439 | static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { | ||
9440 | { 2, NULL } | ||
9441 | }; | ||
9442 | |||
9443 | /* | ||
9444 | * 2ch mode | ||
9445 | */ | ||
9446 | static struct hda_verb alc662_3ST_ch2_init[] = { | ||
9447 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
9448 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
9449 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
9450 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
9451 | { } /* end */ | ||
9452 | }; | ||
9453 | |||
9454 | /* | ||
9455 | * 6ch mode | ||
9456 | */ | ||
9457 | static struct hda_verb alc662_3ST_ch6_init[] = { | ||
9458 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9459 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
9460 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
9461 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9462 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
9463 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
9464 | { } /* end */ | ||
9465 | }; | ||
9466 | |||
9467 | static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { | ||
9468 | { 2, alc662_3ST_ch2_init }, | ||
9469 | { 6, alc662_3ST_ch6_init }, | ||
9470 | }; | ||
9471 | |||
9472 | /* | ||
9473 | * 2ch mode | ||
9474 | */ | ||
9475 | static struct hda_verb alc662_sixstack_ch6_init[] = { | ||
9476 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
9477 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
9478 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9479 | { } /* end */ | ||
9480 | }; | ||
9481 | |||
9482 | /* | ||
9483 | * 6ch mode | ||
9484 | */ | ||
9485 | static struct hda_verb alc662_sixstack_ch8_init[] = { | ||
9486 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9487 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9488 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
9489 | { } /* end */ | ||
9490 | }; | ||
9491 | |||
9492 | static struct hda_channel_mode alc662_5stack_modes[2] = { | ||
9493 | { 2, alc662_sixstack_ch6_init }, | ||
9494 | { 6, alc662_sixstack_ch8_init }, | ||
9495 | }; | ||
9496 | |||
9497 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
9498 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
9499 | */ | ||
9500 | |||
9501 | static struct snd_kcontrol_new alc662_base_mixer[] = { | ||
9502 | /* output mixer control */ | ||
9503 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
9504 | HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), | ||
9505 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
9506 | HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
9507 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
9508 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
9509 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), | ||
9510 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), | ||
9511 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9512 | |||
9513 | /*Input mixer control */ | ||
9514 | HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), | ||
9515 | HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), | ||
9516 | HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), | ||
9517 | HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), | ||
9518 | HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), | ||
9519 | HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), | ||
9520 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), | ||
9521 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), | ||
9522 | |||
9523 | /* Capture mixer control */ | ||
9524 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9525 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9526 | { | ||
9527 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9528 | .name = "Capture Source", | ||
9529 | .count = 1, | ||
9530 | .info = alc_mux_enum_info, | ||
9531 | .get = alc_mux_enum_get, | ||
9532 | .put = alc_mux_enum_put, | ||
9533 | }, | ||
9534 | { } /* end */ | ||
9535 | }; | ||
9536 | |||
9537 | static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | ||
9538 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9539 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9540 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9541 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9542 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9543 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9544 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9545 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9546 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9547 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9548 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9549 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9550 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9551 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9552 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9553 | { | ||
9554 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9555 | /* .name = "Capture Source", */ | ||
9556 | .name = "Input Source", | ||
9557 | .count = 1, | ||
9558 | .info = alc662_mux_enum_info, | ||
9559 | .get = alc662_mux_enum_get, | ||
9560 | .put = alc662_mux_enum_put, | ||
9561 | }, | ||
9562 | { } /* end */ | ||
9563 | }; | ||
9564 | |||
9565 | static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | ||
9566 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9567 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9568 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
9569 | HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), | ||
9570 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
9571 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
9572 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), | ||
9573 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), | ||
9574 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9575 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9576 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9577 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9578 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9579 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9580 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9581 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9582 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9583 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9584 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9585 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9586 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9587 | { | ||
9588 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9589 | /* .name = "Capture Source", */ | ||
9590 | .name = "Input Source", | ||
9591 | .count = 1, | ||
9592 | .info = alc662_mux_enum_info, | ||
9593 | .get = alc662_mux_enum_get, | ||
9594 | .put = alc662_mux_enum_put, | ||
9595 | }, | ||
9596 | { } /* end */ | ||
9597 | }; | ||
9598 | |||
9599 | static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | ||
9600 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
9601 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
9602 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
9603 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), | ||
9604 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9605 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9606 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9607 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
9608 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
9609 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9610 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9611 | { | ||
9612 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9613 | /* .name = "Capture Source", */ | ||
9614 | .name = "Input Source", | ||
9615 | .count = 1, | ||
9616 | .info = alc662_mux_enum_info, | ||
9617 | .get = alc662_mux_enum_get, | ||
9618 | .put = alc662_mux_enum_put, | ||
9619 | }, | ||
9620 | { } /* end */ | ||
9621 | }; | ||
9622 | |||
9623 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { | ||
9624 | { | ||
9625 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9626 | .name = "Channel Mode", | ||
9627 | .info = alc_ch_mode_info, | ||
9628 | .get = alc_ch_mode_get, | ||
9629 | .put = alc_ch_mode_put, | ||
9630 | }, | ||
9631 | { } /* end */ | ||
9632 | }; | ||
9633 | |||
9634 | static struct hda_verb alc662_init_verbs[] = { | ||
9635 | /* ADC: mute amp left and right */ | ||
9636 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
9637 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9638 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
9639 | |||
9640 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9641 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9642 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9643 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
9644 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9645 | |||
9646 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9647 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9648 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9649 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9650 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9651 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9652 | |||
9653 | /* Front Pin: output 0 (0x0c) */ | ||
9654 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9655 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9656 | |||
9657 | /* Rear Pin: output 1 (0x0d) */ | ||
9658 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9659 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9660 | |||
9661 | /* CLFE Pin: output 2 (0x0e) */ | ||
9662 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
9663 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9664 | |||
9665 | /* Mic (rear) pin: input vref at 80% */ | ||
9666 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
9667 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9668 | /* Front Mic pin: input vref at 80% */ | ||
9669 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
9670 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9671 | /* Line In pin: input */ | ||
9672 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
9673 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
9674 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
9675 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
9676 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
9677 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9678 | /* CD pin widget for input */ | ||
9679 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
9680 | |||
9681 | /* FIXME: use matrix-type input source selection */ | ||
9682 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
9683 | /* Input mixer */ | ||
9684 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9685 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9686 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9687 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9688 | { } | ||
9689 | }; | ||
9690 | |||
9691 | static struct hda_verb alc662_sue_init_verbs[] = { | ||
9692 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, | ||
9693 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, | ||
9694 | {} | ||
9695 | }; | ||
9696 | |||
9697 | /* | ||
9698 | * generic initialization of ADC, input mixers and output mixers | ||
9699 | */ | ||
9700 | static struct hda_verb alc662_auto_init_verbs[] = { | ||
9701 | /* | ||
9702 | * Unmute ADC and set the default input to mic-in | ||
9703 | */ | ||
9704 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9705 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9706 | |||
9707 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
9708 | * mixer widget | ||
9709 | * Note: PASD motherboards uses the Line In 2 as the input for front | ||
9710 | * panel mic (mic 2) | ||
9711 | */ | ||
9712 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
9713 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9714 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9715 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9716 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
9717 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9718 | |||
9719 | /* | ||
9720 | * Set up output mixers (0x0c - 0x0f) | ||
9721 | */ | ||
9722 | /* set vol=0 to output mixers */ | ||
9723 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9724 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9725 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
9726 | |||
9727 | /* set up input amps for analog loopback */ | ||
9728 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
9729 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9730 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9731 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9732 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9733 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9734 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9735 | |||
9736 | |||
9737 | /* FIXME: use matrix-type input source selection */ | ||
9738 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
9739 | /* Input mixer */ | ||
9740 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
9741 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
9742 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
9743 | /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ | ||
9744 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
9745 | |||
9746 | { } | ||
9747 | }; | ||
9748 | |||
9749 | /* capture mixer elements */ | ||
9750 | static struct snd_kcontrol_new alc662_capture_mixer[] = { | ||
9751 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
9752 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
9753 | { | ||
9754 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9755 | /* The multiple "Capture Source" controls confuse alsamixer | ||
9756 | * So call somewhat different.. | ||
9757 | * FIXME: the controls appear in the "playback" view! | ||
9758 | */ | ||
9759 | /* .name = "Capture Source", */ | ||
9760 | .name = "Input Source", | ||
9761 | .count = 1, | ||
9762 | .info = alc882_mux_enum_info, | ||
9763 | .get = alc882_mux_enum_get, | ||
9764 | .put = alc882_mux_enum_put, | ||
9765 | }, | ||
9766 | { } /* end */ | ||
9767 | }; | ||
9768 | |||
9769 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | ||
9770 | { | ||
9771 | unsigned int present; | ||
9772 | unsigned char bits; | ||
9773 | |||
9774 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
9775 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
9776 | bits = present ? 0x80 : 0; | ||
9777 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
9778 | 0x80, bits); | ||
9779 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
9780 | 0x80, bits); | ||
9781 | } | ||
9782 | |||
9783 | static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) | ||
9784 | { | ||
9785 | unsigned int present; | ||
9786 | unsigned char bits; | ||
9787 | |||
9788 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
9789 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
9790 | bits = present ? 0x80 : 0; | ||
9791 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
9792 | 0x80, bits); | ||
9793 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
9794 | 0x80, bits); | ||
9795 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
9796 | 0x80, bits); | ||
9797 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
9798 | 0x80, bits); | ||
9799 | } | ||
9800 | |||
9801 | static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, | ||
9802 | unsigned int res) | ||
9803 | { | ||
9804 | if ((res >> 26) == ALC880_HP_EVENT) | ||
9805 | alc662_lenovo_101e_all_automute(codec); | ||
9806 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
9807 | alc662_lenovo_101e_ispeaker_automute(codec); | ||
9808 | } | ||
9809 | |||
9810 | |||
9811 | /* pcm configuration: identiacal with ALC880 */ | ||
9812 | #define alc662_pcm_analog_playback alc880_pcm_analog_playback | ||
9813 | #define alc662_pcm_analog_capture alc880_pcm_analog_capture | ||
9814 | #define alc662_pcm_digital_playback alc880_pcm_digital_playback | ||
9815 | #define alc662_pcm_digital_capture alc880_pcm_digital_capture | ||
9816 | |||
9817 | /* | ||
9818 | * configuration and preset | ||
9819 | */ | ||
9820 | static const char *alc662_models[ALC662_MODEL_LAST] = { | ||
9821 | [ALC662_3ST_2ch_DIG] = "3stack-dig", | ||
9822 | [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", | ||
9823 | [ALC662_3ST_6ch] = "3stack-6ch", | ||
9824 | [ALC662_5ST_DIG] = "6stack-dig", | ||
9825 | [ALC662_LENOVO_101E] = "lenovo-101e", | ||
9826 | [ALC662_AUTO] = "auto", | ||
9827 | }; | ||
9828 | |||
9829 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | ||
9830 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | ||
9831 | {} | ||
9832 | }; | ||
9833 | |||
9834 | static struct alc_config_preset alc662_presets[] = { | ||
9835 | [ALC662_3ST_2ch_DIG] = { | ||
9836 | .mixers = { alc662_3ST_2ch_mixer }, | ||
9837 | .init_verbs = { alc662_init_verbs }, | ||
9838 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9839 | .dac_nids = alc662_dac_nids, | ||
9840 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9841 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9842 | .adc_nids = alc662_adc_nids, | ||
9843 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9844 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
9845 | .channel_mode = alc662_3ST_2ch_modes, | ||
9846 | .input_mux = &alc662_capture_source, | ||
9847 | }, | ||
9848 | [ALC662_3ST_6ch_DIG] = { | ||
9849 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
9850 | .init_verbs = { alc662_init_verbs }, | ||
9851 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9852 | .dac_nids = alc662_dac_nids, | ||
9853 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9854 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9855 | .adc_nids = alc662_adc_nids, | ||
9856 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9857 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
9858 | .channel_mode = alc662_3ST_6ch_modes, | ||
9859 | .need_dac_fix = 1, | ||
9860 | .input_mux = &alc662_capture_source, | ||
9861 | }, | ||
9862 | [ALC662_3ST_6ch] = { | ||
9863 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
9864 | .init_verbs = { alc662_init_verbs }, | ||
9865 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9866 | .dac_nids = alc662_dac_nids, | ||
9867 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9868 | .adc_nids = alc662_adc_nids, | ||
9869 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
9870 | .channel_mode = alc662_3ST_6ch_modes, | ||
9871 | .need_dac_fix = 1, | ||
9872 | .input_mux = &alc662_capture_source, | ||
9873 | }, | ||
9874 | [ALC662_5ST_DIG] = { | ||
9875 | .mixers = { alc662_base_mixer, alc662_chmode_mixer }, | ||
9876 | .init_verbs = { alc662_init_verbs }, | ||
9877 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9878 | .dac_nids = alc662_dac_nids, | ||
9879 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
9880 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9881 | .adc_nids = alc662_adc_nids, | ||
9882 | .dig_in_nid = ALC662_DIGIN_NID, | ||
9883 | .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), | ||
9884 | .channel_mode = alc662_5stack_modes, | ||
9885 | .input_mux = &alc662_capture_source, | ||
9886 | }, | ||
9887 | [ALC662_LENOVO_101E] = { | ||
9888 | .mixers = { alc662_lenovo_101e_mixer }, | ||
9889 | .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, | ||
9890 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
9891 | .dac_nids = alc662_dac_nids, | ||
9892 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
9893 | .adc_nids = alc662_adc_nids, | ||
9894 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
9895 | .channel_mode = alc662_3ST_2ch_modes, | ||
9896 | .input_mux = &alc662_lenovo_101e_capture_source, | ||
9897 | .unsol_event = alc662_lenovo_101e_unsol_event, | ||
9898 | .init_hook = alc662_lenovo_101e_all_automute, | ||
9899 | }, | ||
9900 | |||
9901 | }; | ||
9902 | |||
9903 | |||
9904 | /* | ||
9905 | * BIOS auto configuration | ||
9906 | */ | ||
9907 | |||
9908 | /* add playback controls from the parsed DAC table */ | ||
9909 | static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
9910 | const struct auto_pin_cfg *cfg) | ||
9911 | { | ||
9912 | char name[32]; | ||
9913 | static const char *chname[4] = { | ||
9914 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
9915 | }; | ||
9916 | hda_nid_t nid; | ||
9917 | int i, err; | ||
9918 | |||
9919 | for (i = 0; i < cfg->line_outs; i++) { | ||
9920 | if (!spec->multiout.dac_nids[i]) | ||
9921 | continue; | ||
9922 | nid = alc880_idx_to_dac(i); | ||
9923 | if (i == 2) { | ||
9924 | /* Center/LFE */ | ||
9925 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9926 | "Center Playback Volume", | ||
9927 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
9928 | HDA_OUTPUT)); | ||
9929 | if (err < 0) | ||
9930 | return err; | ||
9931 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9932 | "LFE Playback Volume", | ||
9933 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
9934 | HDA_OUTPUT)); | ||
9935 | if (err < 0) | ||
9936 | return err; | ||
9937 | err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
9938 | "Center Playback Switch", | ||
9939 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | ||
9940 | HDA_INPUT)); | ||
9941 | if (err < 0) | ||
9942 | return err; | ||
9943 | err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
9944 | "LFE Playback Switch", | ||
9945 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | ||
9946 | HDA_INPUT)); | ||
9947 | if (err < 0) | ||
9948 | return err; | ||
9949 | } else { | ||
9950 | sprintf(name, "%s Playback Volume", chname[i]); | ||
9951 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
9952 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
9953 | HDA_OUTPUT)); | ||
9954 | if (err < 0) | ||
9955 | return err; | ||
9956 | sprintf(name, "%s Playback Switch", chname[i]); | ||
9957 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
9958 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | ||
9959 | HDA_INPUT)); | ||
9960 | if (err < 0) | ||
9961 | return err; | ||
9962 | } | ||
9963 | } | ||
9964 | return 0; | ||
9965 | } | ||
9966 | |||
9967 | /* add playback controls for speaker and HP outputs */ | ||
9968 | static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | ||
9969 | const char *pfx) | ||
9970 | { | ||
9971 | hda_nid_t nid; | ||
9972 | int err; | ||
9973 | char name[32]; | ||
9974 | |||
9975 | if (!pin) | ||
9976 | return 0; | ||
9977 | |||
9978 | if (alc880_is_fixed_pin(pin)) { | ||
9979 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
9980 | /* printk("DAC nid=%x\n",nid); */ | ||
9981 | /* specify the DAC as the extra output */ | ||
9982 | if (!spec->multiout.hp_nid) | ||
9983 | spec->multiout.hp_nid = nid; | ||
9984 | else | ||
9985 | spec->multiout.extra_out_nid[0] = nid; | ||
9986 | /* control HP volume/switch on the output mixer amp */ | ||
9987 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
9988 | sprintf(name, "%s Playback Volume", pfx); | ||
9989 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
9990 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
9991 | if (err < 0) | ||
9992 | return err; | ||
9993 | sprintf(name, "%s Playback Switch", pfx); | ||
9994 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
9995 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); | ||
9996 | if (err < 0) | ||
9997 | return err; | ||
9998 | } else if (alc880_is_multi_pin(pin)) { | ||
9999 | /* set manual connection */ | ||
10000 | /* we have only a switch on HP-out PIN */ | ||
10001 | sprintf(name, "%s Playback Switch", pfx); | ||
10002 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
10003 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | ||
10004 | if (err < 0) | ||
10005 | return err; | ||
10006 | } | ||
10007 | return 0; | ||
10008 | } | ||
10009 | |||
10010 | /* create playback/capture controls for input pins */ | ||
10011 | static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, | ||
10012 | const struct auto_pin_cfg *cfg) | ||
10013 | { | ||
10014 | struct hda_input_mux *imux = &spec->private_imux; | ||
10015 | int i, err, idx; | ||
10016 | |||
10017 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
10018 | if (alc880_is_input_pin(cfg->input_pins[i])) { | ||
10019 | idx = alc880_input_pin_idx(cfg->input_pins[i]); | ||
10020 | err = new_analog_input(spec, cfg->input_pins[i], | ||
10021 | auto_pin_cfg_labels[i], | ||
10022 | idx, 0x0b); | ||
10023 | if (err < 0) | ||
10024 | return err; | ||
10025 | imux->items[imux->num_items].label = | ||
10026 | auto_pin_cfg_labels[i]; | ||
10027 | imux->items[imux->num_items].index = | ||
10028 | alc880_input_pin_idx(cfg->input_pins[i]); | ||
10029 | imux->num_items++; | ||
10030 | } | ||
10031 | } | ||
10032 | return 0; | ||
10033 | } | ||
10034 | |||
10035 | static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | ||
10036 | hda_nid_t nid, int pin_type, | ||
10037 | int dac_idx) | ||
10038 | { | ||
10039 | /* set as output */ | ||
10040 | snd_hda_codec_write(codec, nid, 0, | ||
10041 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | ||
10042 | snd_hda_codec_write(codec, nid, 0, | ||
10043 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
10044 | /* need the manual connection? */ | ||
10045 | if (alc880_is_multi_pin(nid)) { | ||
10046 | struct alc_spec *spec = codec->spec; | ||
10047 | int idx = alc880_multi_pin_idx(nid); | ||
10048 | snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, | ||
10049 | AC_VERB_SET_CONNECT_SEL, | ||
10050 | alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); | ||
10051 | } | ||
10052 | } | ||
10053 | |||
10054 | static void alc662_auto_init_multi_out(struct hda_codec *codec) | ||
10055 | { | ||
10056 | struct alc_spec *spec = codec->spec; | ||
10057 | int i; | ||
10058 | |||
10059 | for (i = 0; i <= HDA_SIDE; i++) { | ||
10060 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
10061 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
10062 | if (nid) | ||
10063 | alc662_auto_set_output_and_unmute(codec, nid, pin_type, | ||
10064 | i); | ||
10065 | } | ||
10066 | } | ||
10067 | |||
10068 | static void alc662_auto_init_hp_out(struct hda_codec *codec) | ||
10069 | { | ||
10070 | struct alc_spec *spec = codec->spec; | ||
10071 | hda_nid_t pin; | ||
10072 | |||
10073 | pin = spec->autocfg.hp_pins[0]; | ||
10074 | if (pin) /* connect to front */ | ||
10075 | /* use dac 0 */ | ||
10076 | alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
10077 | } | ||
10078 | |||
10079 | #define alc662_is_input_pin(nid) alc880_is_input_pin(nid) | ||
10080 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID | ||
10081 | |||
10082 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | ||
10083 | { | ||
10084 | struct alc_spec *spec = codec->spec; | ||
10085 | int i; | ||
10086 | |||
10087 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
10088 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
10089 | if (alc662_is_input_pin(nid)) { | ||
10090 | snd_hda_codec_write(codec, nid, 0, | ||
10091 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
10092 | (i <= AUTO_PIN_FRONT_MIC ? | ||
10093 | PIN_VREF80 : PIN_IN)); | ||
10094 | if (nid != ALC662_PIN_CD_NID) | ||
10095 | snd_hda_codec_write(codec, nid, 0, | ||
10096 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
10097 | AMP_OUT_MUTE); | ||
10098 | } | ||
10099 | } | ||
10100 | } | ||
10101 | |||
10102 | static int alc662_parse_auto_config(struct hda_codec *codec) | ||
10103 | { | ||
10104 | struct alc_spec *spec = codec->spec; | ||
10105 | int err; | ||
10106 | static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | ||
10107 | |||
10108 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
10109 | alc662_ignore); | ||
10110 | if (err < 0) | ||
10111 | return err; | ||
10112 | if (!spec->autocfg.line_outs) | ||
10113 | return 0; /* can't find valid BIOS pin config */ | ||
10114 | |||
10115 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); | ||
10116 | if (err < 0) | ||
10117 | return err; | ||
10118 | err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); | ||
10119 | if (err < 0) | ||
10120 | return err; | ||
10121 | err = alc662_auto_create_extra_out(spec, | ||
10122 | spec->autocfg.speaker_pins[0], | ||
10123 | "Speaker"); | ||
10124 | if (err < 0) | ||
10125 | return err; | ||
10126 | err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | ||
10127 | "Headphone"); | ||
10128 | if (err < 0) | ||
10129 | return err; | ||
10130 | err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
10131 | if (err < 0) | ||
10132 | return err; | ||
10133 | |||
10134 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
10135 | |||
10136 | if (spec->autocfg.dig_out_pin) | ||
10137 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
10138 | |||
10139 | if (spec->kctl_alloc) | ||
10140 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
10141 | |||
10142 | spec->num_mux_defs = 1; | ||
10143 | spec->input_mux = &spec->private_imux; | ||
10144 | |||
10145 | if (err < 0) | ||
10146 | return err; | ||
10147 | else if (err > 0) | ||
10148 | /* hack - override the init verbs */ | ||
10149 | spec->init_verbs[0] = alc662_auto_init_verbs; | ||
10150 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; | ||
10151 | spec->num_mixers++; | ||
10152 | return err; | ||
10153 | } | ||
10154 | |||
10155 | /* additional initialization for auto-configuration model */ | ||
10156 | static void alc662_auto_init(struct hda_codec *codec) | ||
10157 | { | ||
10158 | alc662_auto_init_multi_out(codec); | ||
10159 | alc662_auto_init_hp_out(codec); | ||
10160 | alc662_auto_init_analog_input(codec); | ||
10161 | } | ||
10162 | |||
10163 | static int patch_alc662(struct hda_codec *codec) | ||
10164 | { | ||
10165 | struct alc_spec *spec; | ||
10166 | int err, board_config; | ||
10167 | |||
10168 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
10169 | if (!spec) | ||
10170 | return -ENOMEM; | ||
10171 | |||
10172 | codec->spec = spec; | ||
10173 | |||
10174 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | ||
10175 | alc662_models, | ||
10176 | alc662_cfg_tbl); | ||
10177 | if (board_config < 0) { | ||
10178 | printk(KERN_INFO "hda_codec: Unknown model for ALC662, " | ||
10179 | "trying auto-probe from BIOS...\n"); | ||
10180 | board_config = ALC662_AUTO; | ||
10181 | } | ||
10182 | |||
10183 | if (board_config == ALC662_AUTO) { | ||
10184 | /* automatic parse from the BIOS config */ | ||
10185 | err = alc662_parse_auto_config(codec); | ||
10186 | if (err < 0) { | ||
10187 | alc_free(codec); | ||
10188 | return err; | ||
10189 | } else if (err) { | ||
10190 | printk(KERN_INFO | ||
10191 | "hda_codec: Cannot set up configuration " | ||
10192 | "from BIOS. Using base mode...\n"); | ||
10193 | board_config = ALC662_3ST_2ch_DIG; | ||
10194 | } | ||
10195 | } | ||
10196 | |||
10197 | if (board_config != ALC662_AUTO) | ||
10198 | setup_preset(spec, &alc662_presets[board_config]); | ||
10199 | |||
10200 | spec->stream_name_analog = "ALC662 Analog"; | ||
10201 | spec->stream_analog_playback = &alc662_pcm_analog_playback; | ||
10202 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | ||
10203 | |||
10204 | spec->stream_name_digital = "ALC662 Digital"; | ||
10205 | spec->stream_digital_playback = &alc662_pcm_digital_playback; | ||
10206 | spec->stream_digital_capture = &alc662_pcm_digital_capture; | ||
10207 | |||
10208 | if (!spec->adc_nids && spec->input_mux) { | ||
10209 | spec->adc_nids = alc662_adc_nids; | ||
10210 | spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); | ||
10211 | } | ||
10212 | |||
10213 | codec->patch_ops = alc_patch_ops; | ||
10214 | if (board_config == ALC662_AUTO) | ||
10215 | spec->init_hook = alc662_auto_init; | ||
10216 | |||
10217 | return 0; | ||
10218 | } | ||
10219 | |||
10220 | /* | ||
8678 | * patch entries | 10221 | * patch entries |
8679 | */ | 10222 | */ |
8680 | struct hda_codec_preset snd_hda_preset_realtek[] = { | 10223 | struct hda_codec_preset snd_hda_preset_realtek[] = { |
8681 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 10224 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
8682 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 10225 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
8683 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 10226 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
8684 | .patch = patch_alc861 }, | 10227 | .patch = patch_alc861 }, |
8685 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 10228 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
8686 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 10229 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
8687 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 10230 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
10231 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | ||
10232 | .patch = patch_alc883 }, | ||
10233 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | ||
10234 | .patch = patch_alc662 }, | ||
8688 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 10235 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
8689 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 10236 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
8690 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, | 10237 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |