aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-03-01 06:38:54 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-01 06:38:54 -0500
commita91a4aa1ee994abeb2190a1bb2f703933609a703 (patch)
tree1237ed9b6784e5c260245ccf3dde389c3125311d /sound/pci
parent12c2a682b55a40f2a986e36d6632110029bc63a5 (diff)
parent61c2d2b5e7241d4410ab8227ef4f76c1aba8210b (diff)
Merge branch 'topic/hda' into for-linus
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c6
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_hwdep.c53
-rw-r--r--sound/pci/hda/hda_intel.c28
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_conexant.c255
-rw-r--r--sound/pci/hda/patch_realtek.c830
-rw-r--r--sound/pci/hda/patch_sigmatel.c151
8 files changed, 844 insertions, 484 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 26ceace88c96..76d3c4c049db 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2767,7 +2767,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2767 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2767 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2768 power_state); 2768 power_state);
2769 /* partial workaround for "azx_get_response timeout" */ 2769 /* partial workaround for "azx_get_response timeout" */
2770 if (power_state == AC_PWRST_D0) 2770 if (power_state == AC_PWRST_D0 &&
2771 (codec->vendor_id & 0xffff0000) == 0x14f10000)
2771 msleep(10); 2772 msleep(10);
2772 2773
2773 nid = codec->start_nid; 2774 nid = codec->start_nid;
@@ -2801,7 +2802,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2801 if (power_state == AC_PWRST_D0) { 2802 if (power_state == AC_PWRST_D0) {
2802 unsigned long end_time; 2803 unsigned long end_time;
2803 int state; 2804 int state;
2804 msleep(10);
2805 /* wait until the codec reachs to D0 */ 2805 /* wait until the codec reachs to D0 */
2806 end_time = jiffies + msecs_to_jiffies(500); 2806 end_time = jiffies + msecs_to_jiffies(500);
2807 do { 2807 do {
@@ -3275,6 +3275,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3275 3275
3276/* 3276/*
3277 * get the empty PCM device number to assign 3277 * get the empty PCM device number to assign
3278 *
3279 * note the max device number is limited by HDA_MAX_PCMS, currently 10
3278 */ 3280 */
3279static int get_empty_pcm_device(struct hda_bus *bus, int type) 3281static int get_empty_pcm_device(struct hda_bus *bus, int type)
3280{ 3282{
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0c8f05cc56be..b75da47571e6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -527,6 +527,9 @@ enum {
527/* max. codec address */ 527/* max. codec address */
528#define HDA_MAX_CODEC_ADDRESS 0x0f 528#define HDA_MAX_CODEC_ADDRESS 0x0f
529 529
530/* max number of PCM devics per card */
531#define HDA_MAX_PCMS 10
532
530/* 533/*
531 * generic arrays 534 * generic arrays
532 */ 535 */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index b36919c0d363..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -625,6 +625,10 @@ enum {
625 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
626 LINE_MODE_VERB, 626 LINE_MODE_VERB,
627 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
628 NUM_LINE_MODES, 632 NUM_LINE_MODES,
629}; 633};
630 634
@@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
654} 658}
655 659
656/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
657 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
658 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
659 */ 663 */
660static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
661 struct hda_codec **codecp) 665 struct hda_codec **codecp)
662{ 666{
663 if (!*codecp)
664 return;
665 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
666} 668}
667 669
668static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
669 struct hda_codec **codecp) 671 struct hda_codec **codecp)
670{ 672{
671 if (!*codecp)
672 return;
673 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
674} 674}
675 675
676static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
677 struct hda_codec **codecp) 677 struct hda_codec **codecp)
678{ 678{
679 if (!*codecp)
680 return;
681 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
682} 680}
683 681
684static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
685 struct hda_codec **codecp) 683 struct hda_codec **codecp)
686{ 684{
687 if (!*codecp)
688 return;
689 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
690 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
691} 687}
692 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
693struct hda_patch_item { 710struct hda_patch_item {
694 const char *tag; 711 const char *tag;
695 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
696}; 714};
697 715
698static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
699 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
700 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
701 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
702 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
703 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
704}; 726};
705 727
706/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
783 continue; 805 continue;
784 if (*buf == '[') 806 if (*buf == '[')
785 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
786 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
787 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
788 } 811 }
789 release_firmware(fw); 812 release_firmware(fw);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 9925055608b1..d5c93ad852ee 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -125,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
125 "{Intel, ICH9}," 125 "{Intel, ICH9},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT},"
128 "{Intel, SCH}," 129 "{Intel, SCH},"
129 "{ATI, SB450}," 130 "{ATI, SB450},"
130 "{ATI, SB600}," 131 "{ATI, SB600},"
@@ -259,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259#define AZX_MAX_FRAG 32 260#define AZX_MAX_FRAG 32
260/* max buffer size - no h/w limit, you can increase as you like */ 261/* max buffer size - no h/w limit, you can increase as you like */
261#define AZX_MAX_BUF_SIZE (1024*1024*1024) 262#define AZX_MAX_BUF_SIZE (1024*1024*1024)
262/* max number of PCM devics per card */
263#define AZX_MAX_PCMS 8
264 263
265/* RIRB int mask: overrun[2], response[0] */ 264/* RIRB int mask: overrun[2], response[0] */
266#define RIRB_INT_RESPONSE 0x01 265#define RIRB_INT_RESPONSE 0x01
@@ -408,7 +407,7 @@ struct azx {
408 struct azx_dev *azx_dev; 407 struct azx_dev *azx_dev;
409 408
410 /* PCM */ 409 /* PCM */
411 struct snd_pcm *pcm[AZX_MAX_PCMS]; 410 struct snd_pcm *pcm[HDA_MAX_PCMS];
412 411
413 /* HD codec */ 412 /* HD codec */
414 unsigned short codec_mask; 413 unsigned short codec_mask;
@@ -449,6 +448,7 @@ struct azx {
449/* driver types */ 448/* driver types */
450enum { 449enum {
451 AZX_DRIVER_ICH, 450 AZX_DRIVER_ICH,
451 AZX_DRIVER_PCH,
452 AZX_DRIVER_SCH, 452 AZX_DRIVER_SCH,
453 AZX_DRIVER_ATI, 453 AZX_DRIVER_ATI,
454 AZX_DRIVER_ATIHDMI, 454 AZX_DRIVER_ATIHDMI,
@@ -463,6 +463,7 @@ enum {
463 463
464static char *driver_short_names[] __devinitdata = { 464static char *driver_short_names[] __devinitdata = {
465 [AZX_DRIVER_ICH] = "HDA Intel", 465 [AZX_DRIVER_ICH] = "HDA Intel",
466 [AZX_DRIVER_PCH] = "HDA Intel PCH",
466 [AZX_DRIVER_SCH] = "HDA Intel MID", 467 [AZX_DRIVER_SCH] = "HDA Intel MID",
467 [AZX_DRIVER_ATI] = "HDA ATI SB", 468 [AZX_DRIVER_ATI] = "HDA ATI SB",
468 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 469 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
@@ -968,8 +969,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
968 azx_dev->insufficient = 1; 969 azx_dev->insufficient = 1;
969 970
970 /* enable SIE */ 971 /* enable SIE */
971 azx_writeb(chip, INTCTL, 972 azx_writel(chip, INTCTL,
972 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 973 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
973 /* set DMA start and interrupt mask */ 974 /* set DMA start and interrupt mask */
974 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | 975 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
975 SD_CTL_DMA_START | SD_INT_MASK); 976 SD_CTL_DMA_START | SD_INT_MASK);
@@ -988,8 +989,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
988{ 989{
989 azx_stream_clear(chip, azx_dev); 990 azx_stream_clear(chip, azx_dev);
990 /* disable SIE */ 991 /* disable SIE */
991 azx_writeb(chip, INTCTL, 992 azx_writel(chip, INTCTL,
992 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); 993 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
993} 994}
994 995
995 996
@@ -1065,6 +1066,7 @@ static void azx_init_pci(struct azx *chip)
1065 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1066 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1066 break; 1067 break;
1067 case AZX_DRIVER_SCH: 1068 case AZX_DRIVER_SCH:
1069 case AZX_DRIVER_PCH:
1068 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1070 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1069 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1071 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1070 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1072 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1350,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1350 if (chip->initialized) { 1352 if (chip->initialized) {
1351 int i; 1353 int i;
1352 1354
1353 for (i = 0; i < AZX_MAX_PCMS; i++) 1355 for (i = 0; i < HDA_MAX_PCMS; i++)
1354 snd_pcm_suspend_all(chip->pcm[i]); 1356 snd_pcm_suspend_all(chip->pcm[i]);
1355 snd_hda_suspend(chip->bus); 1357 snd_hda_suspend(chip->bus);
1356 snd_hda_resume(chip->bus); 1358 snd_hda_resume(chip->bus);
@@ -1412,7 +1414,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1412 chip->codec_mask &= ~(1 << c); 1414 chip->codec_mask &= ~(1 << c);
1413 /* More badly, accessing to a non-existing 1415 /* More badly, accessing to a non-existing
1414 * codec often screws up the controller chip, 1416 * codec often screws up the controller chip,
1415 * and distrubs the further communications. 1417 * and disturbs the further communications.
1416 * Thus if an error occurs during probing, 1418 * Thus if an error occurs during probing,
1417 * better to reset the controller chip to 1419 * better to reset the controller chip to
1418 * get back to the sanity state. 1420 * get back to the sanity state.
@@ -1983,7 +1985,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1983 int pcm_dev = cpcm->device; 1985 int pcm_dev = cpcm->device;
1984 int s, err; 1986 int s, err;
1985 1987
1986 if (pcm_dev >= AZX_MAX_PCMS) { 1988 if (pcm_dev >= HDA_MAX_PCMS) {
1987 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 1989 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1988 pcm_dev); 1990 pcm_dev);
1989 return -EINVAL; 1991 return -EINVAL;
@@ -2139,7 +2141,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2139 2141
2140 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2142 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2141 azx_clear_irq_pending(chip); 2143 azx_clear_irq_pending(chip);
2142 for (i = 0; i < AZX_MAX_PCMS; i++) 2144 for (i = 0; i < HDA_MAX_PCMS; i++)
2143 snd_pcm_suspend_all(chip->pcm[i]); 2145 snd_pcm_suspend_all(chip->pcm[i]);
2144 if (chip->initialized) 2146 if (chip->initialized)
2145 snd_hda_suspend(chip->bus); 2147 snd_hda_suspend(chip->bus);
@@ -2262,6 +2264,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2262 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2264 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2263 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2265 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2264 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2268 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2267 {} 2270 {}
@@ -2418,6 +2421,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2418 if (bdl_pos_adj[dev] < 0) { 2421 if (bdl_pos_adj[dev] < 0) {
2419 switch (chip->driver_type) { 2422 switch (chip->driver_type) {
2420 case AZX_DRIVER_ICH: 2423 case AZX_DRIVER_ICH:
2424 case AZX_DRIVER_PCH:
2421 bdl_pos_adj[dev] = 1; 2425 bdl_pos_adj[dev] = 1;
2422 break; 2426 break;
2423 default: 2427 default:
@@ -2696,6 +2700,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2696 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, 2700 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2697 /* PCH */ 2701 /* PCH */
2698 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, 2702 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2703 /* CPT */
2704 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2699 /* SCH */ 2705 /* SCH */
2700 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2706 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2701 /* ATI SB 450/600 */ 2707 /* ATI SB 450/600 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 214301d568fa..e6d1bdff1b6e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1098,7 +1098,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 685015a53292..194a28c54992 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -42,10 +42,12 @@
42 42
43/* Conexant 5051 specific */ 43/* Conexant 5051 specific */
44 44
45#define CXT5051_SPDIF_OUT 0x1C 45#define CXT5051_SPDIF_OUT 0x12
46#define CXT5051_PORTB_EVENT 0x38 46#define CXT5051_PORTB_EVENT 0x38
47#define CXT5051_PORTC_EVENT 0x39 47#define CXT5051_PORTC_EVENT 0x39
48 48
49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2)
49 51
50struct conexant_jack { 52struct conexant_jack {
51 53
@@ -74,7 +76,7 @@ struct conexant_spec {
74 */ 76 */
75 unsigned int cur_eapd; 77 unsigned int cur_eapd;
76 unsigned int hp_present; 78 unsigned int hp_present;
77 unsigned int no_auto_mic; 79 unsigned int auto_mic;
78 unsigned int need_dac_fix; 80 unsigned int need_dac_fix;
79 81
80 /* capture */ 82 /* capture */
@@ -111,7 +113,8 @@ struct conexant_spec {
111 113
112 unsigned int dell_automute; 114 unsigned int dell_automute;
113 unsigned int port_d_mode; 115 unsigned int port_d_mode;
114 unsigned int dell_vostro; 116 unsigned int dell_vostro:1;
117 unsigned int ideapad:1;
115 118
116 unsigned int ext_mic_present; 119 unsigned int ext_mic_present;
117 unsigned int recording; 120 unsigned int recording;
@@ -1603,6 +1606,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1603{ 1606{
1604 struct conexant_spec *spec = codec->spec; 1607 struct conexant_spec *spec = codec->spec;
1605 unsigned int pinctl; 1608 unsigned int pinctl;
1609 /* headphone pin */
1610 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1611 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1612 pinctl);
1613 /* speaker pin */
1606 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1614 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1607 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1615 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1608 pinctl); 1616 pinctl);
@@ -1626,7 +1634,7 @@ static void cxt5051_portb_automic(struct hda_codec *codec)
1626 struct conexant_spec *spec = codec->spec; 1634 struct conexant_spec *spec = codec->spec;
1627 unsigned int present; 1635 unsigned int present;
1628 1636
1629 if (spec->no_auto_mic) 1637 if (!(spec->auto_mic & AUTO_MIC_PORTB))
1630 return; 1638 return;
1631 present = snd_hda_jack_detect(codec, 0x17); 1639 present = snd_hda_jack_detect(codec, 0x17);
1632 snd_hda_codec_write(codec, 0x14, 0, 1640 snd_hda_codec_write(codec, 0x14, 0,
@@ -1641,7 +1649,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1641 unsigned int present; 1649 unsigned int present;
1642 hda_nid_t new_adc; 1650 hda_nid_t new_adc;
1643 1651
1644 if (spec->no_auto_mic) 1652 if (!(spec->auto_mic & AUTO_MIC_PORTC))
1645 return; 1653 return;
1646 present = snd_hda_jack_detect(codec, 0x18); 1654 present = snd_hda_jack_detect(codec, 0x18);
1647 if (present) 1655 if (present)
@@ -1687,13 +1695,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1687 conexant_report_jack(codec, nid); 1695 conexant_report_jack(codec, nid);
1688} 1696}
1689 1697
1690static struct snd_kcontrol_new cxt5051_mixers[] = { 1698static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1691 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1692 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1693 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1694 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1695 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1696 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1697 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1699 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1698 { 1700 {
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1703,7 +1705,16 @@ static struct snd_kcontrol_new cxt5051_mixers[] = {
1703 .put = cxt5051_hp_master_sw_put, 1705 .put = cxt5051_hp_master_sw_put,
1704 .private_value = 0x1a, 1706 .private_value = 0x1a,
1705 }, 1707 },
1708 {}
1709};
1706 1710
1711static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1712 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1715 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1716 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1717 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1707 {} 1718 {}
1708}; 1719};
1709 1720
@@ -1712,48 +1723,26 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1712 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1723 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1724 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1714 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1725 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1715 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1716 {
1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1718 .name = "Master Playback Switch",
1719 .info = cxt_eapd_info,
1720 .get = cxt_eapd_get,
1721 .put = cxt5051_hp_master_sw_put,
1722 .private_value = 0x1a,
1723 },
1724
1725 {} 1726 {}
1726}; 1727};
1727 1728
1728static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1729static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1729 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), 1730 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1730 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), 1731 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1731 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1732 {
1733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1734 .name = "Master Playback Switch",
1735 .info = cxt_eapd_info,
1736 .get = cxt_eapd_get,
1737 .put = cxt5051_hp_master_sw_put,
1738 .private_value = 0x1a,
1739 },
1740
1741 {} 1732 {}
1742}; 1733};
1743 1734
1744static struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1735static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1745 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1736 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1746 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), 1737 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1747 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1738 {}
1748 { 1739};
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "Master Playback Switch",
1751 .info = cxt_eapd_info,
1752 .get = cxt_eapd_get,
1753 .put = cxt5051_hp_master_sw_put,
1754 .private_value = 0x1a,
1755 },
1756 1740
1741static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1742 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1743 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1745 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1757 {} 1746 {}
1758}; 1747};
1759 1748
@@ -1782,8 +1771,6 @@ static struct hda_verb cxt5051_init_verbs[] = {
1782 /* EAPD */ 1771 /* EAPD */
1783 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1772 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1784 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1773 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1785 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1786 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1787 { } /* end */ 1774 { } /* end */
1788}; 1775};
1789 1776
@@ -1809,7 +1796,6 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1809 /* EAPD */ 1796 /* EAPD */
1810 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1797 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1811 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1798 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1812 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1813 { } /* end */ 1799 { } /* end */
1814}; 1800};
1815 1801
@@ -1841,15 +1827,13 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1841 /* EAPD */ 1827 /* EAPD */
1842 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1828 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1843 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1829 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1844 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1845 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1846 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1830 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1847 { } /* end */ 1831 { } /* end */
1848}; 1832};
1849 1833
1850static struct hda_verb cxt5051_f700_init_verbs[] = { 1834static struct hda_verb cxt5051_f700_init_verbs[] = {
1851 /* Line in, Mic */ 1835 /* Line in, Mic */
1852 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x03}, 1836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1853 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1837 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1839 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
@@ -1869,15 +1853,34 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
1869 /* EAPD */ 1853 /* EAPD */
1870 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1854 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1871 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1855 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1872 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1873 { } /* end */ 1856 { } /* end */
1874}; 1857};
1875 1858
1859static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1860 unsigned int event)
1861{
1862 snd_hda_codec_write(codec, nid, 0,
1863 AC_VERB_SET_UNSOLICITED_ENABLE,
1864 AC_USRSP_EN | event);
1865#ifdef CONFIG_SND_HDA_INPUT_JACK
1866 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
1867 conexant_report_jack(codec, nid);
1868#endif
1869}
1870
1876/* initialize jack-sensing, too */ 1871/* initialize jack-sensing, too */
1877static int cxt5051_init(struct hda_codec *codec) 1872static int cxt5051_init(struct hda_codec *codec)
1878{ 1873{
1874 struct conexant_spec *spec = codec->spec;
1875
1879 conexant_init(codec); 1876 conexant_init(codec);
1880 conexant_init_jacks(codec); 1877 conexant_init_jacks(codec);
1878
1879 if (spec->auto_mic & AUTO_MIC_PORTB)
1880 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1881 if (spec->auto_mic & AUTO_MIC_PORTC)
1882 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1883
1881 if (codec->patch_ops.unsol_event) { 1884 if (codec->patch_ops.unsol_event) {
1882 cxt5051_hp_automute(codec); 1885 cxt5051_hp_automute(codec);
1883 cxt5051_portb_automic(codec); 1886 cxt5051_portb_automic(codec);
@@ -1893,6 +1896,7 @@ enum {
1893 CXT5051_HP_DV6736, /* HP without mic switch */ 1896 CXT5051_HP_DV6736, /* HP without mic switch */
1894 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1897 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1895 CXT5051_F700, /* HP Compaq Presario F700 */ 1898 CXT5051_F700, /* HP Compaq Presario F700 */
1899 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1896 CXT5051_MODELS 1900 CXT5051_MODELS
1897}; 1901};
1898 1902
@@ -1901,17 +1905,19 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1901 [CXT5051_HP] = "hp", 1905 [CXT5051_HP] = "hp",
1902 [CXT5051_HP_DV6736] = "hp-dv6736", 1906 [CXT5051_HP_DV6736] = "hp-dv6736",
1903 [CXT5051_LENOVO_X200] = "lenovo-x200", 1907 [CXT5051_LENOVO_X200] = "lenovo-x200",
1904 [CXT5051_F700] = "hp 700" 1908 [CXT5051_F700] = "hp-700",
1909 [CXT5051_TOSHIBA] = "toshiba",
1905}; 1910};
1906 1911
1907static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1912static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1908 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1913 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1909 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1914 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1915 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1916 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1910 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1917 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1911 CXT5051_LAPTOP), 1918 CXT5051_LAPTOP),
1912 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1919 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1913 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), 1920 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1914 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1915 {} 1921 {}
1916}; 1922};
1917 1923
@@ -1935,8 +1941,9 @@ static int patch_cxt5051(struct hda_codec *codec)
1935 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 1941 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1936 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 1942 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1937 spec->adc_nids = cxt5051_adc_nids; 1943 spec->adc_nids = cxt5051_adc_nids;
1938 spec->num_mixers = 1; 1944 spec->num_mixers = 2;
1939 spec->mixers[0] = cxt5051_mixers; 1945 spec->mixers[0] = cxt5051_capture_mixers;
1946 spec->mixers[1] = cxt5051_playback_mixers;
1940 spec->num_init_verbs = 1; 1947 spec->num_init_verbs = 1;
1941 spec->init_verbs[0] = cxt5051_init_verbs; 1948 spec->init_verbs[0] = cxt5051_init_verbs;
1942 spec->spdif_route = 0; 1949 spec->spdif_route = 0;
@@ -1950,6 +1957,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1950 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1957 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1951 cxt5051_models, 1958 cxt5051_models,
1952 cxt5051_cfg_tbl); 1959 cxt5051_cfg_tbl);
1960 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1953 switch (board_config) { 1961 switch (board_config) {
1954 case CXT5051_HP: 1962 case CXT5051_HP:
1955 spec->mixers[0] = cxt5051_hp_mixers; 1963 spec->mixers[0] = cxt5051_hp_mixers;
@@ -1957,7 +1965,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1957 case CXT5051_HP_DV6736: 1965 case CXT5051_HP_DV6736:
1958 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 1966 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1959 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 1967 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1960 spec->no_auto_mic = 1; 1968 spec->auto_mic = 0;
1961 break; 1969 break;
1962 case CXT5051_LENOVO_X200: 1970 case CXT5051_LENOVO_X200:
1963 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1971 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
@@ -1965,7 +1973,11 @@ static int patch_cxt5051(struct hda_codec *codec)
1965 case CXT5051_F700: 1973 case CXT5051_F700:
1966 spec->init_verbs[0] = cxt5051_f700_init_verbs; 1974 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1967 spec->mixers[0] = cxt5051_f700_mixers; 1975 spec->mixers[0] = cxt5051_f700_mixers;
1968 spec->no_auto_mic = 1; 1976 spec->auto_mic = 0;
1977 break;
1978 case CXT5051_TOSHIBA:
1979 spec->mixers[0] = cxt5051_toshiba_mixers;
1980 spec->auto_mic = AUTO_MIC_PORTB;
1969 break; 1981 break;
1970 } 1982 }
1971 1983
@@ -2156,6 +2168,34 @@ static void cxt5066_vostro_automic(struct hda_codec *codec)
2156 } 2168 }
2157} 2169}
2158 2170
2171/* toggle input of built-in digital mic and mic jack appropriately */
2172static void cxt5066_ideapad_automic(struct hda_codec *codec)
2173{
2174 unsigned int present;
2175
2176 struct hda_verb ext_mic_present[] = {
2177 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2179 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2180 {}
2181 };
2182 static struct hda_verb ext_mic_absent[] = {
2183 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2184 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2185 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2186 {}
2187 };
2188
2189 present = snd_hda_jack_detect(codec, 0x1b);
2190 if (present) {
2191 snd_printdd("CXT5066: external microphone detected\n");
2192 snd_hda_sequence_write(codec, ext_mic_present);
2193 } else {
2194 snd_printdd("CXT5066: external microphone absent\n");
2195 snd_hda_sequence_write(codec, ext_mic_absent);
2196 }
2197}
2198
2159/* mute internal speaker if HP is plugged */ 2199/* mute internal speaker if HP is plugged */
2160static void cxt5066_hp_automute(struct hda_codec *codec) 2200static void cxt5066_hp_automute(struct hda_codec *codec)
2161{ 2201{
@@ -2205,6 +2245,20 @@ static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2205 } 2245 }
2206} 2246}
2207 2247
2248/* unsolicited event for jack sensing */
2249static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2250{
2251 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2252 switch (res >> 26) {
2253 case CONEXANT_HP_EVENT:
2254 cxt5066_hp_automute(codec);
2255 break;
2256 case CONEXANT_MIC_EVENT:
2257 cxt5066_ideapad_automic(codec);
2258 break;
2259 }
2260}
2261
2208static const struct hda_input_mux cxt5066_analog_mic_boost = { 2262static const struct hda_input_mux cxt5066_analog_mic_boost = {
2209 .num_items = 5, 2263 .num_items = 5,
2210 .items = { 2264 .items = {
@@ -2216,13 +2270,21 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2216 }, 2270 },
2217}; 2271};
2218 2272
2219static int cxt5066_set_mic_boost(struct hda_codec *codec) 2273static void cxt5066_set_mic_boost(struct hda_codec *codec)
2220{ 2274{
2221 struct conexant_spec *spec = codec->spec; 2275 struct conexant_spec *spec = codec->spec;
2222 return snd_hda_codec_write_cache(codec, 0x17, 0, 2276 snd_hda_codec_write_cache(codec, 0x17, 0,
2223 AC_VERB_SET_AMP_GAIN_MUTE, 2277 AC_VERB_SET_AMP_GAIN_MUTE,
2224 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2278 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2225 cxt5066_analog_mic_boost.items[spec->mic_boost].index); 2279 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2280 if (spec->ideapad) {
2281 /* adjust the internal mic as well...it is not through 0x17 */
2282 snd_hda_codec_write_cache(codec, 0x23, 0,
2283 AC_VERB_SET_AMP_GAIN_MUTE,
2284 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2285 cxt5066_analog_mic_boost.
2286 items[spec->mic_boost].index);
2287 }
2226} 2288}
2227 2289
2228static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2290static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
@@ -2653,6 +2715,56 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2653 { } /* end */ 2715 { } /* end */
2654}; 2716};
2655 2717
2718static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2721 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2722 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2723
2724 /* Speakers */
2725 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2727
2728 /* HP, Amp */
2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2730 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2731
2732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2733 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2734
2735 /* DAC1 */
2736 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737
2738 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2744 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2745
2746 /* Audio input selector */
2747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2748 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2749
2750 /* SPDIF route: PCM */
2751 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2752 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2753
2754 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2755 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756
2757 /* internal microphone */
2758 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2759
2760 /* EAPD */
2761 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2762
2763 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2765 { } /* end */
2766};
2767
2656static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2768static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2657 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2658 { } /* end */ 2770 { } /* end */
@@ -2669,6 +2781,8 @@ static int cxt5066_init(struct hda_codec *codec)
2669 cxt5066_hp_automute(codec); 2781 cxt5066_hp_automute(codec);
2670 if (spec->dell_vostro) 2782 if (spec->dell_vostro)
2671 cxt5066_vostro_automic(codec); 2783 cxt5066_vostro_automic(codec);
2784 else if (spec->ideapad)
2785 cxt5066_ideapad_automic(codec);
2672 } 2786 }
2673 cxt5066_set_mic_boost(codec); 2787 cxt5066_set_mic_boost(codec);
2674 return 0; 2788 return 0;
@@ -2694,6 +2808,7 @@ enum {
2694 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2808 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2695 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2809 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2696 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2810 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2811 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2697 CXT5066_MODELS 2812 CXT5066_MODELS
2698}; 2813};
2699 2814
@@ -2701,7 +2816,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2701 [CXT5066_LAPTOP] = "laptop", 2816 [CXT5066_LAPTOP] = "laptop",
2702 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2817 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2703 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2818 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2704 [CXT5066_DELL_VOSTO] = "dell-vostro" 2819 [CXT5066_DELL_VOSTO] = "dell-vostro",
2820 [CXT5066_IDEAPAD] = "ideapad",
2705}; 2821};
2706 2822
2707static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2823static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2711,6 +2827,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2711 CXT5066_DELL_LAPTOP), 2827 CXT5066_DELL_LAPTOP),
2712 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2713 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 2829 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2830 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2714 {} 2831 {}
2715}; 2832};
2716 2833
@@ -2802,6 +2919,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2802 /* input source automatically selected */ 2919 /* input source automatically selected */
2803 spec->input_mux = NULL; 2920 spec->input_mux = NULL;
2804 break; 2921 break;
2922 case CXT5066_IDEAPAD:
2923 codec->patch_ops.init = cxt5066_init;
2924 codec->patch_ops.unsol_event = cxt5066_ideapad_event;
2925 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2926 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2927 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
2928 spec->port_d_mode = 0;
2929 spec->ideapad = 1;
2930 spec->mic_boost = 2; /* default 20dB gain */
2931
2932 /* no S/PDIF out */
2933 spec->multiout.dig_out_nid = 0;
2934
2935 /* input source automatically selected */
2936 spec->input_mux = NULL;
2937 break;
2805 } 2938 }
2806 2939
2807 return 0; 2940 return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f628c33d80b3..e8cbe216e912 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -131,8 +131,10 @@ enum {
131enum { 131enum {
132 ALC269_BASIC, 132 ALC269_BASIC,
133 ALC269_QUANTA_FL1, 133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_AMIC, 134 ALC269_AMIC,
135 ALC269_ASUS_DMIC, 135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
136 ALC269_FUJITSU, 138 ALC269_FUJITSU,
137 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
138 ALC269_AUTO, 140 ALC269_AUTO,
@@ -207,8 +209,10 @@ enum {
207 ALC882_ASUS_A7J, 209 ALC882_ASUS_A7J,
208 ALC882_ASUS_A7M, 210 ALC882_ASUS_A7M,
209 ALC885_MACPRO, 211 ALC885_MACPRO,
212 ALC885_MBA21,
210 ALC885_MBP3, 213 ALC885_MBP3,
211 ALC885_MB5, 214 ALC885_MB5,
215 ALC885_MACMINI3,
212 ALC885_IMAC24, 216 ALC885_IMAC24,
213 ALC885_IMAC91, 217 ALC885_IMAC91,
214 ALC883_3ST_2ch_DIG, 218 ALC883_3ST_2ch_DIG,
@@ -841,27 +845,6 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
841 spec->init_verbs[spec->num_init_verbs++] = verb; 845 spec->init_verbs[spec->num_init_verbs++] = verb;
842} 846}
843 847
844#ifdef CONFIG_PROC_FS
845/*
846 * hook for proc
847 */
848static void print_realtek_coef(struct snd_info_buffer *buffer,
849 struct hda_codec *codec, hda_nid_t nid)
850{
851 int coeff;
852
853 if (nid != 0x20)
854 return;
855 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
856 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
857 coeff = snd_hda_codec_read(codec, nid, 0,
858 AC_VERB_GET_COEF_INDEX, 0);
859 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
860}
861#else
862#define print_realtek_coef NULL
863#endif
864
865/* 848/*
866 * set up from the preset table 849 * set up from the preset table
867 */ 850 */
@@ -1166,6 +1149,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1166 case 0x10ec0888: 1149 case 0x10ec0888:
1167 alc888_coef_init(codec); 1150 alc888_coef_init(codec);
1168 break; 1151 break;
1152#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1169 case 0x10ec0267: 1153 case 0x10ec0267:
1170 case 0x10ec0268: 1154 case 0x10ec0268:
1171 snd_hda_codec_write(codec, 0x20, 0, 1155 snd_hda_codec_write(codec, 0x20, 0,
@@ -1178,6 +1162,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1178 AC_VERB_SET_PROC_COEF, 1162 AC_VERB_SET_PROC_COEF,
1179 tmp | 0x3000); 1163 tmp | 0x3000);
1180 break; 1164 break;
1165#endif /* XXX */
1181 } 1166 }
1182 break; 1167 break;
1183 } 1168 }
@@ -1269,7 +1254,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1269 */ 1254 */
1270static int alc_subsystem_id(struct hda_codec *codec, 1255static int alc_subsystem_id(struct hda_codec *codec,
1271 hda_nid_t porta, hda_nid_t porte, 1256 hda_nid_t porta, hda_nid_t porte,
1272 hda_nid_t portd) 1257 hda_nid_t portd, hda_nid_t porti)
1273{ 1258{
1274 unsigned int ass, tmp, i; 1259 unsigned int ass, tmp, i;
1275 unsigned nid; 1260 unsigned nid;
@@ -1295,7 +1280,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
1295 snd_printd("realtek: No valid SSID, " 1280 snd_printd("realtek: No valid SSID, "
1296 "checking pincfg 0x%08x for NID 0x%x\n", 1281 "checking pincfg 0x%08x for NID 0x%x\n",
1297 ass, nid); 1282 ass, nid);
1298 if (!(ass & 1) && !(ass & 0x100000)) 1283 if (!(ass & 1))
1299 return 0; 1284 return 0;
1300 if ((ass >> 30) != 1) /* no physical connection */ 1285 if ((ass >> 30) != 1) /* no physical connection */
1301 return 0; 1286 return 0;
@@ -1355,6 +1340,8 @@ do_sku:
1355 nid = porte; 1340 nid = porte;
1356 else if (tmp == 2) 1341 else if (tmp == 2)
1357 nid = portd; 1342 nid = portd;
1343 else if (tmp == 3)
1344 nid = porti;
1358 else 1345 else
1359 return 1; 1346 return 1;
1360 for (i = 0; i < spec->autocfg.line_outs; i++) 1347 for (i = 0; i < spec->autocfg.line_outs; i++)
@@ -1369,9 +1356,10 @@ do_sku:
1369} 1356}
1370 1357
1371static void alc_ssid_check(struct hda_codec *codec, 1358static void alc_ssid_check(struct hda_codec *codec,
1372 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) 1359 hda_nid_t porta, hda_nid_t porte,
1360 hda_nid_t portd, hda_nid_t porti)
1373{ 1361{
1374 if (!alc_subsystem_id(codec, porta, porte, portd)) { 1362 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1375 struct alc_spec *spec = codec->spec; 1363 struct alc_spec *spec = codec->spec;
1376 snd_printd("realtek: " 1364 snd_printd("realtek: "
1377 "Enable default setup for auto mode as fallback\n"); 1365 "Enable default setup for auto mode as fallback\n");
@@ -3729,25 +3717,22 @@ static void alc_power_eapd(struct hda_codec *codec)
3729 /* We currently only handle front, HP */ 3717 /* We currently only handle front, HP */
3730 switch (codec->vendor_id) { 3718 switch (codec->vendor_id) {
3731 case 0x10ec0260: 3719 case 0x10ec0260:
3732 snd_hda_codec_write(codec, 0x0f, 0, 3720 set_eapd(codec, 0x0f, 0);
3733 AC_VERB_SET_EAPD_BTLENABLE, 0x00); 3721 set_eapd(codec, 0x10, 0);
3734 snd_hda_codec_write(codec, 0x10, 0,
3735 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3736 break; 3722 break;
3737 case 0x10ec0262: 3723 case 0x10ec0262:
3738 case 0x10ec0267: 3724 case 0x10ec0267:
3739 case 0x10ec0268: 3725 case 0x10ec0268:
3740 case 0x10ec0269: 3726 case 0x10ec0269:
3727 case 0x10ec0270:
3741 case 0x10ec0272: 3728 case 0x10ec0272:
3742 case 0x10ec0660: 3729 case 0x10ec0660:
3743 case 0x10ec0662: 3730 case 0x10ec0662:
3744 case 0x10ec0663: 3731 case 0x10ec0663:
3745 case 0x10ec0862: 3732 case 0x10ec0862:
3746 case 0x10ec0889: 3733 case 0x10ec0889:
3747 snd_hda_codec_write(codec, 0x14, 0, 3734 set_eapd(codec, 0x14, 0);
3748 AC_VERB_SET_EAPD_BTLENABLE, 0x00); 3735 set_eapd(codec, 0x15, 0);
3749 snd_hda_codec_write(codec, 0x15, 0,
3750 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3751 break; 3736 break;
3752 } 3737 }
3753} 3738}
@@ -4877,7 +4862,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4877 spec->num_mux_defs = 1; 4862 spec->num_mux_defs = 1;
4878 spec->input_mux = &spec->private_imux[0]; 4863 spec->input_mux = &spec->private_imux[0];
4879 4864
4880 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 4865 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4881 4866
4882 return 1; 4867 return 1;
4883} 4868}
@@ -5081,7 +5066,6 @@ static int patch_alc880(struct hda_codec *codec)
5081 if (!spec->loopback.amplist) 5066 if (!spec->loopback.amplist)
5082 spec->loopback.amplist = alc880_loopbacks; 5067 spec->loopback.amplist = alc880_loopbacks;
5083#endif 5068#endif
5084 codec->proc_widget_hook = print_realtek_coef;
5085 5069
5086 return 0; 5070 return 0;
5087} 5071}
@@ -6412,7 +6396,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6412 spec->num_mux_defs = 1; 6396 spec->num_mux_defs = 1;
6413 spec->input_mux = &spec->private_imux[0]; 6397 spec->input_mux = &spec->private_imux[0];
6414 6398
6415 alc_ssid_check(codec, 0x10, 0x15, 0x0f); 6399 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6416 6400
6417 return 1; 6401 return 1;
6418} 6402}
@@ -6691,7 +6675,6 @@ static int patch_alc260(struct hda_codec *codec)
6691 if (!spec->loopback.amplist) 6675 if (!spec->loopback.amplist)
6692 spec->loopback.amplist = alc260_loopbacks; 6676 spec->loopback.amplist = alc260_loopbacks;
6693#endif 6677#endif
6694 codec->proc_widget_hook = print_realtek_coef;
6695 6678
6696 return 0; 6679 return 0;
6697} 6680}
@@ -6773,6 +6756,14 @@ static struct hda_input_mux mb5_capture_source = {
6773 }, 6756 },
6774}; 6757};
6775 6758
6759static struct hda_input_mux macmini3_capture_source = {
6760 .num_items = 2,
6761 .items = {
6762 { "Line", 0x2 },
6763 { "CD", 0x4 },
6764 },
6765};
6766
6776static struct hda_input_mux alc883_3stack_6ch_intel = { 6767static struct hda_input_mux alc883_3stack_6ch_intel = {
6777 .num_items = 4, 6768 .num_items = 4,
6778 .items = { 6769 .items = {
@@ -6961,6 +6952,13 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
6961 { 8, alc882_sixstack_ch8_init }, 6952 { 8, alc882_sixstack_ch8_init },
6962}; 6953};
6963 6954
6955
6956/* Macbook Air 2,1 */
6957
6958static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
6959 { 2, NULL },
6960};
6961
6964/* 6962/*
6965 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 6963 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6966 */ 6964 */
@@ -7021,6 +7019,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7021 { 6, alc885_mb5_ch6_init }, 7019 { 6, alc885_mb5_ch6_init },
7022}; 7020};
7023 7021
7022#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7024 7023
7025/* 7024/*
7026 * 2ch mode 7025 * 2ch mode
@@ -7232,6 +7231,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7232 { } /* end */ 7231 { } /* end */
7233}; 7232};
7234 7233
7234/* Macbook Air 2,1 same control for HP and internal Speaker */
7235
7236static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7239 { }
7240};
7241
7242
7235static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7243static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7236 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7237 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7245 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7265,6 +7273,21 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7265 { } /* end */ 7273 { } /* end */
7266}; 7274};
7267 7275
7276static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7288 { } /* end */
7289};
7290
7268static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7291static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7269 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7270 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), 7293 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7356,29 +7379,18 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7356 7379
7357static struct hda_verb alc882_base_init_verbs[] = { 7380static struct hda_verb alc882_base_init_verbs[] = {
7358 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7381 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7362 /* Rear mixer */ 7384 /* Rear mixer */
7363 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7366 /* CLFE mixer */ 7387 /* CLFE mixer */
7367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7370 /* Side mixer */ 7390 /* Side mixer */
7371 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7374 7393
7375 /* mute analog input loopbacks */
7376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7381
7382 /* Front Pin: output 0 (0x0c) */ 7394 /* Front Pin: output 0 (0x0c) */
7383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -7415,14 +7427,8 @@ static struct hda_verb alc882_base_init_verbs[] = {
7415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7427 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7416 /* Input mixer2 */ 7428 /* Input mixer2 */
7417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7421 /* Input mixer3 */ 7430 /* Input mixer3 */
7422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7426 /* ADC2: mute amp left and right */ 7432 /* ADC2: mute amp left and right */
7427 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7433 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7466,26 +7472,17 @@ static struct hda_verb alc_hp15_unsol_verbs[] = {
7466 7472
7467static struct hda_verb alc885_init_verbs[] = { 7473static struct hda_verb alc885_init_verbs[] = {
7468 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7474 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7472 /* Rear mixer */ 7477 /* Rear mixer */
7473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7476 /* CLFE mixer */ 7480 /* CLFE mixer */
7477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7479 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7480 /* Side mixer */ 7483 /* Side mixer */
7481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7482 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7484
7485 /* mute analog input loopbacks */
7486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7489 7486
7490 /* Front HP Pin: output 0 (0x0c) */ 7487 /* Front HP Pin: output 0 (0x0c) */
7491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -7519,17 +7516,11 @@ static struct hda_verb alc885_init_verbs[] = {
7519 7516
7520 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7517 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7521 /* Input mixer1 */ 7518 /* Input mixer1 */
7522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7525 /* Input mixer2 */ 7520 /* Input mixer2 */
7526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7529 /* Input mixer3 */ 7522 /* Input mixer3 */
7530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7533 /* ADC2: mute amp left and right */ 7524 /* ADC2: mute amp left and right */
7534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7535 /* ADC3: mute amp left and right */ 7526 /* ADC3: mute amp left and right */
@@ -7671,6 +7662,76 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7671 { } 7662 { }
7672}; 7663};
7673 7664
7665/* Macmini 3,1 */
7666static struct hda_verb alc885_macmini3_init_verbs[] = {
7667 /* DACs */
7668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7672 /* Front mixer */
7673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7676 /* Surround mixer */
7677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7680 /* LFE mixer */
7681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 /* HP mixer */
7685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7688 /* Front Pin (0x0c) */
7689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 /* LFE Pin (0x0e) */
7693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7696 /* HP Pin (0x0f) */
7697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 /* Line In pin */
7702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7704
7705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7709 { }
7710};
7711
7712
7713static struct hda_verb alc885_mba21_init_verbs[] = {
7714 /*Internal and HP Speaker Mixer*/
7715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718 /*Internal Speaker Pin (0x0c)*/
7719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7722 /* HP Pin: output 0 (0x0e) */
7723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7727 /* Line in (is hp when jack connected)*/
7728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7730
7731 { }
7732 };
7733
7734
7674/* Macbook Pro rev3 */ 7735/* Macbook Pro rev3 */
7675static struct hda_verb alc885_mbp3_init_verbs[] = { 7736static struct hda_verb alc885_mbp3_init_verbs[] = {
7676 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -7833,54 +7894,35 @@ static void alc885_imac24_setup(struct hda_codec *codec)
7833 spec->autocfg.speaker_pins[1] = 0x1a; 7894 spec->autocfg.speaker_pins[1] = 0x1a;
7834} 7895}
7835 7896
7836static void alc885_mbp3_setup(struct hda_codec *codec) 7897#define alc885_mb5_setup alc885_imac24_setup
7837{ 7898#define alc885_macmini3_setup alc885_imac24_setup
7838 struct alc_spec *spec = codec->spec;
7839
7840 spec->autocfg.hp_pins[0] = 0x15;
7841 spec->autocfg.speaker_pins[0] = 0x14;
7842}
7843 7899
7844static void alc885_mb5_automute(struct hda_codec *codec) 7900/* Macbook Air 2,1 */
7901static void alc885_mba21_setup(struct hda_codec *codec)
7845{ 7902{
7846 unsigned int present; 7903 struct alc_spec *spec = codec->spec;
7847
7848 present = snd_hda_codec_read(codec, 0x14, 0,
7849 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7850 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7851 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7852 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7853 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7854 7904
7905 spec->autocfg.hp_pins[0] = 0x14;
7906 spec->autocfg.speaker_pins[0] = 0x18;
7855} 7907}
7856 7908
7857static void alc885_mb5_unsol_event(struct hda_codec *codec,
7858 unsigned int res)
7859{
7860 /* Headphone insertion or removal. */
7861 if ((res >> 26) == ALC880_HP_EVENT)
7862 alc885_mb5_automute(codec);
7863}
7864 7909
7865static void alc885_imac91_automute(struct hda_codec *codec)
7866{
7867 unsigned int present;
7868 7910
7869 present = snd_hda_codec_read(codec, 0x14, 0, 7911static void alc885_mbp3_setup(struct hda_codec *codec)
7870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7912{
7871 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7913 struct alc_spec *spec = codec->spec;
7872 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7873 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7875 7914
7915 spec->autocfg.hp_pins[0] = 0x15;
7916 spec->autocfg.speaker_pins[0] = 0x14;
7876} 7917}
7877 7918
7878static void alc885_imac91_unsol_event(struct hda_codec *codec, 7919static void alc885_imac91_setup(struct hda_codec *codec)
7879 unsigned int res)
7880{ 7920{
7881 /* Headphone insertion or removal. */ 7921 struct alc_spec *spec = codec->spec;
7882 if ((res >> 26) == ALC880_HP_EVENT) 7922
7883 alc885_imac91_automute(codec); 7923 spec->autocfg.hp_pins[0] = 0x14;
7924 spec->autocfg.speaker_pins[0] = 0x15;
7925 spec->autocfg.speaker_pins[1] = 0x1a;
7884} 7926}
7885 7927
7886static struct hda_verb alc882_targa_verbs[] = { 7928static struct hda_verb alc882_targa_verbs[] = {
@@ -8015,18 +8057,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8015 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8017 8059
8018 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8019 * mixer widget
8020 * Note: PASD motherboards uses the Line In 2 as the input for
8021 * front panel mic (mic 2)
8022 */
8023 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8029
8030 /* 8060 /*
8031 * Set up output mixers (0x0c - 0x0f) 8061 * Set up output mixers (0x0c - 0x0f)
8032 */ 8062 */
@@ -8051,16 +8081,9 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8051 /* FIXME: use matrix-type input source selection */ 8081 /* FIXME: use matrix-type input source selection */
8052 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8053 /* Input mixer2 */ 8083 /* Input mixer2 */
8054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8058 /* Input mixer3 */ 8085 /* Input mixer3 */
8059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8063
8064 { } 8087 { }
8065}; 8088};
8066 8089
@@ -9047,6 +9070,8 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9047 [ALC882_ASUS_A7M] = "asus-a7m", 9070 [ALC882_ASUS_A7M] = "asus-a7m",
9048 [ALC885_MACPRO] = "macpro", 9071 [ALC885_MACPRO] = "macpro",
9049 [ALC885_MB5] = "mb5", 9072 [ALC885_MB5] = "mb5",
9073 [ALC885_MACMINI3] = "macmini3",
9074 [ALC885_MBA21] = "mba21",
9050 [ALC885_MBP3] = "mbp3", 9075 [ALC885_MBP3] = "mbp3",
9051 [ALC885_IMAC24] = "imac24", 9076 [ALC885_IMAC24] = "imac24",
9052 [ALC885_IMAC91] = "imac91", 9077 [ALC885_IMAC91] = "imac91",
@@ -9230,6 +9255,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9230 */ 9255 */
9231 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9256 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9232 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9257 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9258 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9233 {} /* terminator */ 9259 {} /* terminator */
9234}; 9260};
9235 9261
@@ -9281,6 +9307,18 @@ static struct alc_config_preset alc882_presets[] = {
9281 .input_mux = &alc882_capture_source, 9307 .input_mux = &alc882_capture_source,
9282 .dig_out_nid = ALC882_DIGOUT_NID, 9308 .dig_out_nid = ALC882_DIGOUT_NID,
9283 }, 9309 },
9310 [ALC885_MBA21] = {
9311 .mixers = { alc885_mba21_mixer },
9312 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9313 .num_dacs = 2,
9314 .dac_nids = alc882_dac_nids,
9315 .channel_mode = alc885_mba21_ch_modes,
9316 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9317 .input_mux = &alc882_capture_source,
9318 .unsol_event = alc_automute_amp_unsol_event,
9319 .setup = alc885_mba21_setup,
9320 .init_hook = alc_automute_amp,
9321 },
9284 [ALC885_MBP3] = { 9322 [ALC885_MBP3] = {
9285 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9323 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9286 .init_verbs = { alc885_mbp3_init_verbs, 9324 .init_verbs = { alc885_mbp3_init_verbs,
@@ -9308,8 +9346,24 @@ static struct alc_config_preset alc882_presets[] = {
9308 .input_mux = &mb5_capture_source, 9346 .input_mux = &mb5_capture_source,
9309 .dig_out_nid = ALC882_DIGOUT_NID, 9347 .dig_out_nid = ALC882_DIGOUT_NID,
9310 .dig_in_nid = ALC882_DIGIN_NID, 9348 .dig_in_nid = ALC882_DIGIN_NID,
9311 .unsol_event = alc885_mb5_unsol_event, 9349 .unsol_event = alc_automute_amp_unsol_event,
9312 .init_hook = alc885_mb5_automute, 9350 .setup = alc885_mb5_setup,
9351 .init_hook = alc_automute_amp,
9352 },
9353 [ALC885_MACMINI3] = {
9354 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9355 .init_verbs = { alc885_macmini3_init_verbs,
9356 alc880_gpio1_init_verbs },
9357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9358 .dac_nids = alc882_dac_nids,
9359 .channel_mode = alc885_macmini3_6ch_modes,
9360 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9361 .input_mux = &macmini3_capture_source,
9362 .dig_out_nid = ALC882_DIGOUT_NID,
9363 .dig_in_nid = ALC882_DIGIN_NID,
9364 .unsol_event = alc_automute_amp_unsol_event,
9365 .setup = alc885_macmini3_setup,
9366 .init_hook = alc_automute_amp,
9313 }, 9367 },
9314 [ALC885_MACPRO] = { 9368 [ALC885_MACPRO] = {
9315 .mixers = { alc882_macpro_mixer }, 9369 .mixers = { alc882_macpro_mixer },
@@ -9348,8 +9402,9 @@ static struct alc_config_preset alc882_presets[] = {
9348 .input_mux = &alc882_capture_source, 9402 .input_mux = &alc882_capture_source,
9349 .dig_out_nid = ALC882_DIGOUT_NID, 9403 .dig_out_nid = ALC882_DIGOUT_NID,
9350 .dig_in_nid = ALC882_DIGIN_NID, 9404 .dig_in_nid = ALC882_DIGIN_NID,
9351 .unsol_event = alc885_imac91_unsol_event, 9405 .unsol_event = alc_automute_amp_unsol_event,
9352 .init_hook = alc885_imac91_automute, 9406 .setup = alc885_imac91_setup,
9407 .init_hook = alc_automute_amp,
9353 }, 9408 },
9354 [ALC882_TARGA] = { 9409 [ALC882_TARGA] = {
9355 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9410 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -10172,7 +10227,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10172 spec->num_mux_defs = 1; 10227 spec->num_mux_defs = 1;
10173 spec->input_mux = &spec->private_imux[0]; 10228 spec->input_mux = &spec->private_imux[0];
10174 10229
10175 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 10230 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10176 10231
10177 err = alc_auto_add_mic_boost(codec); 10232 err = alc_auto_add_mic_boost(codec);
10178 if (err < 0) 10233 if (err < 0)
@@ -10310,7 +10365,6 @@ static int patch_alc882(struct hda_codec *codec)
10310 if (!spec->loopback.amplist) 10365 if (!spec->loopback.amplist)
10311 spec->loopback.amplist = alc882_loopbacks; 10366 spec->loopback.amplist = alc882_loopbacks;
10312#endif 10367#endif
10313 codec->proc_widget_hook = print_realtek_coef;
10314 10368
10315 return 0; 10369 return 0;
10316} 10370}
@@ -11731,7 +11785,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11731 if (err < 0) 11785 if (err < 0)
11732 return err; 11786 return err;
11733 11787
11734 alc_ssid_check(codec, 0x15, 0x14, 0x1b); 11788 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11735 11789
11736 return 1; 11790 return 1;
11737} 11791}
@@ -12174,7 +12228,6 @@ static int patch_alc262(struct hda_codec *codec)
12174 if (!spec->loopback.amplist) 12228 if (!spec->loopback.amplist)
12175 spec->loopback.amplist = alc262_loopbacks; 12229 spec->loopback.amplist = alc262_loopbacks;
12176#endif 12230#endif
12177 codec->proc_widget_hook = print_realtek_coef;
12178 12231
12179 return 0; 12232 return 0;
12180} 12233}
@@ -12683,7 +12736,6 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12683 dac = 0x02; 12736 dac = 0x02;
12684 break; 12737 break;
12685 case 0x15: 12738 case 0x15:
12686 case 0x21:
12687 dac = 0x03; 12739 dac = 0x03;
12688 break; 12740 break;
12689 default: 12741 default:
@@ -12904,7 +12956,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12904 if (err < 0) 12956 if (err < 0)
12905 return err; 12957 return err;
12906 12958
12907 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 12959 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12908 12960
12909 return 1; 12961 return 1;
12910} 12962}
@@ -13241,8 +13293,6 @@ static int patch_alc268(struct hda_codec *codec)
13241 if (board_config == ALC268_AUTO) 13293 if (board_config == ALC268_AUTO)
13242 spec->init_hook = alc268_auto_init; 13294 spec->init_hook = alc268_auto_init;
13243 13295
13244 codec->proc_widget_hook = print_realtek_coef;
13245
13246 return 0; 13296 return 0;
13247} 13297}
13248 13298
@@ -13262,6 +13312,15 @@ static hda_nid_t alc269_capsrc_nids[1] = {
13262 0x23, 13312 0x23,
13263}; 13313};
13264 13314
13315static hda_nid_t alc269vb_adc_nids[1] = {
13316 /* ADC1 */
13317 0x09,
13318};
13319
13320static hda_nid_t alc269vb_capsrc_nids[1] = {
13321 0x22,
13322};
13323
13265/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13324/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13266 * not a mux! 13325 * not a mux!
13267 */ 13326 */
@@ -13330,7 +13389,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13330 { } 13389 { }
13331}; 13390};
13332 13391
13333static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 13392static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13334 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13393 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13335 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -13338,16 +13397,47 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13338 { } /* end */ 13397 { } /* end */
13339}; 13398};
13340 13399
13400static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13401 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13405 { } /* end */
13406};
13407
13341/* capture mixer elements */ 13408/* capture mixer elements */
13342static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 13409static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13410 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13413 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13414 { } /* end */
13415};
13416
13417static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13343 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13344 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13345 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13346 { } /* end */ 13421 { } /* end */
13347}; 13422};
13348 13423
13424static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13425 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13429 { } /* end */
13430};
13431
13432static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13433 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13436 { } /* end */
13437};
13438
13349/* FSC amilo */ 13439/* FSC amilo */
13350#define alc269_fujitsu_mixer alc269_eeepc_mixer 13440#define alc269_fujitsu_mixer alc269_laptop_mixer
13351 13441
13352static struct hda_verb alc269_quanta_fl1_verbs[] = { 13442static struct hda_verb alc269_quanta_fl1_verbs[] = {
13353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -13490,7 +13580,7 @@ static void alc269_lifebook_init_hook(struct hda_codec *codec)
13490 alc269_lifebook_mic_autoswitch(codec); 13580 alc269_lifebook_mic_autoswitch(codec);
13491} 13581}
13492 13582
13493static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 13583static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13584 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13495 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 13585 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13496 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13586 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13501,7 +13591,7 @@ static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13501 {} 13591 {}
13502}; 13592};
13503 13593
13504static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 13594static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13505 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13506 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 13596 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13507 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13597 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13511,6 +13601,28 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13511 {} 13601 {}
13512}; 13602};
13513 13603
13604static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13605 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13606 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13607 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13609 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13611 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13612 {}
13613};
13614
13615static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13616 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13617 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13618 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13623 {}
13624};
13625
13514/* toggle speaker-output according to the hp-jack state */ 13626/* toggle speaker-output according to the hp-jack state */
13515static void alc269_speaker_automute(struct hda_codec *codec) 13627static void alc269_speaker_automute(struct hda_codec *codec)
13516{ 13628{
@@ -13528,7 +13640,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13528} 13640}
13529 13641
13530/* unsolicited event for HP jack sensing */ 13642/* unsolicited event for HP jack sensing */
13531static void alc269_eeepc_unsol_event(struct hda_codec *codec, 13643static void alc269_laptop_unsol_event(struct hda_codec *codec,
13532 unsigned int res) 13644 unsigned int res)
13533{ 13645{
13534 switch (res >> 26) { 13646 switch (res >> 26) {
@@ -13541,7 +13653,7 @@ static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13541 } 13653 }
13542} 13654}
13543 13655
13544static void alc269_eeepc_dmic_setup(struct hda_codec *codec) 13656static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13545{ 13657{
13546 struct alc_spec *spec = codec->spec; 13658 struct alc_spec *spec = codec->spec;
13547 spec->ext_mic.pin = 0x18; 13659 spec->ext_mic.pin = 0x18;
@@ -13551,7 +13663,17 @@ static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13551 spec->auto_mic = 1; 13663 spec->auto_mic = 1;
13552} 13664}
13553 13665
13554static void alc269_eeepc_amic_setup(struct hda_codec *codec) 13666static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13667{
13668 struct alc_spec *spec = codec->spec;
13669 spec->ext_mic.pin = 0x18;
13670 spec->ext_mic.mux_idx = 0;
13671 spec->int_mic.pin = 0x12;
13672 spec->int_mic.mux_idx = 6;
13673 spec->auto_mic = 1;
13674}
13675
13676static void alc269_laptop_amic_setup(struct hda_codec *codec)
13555{ 13677{
13556 struct alc_spec *spec = codec->spec; 13678 struct alc_spec *spec = codec->spec;
13557 spec->ext_mic.pin = 0x18; 13679 spec->ext_mic.pin = 0x18;
@@ -13561,7 +13683,7 @@ static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13561 spec->auto_mic = 1; 13683 spec->auto_mic = 1;
13562} 13684}
13563 13685
13564static void alc269_eeepc_inithook(struct hda_codec *codec) 13686static void alc269_laptop_inithook(struct hda_codec *codec)
13565{ 13687{
13566 alc269_speaker_automute(codec); 13688 alc269_speaker_automute(codec);
13567 alc_mic_automute(codec); 13689 alc_mic_automute(codec);
@@ -13574,22 +13696,10 @@ static struct hda_verb alc269_init_verbs[] = {
13574 /* 13696 /*
13575 * Unmute ADC0 and set the default input to mic-in 13697 * Unmute ADC0 and set the default input to mic-in
13576 */ 13698 */
13577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13578
13579 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13580 * analog-loopback mixer widget
13581 * Note: PASD motherboards uses the Line In 2 as the input for
13582 * front panel mic (mic 2)
13583 */
13584 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13590 13700
13591 /* 13701 /*
13592 * Set up output mixers (0x0c - 0x0e) 13702 * Set up output mixers (0x02 - 0x03)
13593 */ 13703 */
13594 /* set vol=0 to output mixers */ 13704 /* set vol=0 to output mixers */
13595 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13705 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13614,26 +13724,57 @@ static struct hda_verb alc269_init_verbs[] = {
13614 13724
13615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13725 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13617 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13620 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13621 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13622 13727
13623 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13728 /* FIXME: use Mux-type input source selection */
13624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 13729 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13730 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13731 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13625 13732
13626 /* FIXME: use matrix-type input source selection */ 13733 /* set EAPD */
13734 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13735 { }
13736};
13737
13738static struct hda_verb alc269vb_init_verbs[] = {
13739 /*
13740 * Unmute ADC0 and set the default input to mic-in
13741 */
13742 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13743
13744 /*
13745 * Set up output mixers (0x02 - 0x03)
13746 */
13747 /* set vol=0 to output mixers */
13748 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13750
13751 /* set up input amps for analog loopback */
13752 /* Amp Indices: DAC = 0, mixer = 1 */
13753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13759
13760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13761 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13767
13768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13769 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13770
13771 /* FIXME: use Mux-type input source selection */
13627 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 13772 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13628 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 13773 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13774 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13631 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13632 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13633 13775
13634 /* set EAPD */ 13776 /* set EAPD */
13635 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13777 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13636 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13637 { } 13778 { }
13638}; 13779};
13639 13780
@@ -13681,6 +13822,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13681 struct alc_spec *spec = codec->spec; 13822 struct alc_spec *spec = codec->spec;
13682 int err; 13823 int err;
13683 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 13824 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13825 hda_nid_t real_capsrc_nids;
13684 13826
13685 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13827 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13686 alc269_ignore); 13828 alc269_ignore);
@@ -13702,11 +13844,20 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13702 if (spec->kctls.list) 13844 if (spec->kctls.list)
13703 add_mixer(spec, spec->kctls.list); 13845 add_mixer(spec, spec->kctls.list);
13704 13846
13705 add_verb(spec, alc269_init_verbs); 13847 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13848 add_verb(spec, alc269vb_init_verbs);
13849 real_capsrc_nids = alc269vb_capsrc_nids[0];
13850 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
13851 } else {
13852 add_verb(spec, alc269_init_verbs);
13853 real_capsrc_nids = alc269_capsrc_nids[0];
13854 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13855 }
13856
13706 spec->num_mux_defs = 1; 13857 spec->num_mux_defs = 1;
13707 spec->input_mux = &spec->private_imux[0]; 13858 spec->input_mux = &spec->private_imux[0];
13708 /* set default input source */ 13859 /* set default input source */
13709 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 13860 snd_hda_codec_write_cache(codec, real_capsrc_nids,
13710 0, AC_VERB_SET_CONNECT_SEL, 13861 0, AC_VERB_SET_CONNECT_SEL,
13711 spec->input_mux->items[0].index); 13862 spec->input_mux->items[0].index);
13712 13863
@@ -13717,8 +13868,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13717 if (!spec->cap_mixer && !spec->no_analog) 13868 if (!spec->cap_mixer && !spec->no_analog)
13718 set_capture_mixer(codec); 13869 set_capture_mixer(codec);
13719 13870
13720 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13721
13722 return 1; 13871 return 1;
13723} 13872}
13724 13873
@@ -13744,8 +13893,8 @@ static void alc269_auto_init(struct hda_codec *codec)
13744static const char *alc269_models[ALC269_MODEL_LAST] = { 13893static const char *alc269_models[ALC269_MODEL_LAST] = {
13745 [ALC269_BASIC] = "basic", 13894 [ALC269_BASIC] = "basic",
13746 [ALC269_QUANTA_FL1] = "quanta", 13895 [ALC269_QUANTA_FL1] = "quanta",
13747 [ALC269_ASUS_AMIC] = "asus-amic", 13896 [ALC269_AMIC] = "laptop-amic",
13748 [ALC269_ASUS_DMIC] = "asus-dmic", 13897 [ALC269_DMIC] = "laptop-dmic",
13749 [ALC269_FUJITSU] = "fujitsu", 13898 [ALC269_FUJITSU] = "fujitsu",
13750 [ALC269_LIFEBOOK] = "lifebook", 13899 [ALC269_LIFEBOOK] = "lifebook",
13751 [ALC269_AUTO] = "auto", 13900 [ALC269_AUTO] = "auto",
@@ -13754,43 +13903,57 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
13754static struct snd_pci_quirk alc269_cfg_tbl[] = { 13903static struct snd_pci_quirk alc269_cfg_tbl[] = {
13755 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 13904 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13756 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 13905 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13757 ALC269_ASUS_AMIC), 13906 ALC269_AMIC),
13758 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), 13907 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13759 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), 13908 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13760 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), 13909 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13761 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), 13910 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13762 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), 13911 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13763 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), 13912 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
13764 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), 13913 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
13765 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), 13914 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
13766 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), 13915 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
13767 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), 13916 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
13768 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), 13917 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
13769 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), 13918 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
13770 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), 13919 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
13771 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), 13920 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
13772 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), 13921 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
13773 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), 13922 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
13774 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), 13923 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
13775 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), 13924 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
13776 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), 13925 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
13777 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), 13926 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
13778 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), 13927 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
13779 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), 13928 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
13780 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), 13929 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
13781 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), 13930 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
13782 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), 13931 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
13783 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), 13932 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
13784 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), 13933 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
13785 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), 13934 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
13935 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
13936 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
13937 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
13938 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
13939 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
13940 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
13941 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
13942 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
13786 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 13943 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13787 ALC269_ASUS_DMIC), 13944 ALC269_DMIC),
13788 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 13945 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13789 ALC269_ASUS_DMIC), 13946 ALC269_DMIC),
13790 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), 13947 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13791 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), 13948 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
13792 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 13949 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
13793 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 13950 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13951 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13952 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13953 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
13954 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
13955 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
13956 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
13794 {} 13957 {}
13795}; 13958};
13796 13959
@@ -13818,47 +13981,75 @@ static struct alc_config_preset alc269_presets[] = {
13818 .setup = alc269_quanta_fl1_setup, 13981 .setup = alc269_quanta_fl1_setup,
13819 .init_hook = alc269_quanta_fl1_init_hook, 13982 .init_hook = alc269_quanta_fl1_init_hook,
13820 }, 13983 },
13821 [ALC269_ASUS_AMIC] = { 13984 [ALC269_AMIC] = {
13822 .mixers = { alc269_eeepc_mixer }, 13985 .mixers = { alc269_laptop_mixer },
13823 .cap_mixer = alc269_epc_capture_mixer, 13986 .cap_mixer = alc269_laptop_analog_capture_mixer,
13824 .init_verbs = { alc269_init_verbs, 13987 .init_verbs = { alc269_init_verbs,
13825 alc269_eeepc_amic_init_verbs }, 13988 alc269_laptop_amic_init_verbs },
13826 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13989 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13827 .dac_nids = alc269_dac_nids, 13990 .dac_nids = alc269_dac_nids,
13828 .hp_nid = 0x03, 13991 .hp_nid = 0x03,
13829 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13992 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13830 .channel_mode = alc269_modes, 13993 .channel_mode = alc269_modes,
13831 .unsol_event = alc269_eeepc_unsol_event, 13994 .unsol_event = alc269_laptop_unsol_event,
13832 .setup = alc269_eeepc_amic_setup, 13995 .setup = alc269_laptop_amic_setup,
13833 .init_hook = alc269_eeepc_inithook, 13996 .init_hook = alc269_laptop_inithook,
13834 }, 13997 },
13835 [ALC269_ASUS_DMIC] = { 13998 [ALC269_DMIC] = {
13836 .mixers = { alc269_eeepc_mixer }, 13999 .mixers = { alc269_laptop_mixer },
13837 .cap_mixer = alc269_epc_capture_mixer, 14000 .cap_mixer = alc269_laptop_digital_capture_mixer,
13838 .init_verbs = { alc269_init_verbs, 14001 .init_verbs = { alc269_init_verbs,
13839 alc269_eeepc_dmic_init_verbs }, 14002 alc269_laptop_dmic_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14004 .dac_nids = alc269_dac_nids,
14005 .hp_nid = 0x03,
14006 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14007 .channel_mode = alc269_modes,
14008 .unsol_event = alc269_laptop_unsol_event,
14009 .setup = alc269_laptop_dmic_setup,
14010 .init_hook = alc269_laptop_inithook,
14011 },
14012 [ALC269VB_AMIC] = {
14013 .mixers = { alc269vb_laptop_mixer },
14014 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14015 .init_verbs = { alc269vb_init_verbs,
14016 alc269vb_laptop_amic_init_verbs },
14017 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14018 .dac_nids = alc269_dac_nids,
14019 .hp_nid = 0x03,
14020 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14021 .channel_mode = alc269_modes,
14022 .unsol_event = alc269_laptop_unsol_event,
14023 .setup = alc269_laptop_amic_setup,
14024 .init_hook = alc269_laptop_inithook,
14025 },
14026 [ALC269VB_DMIC] = {
14027 .mixers = { alc269vb_laptop_mixer },
14028 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14029 .init_verbs = { alc269vb_init_verbs,
14030 alc269vb_laptop_dmic_init_verbs },
13840 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14031 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13841 .dac_nids = alc269_dac_nids, 14032 .dac_nids = alc269_dac_nids,
13842 .hp_nid = 0x03, 14033 .hp_nid = 0x03,
13843 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14034 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13844 .channel_mode = alc269_modes, 14035 .channel_mode = alc269_modes,
13845 .unsol_event = alc269_eeepc_unsol_event, 14036 .unsol_event = alc269_laptop_unsol_event,
13846 .setup = alc269_eeepc_dmic_setup, 14037 .setup = alc269vb_laptop_dmic_setup,
13847 .init_hook = alc269_eeepc_inithook, 14038 .init_hook = alc269_laptop_inithook,
13848 }, 14039 },
13849 [ALC269_FUJITSU] = { 14040 [ALC269_FUJITSU] = {
13850 .mixers = { alc269_fujitsu_mixer }, 14041 .mixers = { alc269_fujitsu_mixer },
13851 .cap_mixer = alc269_epc_capture_mixer, 14042 .cap_mixer = alc269_laptop_digital_capture_mixer,
13852 .init_verbs = { alc269_init_verbs, 14043 .init_verbs = { alc269_init_verbs,
13853 alc269_eeepc_dmic_init_verbs }, 14044 alc269_laptop_dmic_init_verbs },
13854 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14045 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13855 .dac_nids = alc269_dac_nids, 14046 .dac_nids = alc269_dac_nids,
13856 .hp_nid = 0x03, 14047 .hp_nid = 0x03,
13857 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14048 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13858 .channel_mode = alc269_modes, 14049 .channel_mode = alc269_modes,
13859 .unsol_event = alc269_eeepc_unsol_event, 14050 .unsol_event = alc269_laptop_unsol_event,
13860 .setup = alc269_eeepc_dmic_setup, 14051 .setup = alc269_laptop_dmic_setup,
13861 .init_hook = alc269_eeepc_inithook, 14052 .init_hook = alc269_laptop_inithook,
13862 }, 14053 },
13863 [ALC269_LIFEBOOK] = { 14054 [ALC269_LIFEBOOK] = {
13864 .mixers = { alc269_lifebook_mixer }, 14055 .mixers = { alc269_lifebook_mixer },
@@ -13879,6 +14070,7 @@ static int patch_alc269(struct hda_codec *codec)
13879 struct alc_spec *spec; 14070 struct alc_spec *spec;
13880 int board_config; 14071 int board_config;
13881 int err; 14072 int err;
14073 int is_alc269vb = 0;
13882 14074
13883 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14075 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13884 if (spec == NULL) 14076 if (spec == NULL)
@@ -13895,6 +14087,7 @@ static int patch_alc269(struct hda_codec *codec)
13895 alc_free(codec); 14087 alc_free(codec);
13896 return -ENOMEM; 14088 return -ENOMEM;
13897 } 14089 }
14090 is_alc269vb = 1;
13898 } 14091 }
13899 14092
13900 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14093 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
@@ -13930,7 +14123,7 @@ static int patch_alc269(struct hda_codec *codec)
13930 if (board_config != ALC269_AUTO) 14123 if (board_config != ALC269_AUTO)
13931 setup_preset(codec, &alc269_presets[board_config]); 14124 setup_preset(codec, &alc269_presets[board_config]);
13932 14125
13933 if (codec->subsystem_id == 0x17aa3bf8) { 14126 if (board_config == ALC269_QUANTA_FL1) {
13934 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14127 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13935 * fix the sample rate of analog I/O to 44.1kHz 14128 * fix the sample rate of analog I/O to 44.1kHz
13936 */ 14129 */
@@ -13943,9 +14136,16 @@ static int patch_alc269(struct hda_codec *codec)
13943 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14136 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13944 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14137 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13945 14138
13946 spec->adc_nids = alc269_adc_nids; 14139 if (!is_alc269vb) {
13947 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14140 spec->adc_nids = alc269_adc_nids;
13948 spec->capsrc_nids = alc269_capsrc_nids; 14141 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14142 spec->capsrc_nids = alc269_capsrc_nids;
14143 } else {
14144 spec->adc_nids = alc269vb_adc_nids;
14145 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14146 spec->capsrc_nids = alc269vb_capsrc_nids;
14147 }
14148
13949 if (!spec->cap_mixer) 14149 if (!spec->cap_mixer)
13950 set_capture_mixer(codec); 14150 set_capture_mixer(codec);
13951 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14151 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
@@ -13959,7 +14159,6 @@ static int patch_alc269(struct hda_codec *codec)
13959 if (!spec->loopback.amplist) 14159 if (!spec->loopback.amplist)
13960 spec->loopback.amplist = alc269_loopbacks; 14160 spec->loopback.amplist = alc269_loopbacks;
13961#endif 14161#endif
13962 codec->proc_widget_hook = print_realtek_coef;
13963 14162
13964 return 0; 14163 return 0;
13965} 14164}
@@ -14822,7 +15021,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14822 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15021 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14823 set_capture_mixer(codec); 15022 set_capture_mixer(codec);
14824 15023
14825 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 15024 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
14826 15025
14827 return 1; 15026 return 1;
14828} 15027}
@@ -15087,7 +15286,6 @@ static int patch_alc861(struct hda_codec *codec)
15087 if (!spec->loopback.amplist) 15286 if (!spec->loopback.amplist)
15088 spec->loopback.amplist = alc861_loopbacks; 15287 spec->loopback.amplist = alc861_loopbacks;
15089#endif 15288#endif
15090 codec->proc_widget_hook = print_realtek_coef;
15091 15289
15092 return 0; 15290 return 0;
15093} 15291}
@@ -15714,7 +15912,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15714static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 15912static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15715 const struct auto_pin_cfg *cfg) 15913 const struct auto_pin_cfg *cfg)
15716{ 15914{
15717 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); 15915 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15718} 15916}
15719 15917
15720 15918
@@ -15950,7 +16148,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15950 if (err < 0) 16148 if (err < 0)
15951 return err; 16149 return err;
15952 16150
15953 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 16151 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
15954 16152
15955 return 1; 16153 return 1;
15956} 16154}
@@ -16067,7 +16265,6 @@ static int patch_alc861vd(struct hda_codec *codec)
16067 if (!spec->loopback.amplist) 16265 if (!spec->loopback.amplist)
16068 spec->loopback.amplist = alc861vd_loopbacks; 16266 spec->loopback.amplist = alc861vd_loopbacks;
16069#endif 16267#endif
16070 codec->proc_widget_hook = print_realtek_coef;
16071 16268
16072 return 0; 16269 return 0;
16073} 16270}
@@ -16534,13 +16731,6 @@ static struct hda_verb alc662_init_verbs[] = {
16534 /* ADC: mute amp left and right */ 16731 /* ADC: mute amp left and right */
16535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16536 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16537 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16538
16539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16544 16734
16545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -16590,6 +16780,28 @@ static struct hda_verb alc662_init_verbs[] = {
16590 { } 16780 { }
16591}; 16781};
16592 16782
16783static struct hda_verb alc663_init_verbs[] = {
16784 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16786 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16787 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16788 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16789 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16790 { }
16791};
16792
16793static struct hda_verb alc272_init_verbs[] = {
16794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16796 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16799 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16802 { }
16803};
16804
16593static struct hda_verb alc662_sue_init_verbs[] = { 16805static struct hda_verb alc662_sue_init_verbs[] = {
16594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 16806 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16595 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 16807 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
@@ -16609,61 +16821,6 @@ static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16609 {} 16821 {}
16610}; 16822};
16611 16823
16612/*
16613 * generic initialization of ADC, input mixers and output mixers
16614 */
16615static struct hda_verb alc662_auto_init_verbs[] = {
16616 /*
16617 * Unmute ADC and set the default input to mic-in
16618 */
16619 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16621
16622 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16623 * mixer widget
16624 * Note: PASD motherboards uses the Line In 2 as the input for front
16625 * panel mic (mic 2)
16626 */
16627 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16633
16634 /*
16635 * Set up output mixers (0x0c - 0x0f)
16636 */
16637 /* set vol=0 to output mixers */
16638 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16639 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16640 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16641
16642 /* set up input amps for analog loopback */
16643 /* Amp Indices: DAC = 0, mixer = 1 */
16644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16647 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16648 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16649 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16650
16651
16652 /* FIXME: use matrix-type input source selection */
16653 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16654 /* Input mixer */
16655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16657 { }
16658};
16659
16660/* additional verbs for ALC663 */
16661static struct hda_verb alc663_auto_init_verbs[] = {
16662 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16663 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16664 { }
16665};
16666
16667static struct hda_verb alc663_m51va_init_verbs[] = { 16824static struct hda_verb alc663_m51va_init_verbs[] = {
16668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16669 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17414,6 +17571,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17414 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 17571 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17415 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 17572 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17416 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 17573 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17574 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17417 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 17575 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17418 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 17576 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17419 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 17577 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
@@ -17449,6 +17607,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17449 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 17607 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17450 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 17608 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17451 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 17609 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17610 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17452 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 17611 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17453 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 17612 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17454 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 17613 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
@@ -17476,6 +17635,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17476 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 17635 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17477 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 17636 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17478 ALC662_3ST_6ch_DIG), 17637 ALC662_3ST_6ch_DIG),
17638 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17479 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 17639 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17480 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 17640 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17481 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 17641 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
@@ -18094,15 +18254,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18094 spec->num_mux_defs = 1; 18254 spec->num_mux_defs = 1;
18095 spec->input_mux = &spec->private_imux[0]; 18255 spec->input_mux = &spec->private_imux[0];
18096 18256
18097 add_verb(spec, alc662_auto_init_verbs); 18257 add_verb(spec, alc662_init_verbs);
18098 if (codec->vendor_id == 0x10ec0663) 18258 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18099 add_verb(spec, alc663_auto_init_verbs); 18259 codec->vendor_id == 0x10ec0665)
18260 add_verb(spec, alc663_init_verbs);
18261
18262 if (codec->vendor_id == 0x10ec0272)
18263 add_verb(spec, alc272_init_verbs);
18100 18264
18101 err = alc_auto_add_mic_boost(codec); 18265 err = alc_auto_add_mic_boost(codec);
18102 if (err < 0) 18266 if (err < 0)
18103 return err; 18267 return err;
18104 18268
18105 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 18269 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18270 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18271 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18272 else
18273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18106 18274
18107 return 1; 18275 return 1;
18108} 18276}
@@ -18188,11 +18356,20 @@ static int patch_alc662(struct hda_codec *codec)
18188 18356
18189 if (!spec->cap_mixer) 18357 if (!spec->cap_mixer)
18190 set_capture_mixer(codec); 18358 set_capture_mixer(codec);
18191 if (codec->vendor_id == 0x10ec0662) 18359
18360 switch (codec->vendor_id) {
18361 case 0x10ec0662:
18192 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18362 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18193 else 18363 break;
18364 case 0x10ec0272:
18365 case 0x10ec0663:
18366 case 0x10ec0665:
18194 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18367 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18195 18368 break;
18369 case 0x10ec0273:
18370 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18371 break;
18372 }
18196 spec->vmaster_nid = 0x02; 18373 spec->vmaster_nid = 0x02;
18197 18374
18198 codec->patch_ops = alc_patch_ops; 18375 codec->patch_ops = alc_patch_ops;
@@ -18202,7 +18379,6 @@ static int patch_alc662(struct hda_codec *codec)
18202 if (!spec->loopback.amplist) 18379 if (!spec->loopback.amplist)
18203 spec->loopback.amplist = alc662_loopbacks; 18380 spec->loopback.amplist = alc662_loopbacks;
18204#endif 18381#endif
18205 codec->proc_widget_hook = print_realtek_coef;
18206 18382
18207 return 0; 18383 return 0;
18208} 18384}
@@ -18243,6 +18419,8 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18243 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 18419 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18244 .patch = patch_alc662 }, 18420 .patch = patch_alc662 },
18245 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 18421 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18422 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18423 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18246 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 18424 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18247 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 18425 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18248 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 18426 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index dbffb5b5c69d..8c416bb18a57 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -568,6 +568,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
568 0x0f, 0x10, 0x11, 0x1f, 0x20, 568 0x0f, 0x10, 0x11, 0x1f, 0x20,
569}; 569};
570 570
571static hda_nid_t stac92hd88xxx_pin_nids[10] = {
572 0x0a, 0x0b, 0x0c, 0x0d,
573 0x0f, 0x11, 0x1f, 0x20,
574};
575
571#define STAC92HD71BXX_NUM_PINS 13 576#define STAC92HD71BXX_NUM_PINS 13
572static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 577static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
573 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 578 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -2873,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2873 2878
2874 conn_len = snd_hda_get_connections(codec, nid, conn, 2879 conn_len = snd_hda_get_connections(codec, nid, conn,
2875 HDA_MAX_CONNECTIONS); 2880 HDA_MAX_CONNECTIONS);
2881 /* 92HD88: trace back up the link of nids to find the DAC */
2882 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2883 != AC_WID_AUD_OUT)) {
2884 nid = conn[0];
2885 conn_len = snd_hda_get_connections(codec, nid, conn,
2886 HDA_MAX_CONNECTIONS);
2887 }
2876 for (j = 0; j < conn_len; j++) { 2888 for (j = 0; j < conn_len; j++) {
2877 wcaps = get_wcaps(codec, conn[j]); 2889 wcaps = get_wcaps(codec, conn[j]);
2878 wtype = get_wcaps_type(wcaps); 2890 wtype = get_wcaps_type(wcaps);
@@ -4351,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec)
4351 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4363 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4352 stac_issue_unsol_event(codec, nid); 4364 stac_issue_unsol_event(codec, nid);
4353 } 4365 }
4366
4367#ifdef CONFIG_SND_HDA_POWER_SAVE
4368 /* sync mute LED */
4369 if (spec->gpio_led && codec->patch_ops.check_power_status)
4370 codec->patch_ops.check_power_status(codec, 0x01);
4371#endif
4354 if (spec->dac_list) 4372 if (spec->dac_list)
4355 stac92xx_power_down(codec); 4373 stac92xx_power_down(codec);
4356 return 0; 4374 return 0;
@@ -4742,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id);
4742static void set_hp_led_gpio(struct hda_codec *codec) 4760static void set_hp_led_gpio(struct hda_codec *codec)
4743{ 4761{
4744 struct sigmatel_spec *spec = codec->spec; 4762 struct sigmatel_spec *spec = codec->spec;
4745 switch (codec->vendor_id) { 4763 unsigned int gpio;
4746 case 0x111d7608: 4764
4747 /* GPIO 0 */ 4765 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4748 spec->gpio_led = 0x01; 4766 gpio &= AC_GPIO_IO_COUNT;
4749 break; 4767 if (gpio > 3)
4750 case 0x111d7600: 4768 spec->gpio_led = 0x08; /* GPIO 3 */
4751 case 0x111d7601: 4769 else
4752 case 0x111d7602: 4770 spec->gpio_led = 0x01; /* GPIO 0 */
4753 case 0x111d7603:
4754 /* GPIO 3 */
4755 spec->gpio_led = 0x08;
4756 break;
4757 }
4758} 4771}
4759 4772
4760/* 4773/*
@@ -4777,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec)
4777 * Need more information on whether it is true across the entire series. 4790 * Need more information on whether it is true across the entire series.
4778 * -- kunal 4791 * -- kunal
4779 */ 4792 */
4780static int find_mute_led_gpio(struct hda_codec *codec) 4793static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4781{ 4794{
4782 struct sigmatel_spec *spec = codec->spec; 4795 struct sigmatel_spec *spec = codec->spec;
4783 const struct dmi_device *dev = NULL; 4796 const struct dmi_device *dev = NULL;
@@ -4804,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec)
4804 */ 4817 */
4805 if (!hp_blike_system(codec->subsystem_id)) { 4818 if (!hp_blike_system(codec->subsystem_id)) {
4806 set_hp_led_gpio(codec); 4819 set_hp_led_gpio(codec);
4807 spec->gpio_led_polarity = 1; 4820 spec->gpio_led_polarity = default_polarity;
4808 return 1; 4821 return 1;
4809 } 4822 }
4810 } 4823 }
@@ -4902,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec)
4902 stac_issue_unsol_event(codec, 4915 stac_issue_unsol_event(codec,
4903 spec->autocfg.line_out_pins[0]); 4916 spec->autocfg.line_out_pins[0]);
4904 } 4917 }
4918#ifdef CONFIG_SND_HDA_POWER_SAVE
4919 /* sync mute LED */
4920 if (spec->gpio_led && codec->patch_ops.check_power_status)
4921 codec->patch_ops.check_power_status(codec, 0x01);
4922#endif
4905 return 0; 4923 return 0;
4906} 4924}
4907 4925
@@ -4921,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4921 hda_nid_t nid) 4939 hda_nid_t nid)
4922{ 4940{
4923 struct sigmatel_spec *spec = codec->spec; 4941 struct sigmatel_spec *spec = codec->spec;
4942 int i, muted = 1;
4924 4943
4925 if (nid == 0x10) { 4944 for (i = 0; i < spec->multiout.num_dacs; i++) {
4926 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4945 nid = spec->multiout.dac_nids[i];
4927 HDA_AMP_MUTE) 4946 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4928 spec->gpio_data &= ~spec->gpio_led; /* orange */ 4947 HDA_AMP_MUTE)) {
4929 else 4948 muted = 0; /* something heard */
4930 spec->gpio_data |= spec->gpio_led; /* white */ 4949 break;
4931
4932 if (!spec->gpio_led_polarity) {
4933 /* LED state is inverted on these systems */
4934 spec->gpio_data ^= spec->gpio_led;
4935 } 4950 }
4936
4937 stac_gpio_set(codec, spec->gpio_mask,
4938 spec->gpio_dir,
4939 spec->gpio_data);
4940 } 4951 }
4952 if (muted)
4953 spec->gpio_data &= ~spec->gpio_led; /* orange */
4954 else
4955 spec->gpio_data |= spec->gpio_led; /* white */
4941 4956
4942 return 0; 4957 if (!spec->gpio_led_polarity) {
4943} 4958 /* LED state is inverted on these systems */
4944 4959 spec->gpio_data ^= spec->gpio_led;
4945static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, 4960 }
4946 hda_nid_t nid)
4947{
4948 struct sigmatel_spec *spec = codec->spec;
4949 4961
4950 if (nid != 0x13)
4951 return 0;
4952 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE)
4953 spec->gpio_data |= spec->gpio_led; /* mute LED on */
4954 else
4955 spec->gpio_data &= ~spec->gpio_led; /* mute LED off */
4956 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 4962 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4957
4958 return 0; 4963 return 0;
4959} 4964}
4960
4961#endif 4965#endif
4962 4966
4963static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4967static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -5279,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5279 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; 5283 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5280 int err; 5284 int err;
5281 int num_dacs; 5285 int num_dacs;
5282 hda_nid_t nid;
5283 5286
5284 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5287 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5285 if (spec == NULL) 5288 if (spec == NULL)
@@ -5318,7 +5321,18 @@ again:
5318 stac92hd83xxx_brd_tbl[spec->board_config]); 5321 stac92hd83xxx_brd_tbl[spec->board_config]);
5319 5322
5320 switch (codec->vendor_id) { 5323 switch (codec->vendor_id) {
5324 case 0x111d7666:
5325 case 0x111d7667:
5326 case 0x111d7668:
5327 case 0x111d7669:
5328 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5329 spec->pin_nids = stac92hd88xxx_pin_nids;
5330 spec->mono_nid = 0;
5331 spec->digbeep_nid = 0;
5332 spec->num_pwrs = 0;
5333 break;
5321 case 0x111d7604: 5334 case 0x111d7604:
5335 case 0x111d76d4:
5322 case 0x111d7605: 5336 case 0x111d7605:
5323 case 0x111d76d5: 5337 case 0x111d76d5:
5324 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5338 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5329,8 +5343,10 @@ again:
5329 5343
5330 codec->patch_ops = stac92xx_patch_ops; 5344 codec->patch_ops = stac92xx_patch_ops;
5331 5345
5332 if (spec->board_config == STAC_92HD83XXX_HP) 5346 if (find_mute_led_gpio(codec, 0))
5333 spec->gpio_led = 0x01; 5347 snd_printd("mute LED gpio %d polarity %d\n",
5348 spec->gpio_led,
5349 spec->gpio_led_polarity);
5334 5350
5335#ifdef CONFIG_SND_HDA_POWER_SAVE 5351#ifdef CONFIG_SND_HDA_POWER_SAVE
5336 if (spec->gpio_led) { 5352 if (spec->gpio_led) {
@@ -5339,7 +5355,7 @@ again:
5339 spec->gpio_data |= spec->gpio_led; 5355 spec->gpio_data |= spec->gpio_led;
5340 /* register check_power_status callback. */ 5356 /* register check_power_status callback. */
5341 codec->patch_ops.check_power_status = 5357 codec->patch_ops.check_power_status =
5342 idt92hd83xxx_hp_check_power_status; 5358 stac92xx_hp_check_power_status;
5343 } 5359 }
5344#endif 5360#endif
5345 5361
@@ -5359,24 +5375,21 @@ again:
5359 return err; 5375 return err;
5360 } 5376 }
5361 5377
5362 switch (spec->board_config) { 5378 /* docking output support */
5363 case STAC_DELL_S14: 5379 num_dacs = snd_hda_get_connections(codec, 0xF,
5364 nid = 0xf;
5365 break;
5366 default:
5367 nid = 0xe;
5368 break;
5369 }
5370
5371 num_dacs = snd_hda_get_connections(codec, nid,
5372 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5380 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5373 if (num_dacs < 0) 5381 /* skip non-DAC connections */
5374 num_dacs = STAC92HD83_DAC_COUNT; 5382 while (num_dacs >= 0 &&
5375 5383 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5376 /* set port X to select the last DAC 5384 != AC_WID_AUD_OUT))
5377 */ 5385 num_dacs--;
5378 snd_hda_codec_write_cache(codec, nid, 0, 5386 /* set port E and F to select the last DAC */
5387 if (num_dacs >= 0) {
5388 snd_hda_codec_write_cache(codec, 0xE, 0,
5389 AC_VERB_SET_CONNECT_SEL, num_dacs);
5390 snd_hda_codec_write_cache(codec, 0xF, 0,
5379 AC_VERB_SET_CONNECT_SEL, num_dacs); 5391 AC_VERB_SET_CONNECT_SEL, num_dacs);
5392 }
5380 5393
5381 codec->proc_widget_hook = stac92hd_proc_hook; 5394 codec->proc_widget_hook = stac92hd_proc_hook;
5382 5395
@@ -5657,7 +5670,6 @@ again:
5657 */ 5670 */
5658 spec->num_smuxes = 1; 5671 spec->num_smuxes = 1;
5659 spec->num_dmuxes = 1; 5672 spec->num_dmuxes = 1;
5660 spec->gpio_led = 0x01;
5661 /* fallthrough */ 5673 /* fallthrough */
5662 case STAC_HP_DV5: 5674 case STAC_HP_DV5:
5663 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5675 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
@@ -5672,8 +5684,6 @@ again:
5672 spec->num_dmics = 1; 5684 spec->num_dmics = 1;
5673 spec->num_dmuxes = 1; 5685 spec->num_dmuxes = 1;
5674 spec->num_smuxes = 1; 5686 spec->num_smuxes = 1;
5675 /* orange/white mute led on GPIO3, orange=0, white=1 */
5676 spec->gpio_led = 0x08;
5677 break; 5687 break;
5678 } 5688 }
5679 5689
@@ -5695,7 +5705,7 @@ again:
5695 } 5705 }
5696 } 5706 }
5697 5707
5698 if (find_mute_led_gpio(codec)) 5708 if (find_mute_led_gpio(codec, 1))
5699 snd_printd("mute LED gpio %d polarity %d\n", 5709 snd_printd("mute LED gpio %d polarity %d\n",
5700 spec->gpio_led, 5710 spec->gpio_led,
5701 spec->gpio_led_polarity); 5711 spec->gpio_led_polarity);
@@ -6236,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6236 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 6246 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
6237 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 6247 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
6238 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 6248 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
6249 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6239 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6250 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6240 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6251 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6252 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6253 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6254 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
6255 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
6241 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 6256 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
6242 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 6257 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
6243 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 6258 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },